@tnkrai/tnkr-editor 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +78 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +78 -67
- package/dist/index.js.map +1 -1
- package/dist/preview/PreviewSidebar.d.ts.map +1 -1
- package/dist/src/components/TnkrModelView/TnkrEditorModelViewCore.d.ts.map +1 -1
- package/dist/src/components/TnkrModelView/modelViewCore.d.ts.map +1 -1
- package/dist/src/components/TnkrModelView/partUtils.d.ts +2 -2
- package/dist/src/components/TnkrModelView/partUtils.d.ts.map +1 -1
- package/dist/src/components/TnkrModelView/types.d.ts +1 -0
- package/dist/src/components/TnkrModelView/types.d.ts.map +1 -1
- package/dist/src/components/assembly/AssemblyViewMode.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -73196,7 +73196,7 @@ function expandGroupsToChildren(parts) {
|
|
|
73196
73196
|
return expandedParts;
|
|
73197
73197
|
}
|
|
73198
73198
|
// Utility function to sync step parts with latest data from referenced steps
|
|
73199
|
-
function syncStepPartsWithLatestData(stepParts, allSteps) {
|
|
73199
|
+
function syncStepPartsWithLatestData(stepParts, allSteps, animationDirections) {
|
|
73200
73200
|
const updatedParts = [];
|
|
73201
73201
|
const processedStepIds = new Set(); // Track processed steps to avoid infinite recursion
|
|
73202
73202
|
console.log('Syncing step parts:', stepParts);
|
|
@@ -73229,8 +73229,11 @@ function syncStepPartsWithLatestData(stepParts, allSteps) {
|
|
|
73229
73229
|
processPart(currentPart, depth + 1);
|
|
73230
73230
|
}
|
|
73231
73231
|
else {
|
|
73232
|
-
//
|
|
73233
|
-
|
|
73232
|
+
// Override with animationDirection from MongoDB if provided
|
|
73233
|
+
const cleanedPart = Object.assign(Object.assign({}, currentPart), { metadata: Object.assign(Object.assign({}, currentPart.metadata), {
|
|
73234
|
+
// Use MongoDB animationDirections as single source of truth
|
|
73235
|
+
animationDirection: (animationDirections === null || animationDirections === void 0 ? void 0 : animationDirections[currentPart.id]) || undefined }) });
|
|
73236
|
+
updatedParts.push(cleanedPart);
|
|
73234
73237
|
}
|
|
73235
73238
|
});
|
|
73236
73239
|
}
|
|
@@ -73239,8 +73242,11 @@ function syncStepPartsWithLatestData(stepParts, allSteps) {
|
|
|
73239
73242
|
}
|
|
73240
73243
|
}
|
|
73241
73244
|
else {
|
|
73242
|
-
//
|
|
73243
|
-
|
|
73245
|
+
// Override with animationDirection from MongoDB if provided
|
|
73246
|
+
const cleanedPart = Object.assign(Object.assign({}, part), { metadata: Object.assign(Object.assign({}, part.metadata), {
|
|
73247
|
+
// Use MongoDB animationDirections as single source of truth
|
|
73248
|
+
animationDirection: (animationDirections === null || animationDirections === void 0 ? void 0 : animationDirections[part.id]) || undefined }) });
|
|
73249
|
+
updatedParts.push(cleanedPart);
|
|
73244
73250
|
}
|
|
73245
73251
|
};
|
|
73246
73252
|
// Process each part in the initial stepParts array
|
|
@@ -74120,85 +74126,94 @@ function useModelViewCore(parts = []) {
|
|
|
74120
74126
|
return ({
|
|
74121
74127
|
id: part.id,
|
|
74122
74128
|
name: part.name,
|
|
74129
|
+
type: part.type,
|
|
74123
74130
|
direction: (_a = part.metadata) === null || _a === void 0 ? void 0 : _a.animationDirection,
|
|
74124
74131
|
});
|
|
74125
74132
|
}),
|
|
74126
74133
|
});
|
|
74127
74134
|
}
|
|
74128
|
-
// Process
|
|
74135
|
+
// Process parts directly - handle groups and transforms
|
|
74136
|
+
const processedTransforms = new Set(); // Track which transforms we've already animated
|
|
74129
74137
|
partsWithDirections.forEach((part) => {
|
|
74130
|
-
var _a, _b;
|
|
74138
|
+
var _a, _b, _c;
|
|
74131
74139
|
const direction = (_a = part.metadata) === null || _a === void 0 ? void 0 : _a.animationDirection;
|
|
74132
|
-
|
|
74133
|
-
|
|
74134
|
-
|
|
74135
|
-
|
|
74136
|
-
if (
|
|
74137
|
-
|
|
74138
|
-
|
|
74139
|
-
|
|
74140
|
-
|
|
74141
|
-
|
|
74142
|
-
|
|
74143
|
-
}
|
|
74144
|
-
else {
|
|
74145
|
-
if (factor === 1) {
|
|
74146
|
-
console.log(`🎲 Transform ${part.name} using fallback explosion`);
|
|
74147
|
-
}
|
|
74148
|
-
targetPosition = calculateExplodedPosition(originalTranslation, [0, 0, 0], factor, 3, part.id);
|
|
74140
|
+
// Handle groups with all their children moving as a unit
|
|
74141
|
+
if ((part.type === 'group' || ((_b = part.metadata) === null || _b === void 0 ? void 0 : _b.isGroup)) && part.children) {
|
|
74142
|
+
// Calculate ONE offset for the entire group
|
|
74143
|
+
let groupOffset = [0, 0, 0];
|
|
74144
|
+
if (direction) {
|
|
74145
|
+
// Group has a direction - calculate directional offset
|
|
74146
|
+
const tempPos = calculateDirectionalExplodedPosition('0 0 0', direction, factor);
|
|
74147
|
+
groupOffset = tempPos.split(' ').map(Number);
|
|
74148
|
+
console.log(`📦 Group ${part.id} (${part.name}) calculated offset: [${groupOffset.join(', ')}] for direction: ${direction}`);
|
|
74149
|
+
if (factor === 1) {
|
|
74150
|
+
console.log(`📦 Group ${part.id} (${part.name}) moving ${direction} as a unit with offset [${groupOffset.join(', ')}]`);
|
|
74149
74151
|
}
|
|
74150
|
-
transformElement.setAttribute('translation', targetPosition);
|
|
74151
74152
|
}
|
|
74152
74153
|
else {
|
|
74154
|
+
// Group without direction - use random explosion but same for all parts
|
|
74155
|
+
const tempPos = calculateExplodedPosition('0 0 0', [0, 0, 0], factor, 3, part.id);
|
|
74156
|
+
groupOffset = tempPos.split(' ').map(Number);
|
|
74153
74157
|
if (factor === 1) {
|
|
74154
|
-
console.
|
|
74158
|
+
console.log(`🎲 Group ${part.id} (${part.name}) exploding randomly as a unit`);
|
|
74155
74159
|
}
|
|
74156
74160
|
}
|
|
74157
|
-
|
|
74158
|
-
|
|
74159
|
-
|
|
74160
|
-
if (factor === 1) {
|
|
74161
|
-
console.log(`📍 Group ${part.name} with ${part.children.length} children using direction: ${direction || 'fallback'}`);
|
|
74162
|
-
}
|
|
74163
|
-
// Calculate group offset once using camera-relative movement
|
|
74164
|
-
let groupOffset = [0, 0, 0];
|
|
74165
|
-
if (direction) {
|
|
74166
|
-
// Use the same calculateDirectionalExplodedPosition logic for consistency
|
|
74167
|
-
const tempPos = calculateDirectionalExplodedPosition('0 0 0', direction, factor);
|
|
74168
|
-
const offset = tempPos.split(' ').map(Number);
|
|
74169
|
-
groupOffset = offset;
|
|
74170
|
-
}
|
|
74171
|
-
// Apply the same offset to all child transforms in the group
|
|
74172
|
-
const collectAndAnimateTransforms = (children) => {
|
|
74161
|
+
// Apply THE SAME offset to ALL transforms in the group
|
|
74162
|
+
const applyGroupOffset = (children, depth = 0) => {
|
|
74163
|
+
console.log(`${' '.repeat(depth)}Applying offset to ${children.length} children`);
|
|
74173
74164
|
children.forEach((child) => {
|
|
74174
74165
|
var _a;
|
|
74175
|
-
|
|
74166
|
+
console.log(`${' '.repeat(depth)}Child: ${child.name} (${child.id}), type: ${child.type}`);
|
|
74167
|
+
if (child.type === 'transform' && child.id) {
|
|
74176
74168
|
const transformElement = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(`Transform[id="${CSS.escape(child.id)}"]`);
|
|
74177
74169
|
const originalTranslation = originalTransformsRef.current.get(child.id);
|
|
74178
74170
|
if (transformElement && originalTranslation) {
|
|
74179
74171
|
const pos = originalTranslation.split(' ').map(Number);
|
|
74180
|
-
|
|
74181
|
-
|
|
74182
|
-
|
|
74183
|
-
|
|
74184
|
-
|
|
74185
|
-
|
|
74186
|
-
|
|
74187
|
-
].join(' ');
|
|
74188
|
-
}
|
|
74189
|
-
else {
|
|
74190
|
-
// Fallback to individual explosion
|
|
74191
|
-
targetPosition = calculateExplodedPosition(originalTranslation, [0, 0, 0], factor, 3, child.id);
|
|
74192
|
-
}
|
|
74172
|
+
// Apply the group offset to maintain relative positions
|
|
74173
|
+
const targetPosition = [
|
|
74174
|
+
pos[0] + groupOffset[0],
|
|
74175
|
+
pos[1] + groupOffset[1],
|
|
74176
|
+
pos[2] + groupOffset[2],
|
|
74177
|
+
].join(' ');
|
|
74178
|
+
console.log(`${' '.repeat(depth)}✅ Applying offset [${groupOffset.join(', ')}] to transform ${child.name}: ${originalTranslation} -> ${targetPosition}`);
|
|
74193
74179
|
transformElement.setAttribute('translation', targetPosition);
|
|
74180
|
+
processedTransforms.add(child.id); // Mark as processed
|
|
74181
|
+
}
|
|
74182
|
+
else {
|
|
74183
|
+
console.log(`${' '.repeat(depth)}❌ Could not find element or translation for ${child.id}`);
|
|
74194
74184
|
}
|
|
74195
74185
|
}
|
|
74196
|
-
|
|
74197
|
-
|
|
74186
|
+
// Recursively process nested children
|
|
74187
|
+
if (child.children) {
|
|
74188
|
+
applyGroupOffset(child.children, depth + 1);
|
|
74198
74189
|
}
|
|
74199
74190
|
});
|
|
74200
74191
|
};
|
|
74201
|
-
|
|
74192
|
+
applyGroupOffset(part.children, 0);
|
|
74193
|
+
}
|
|
74194
|
+
else if (part.type === 'transform' && part.id && !processedTransforms.has(part.id)) {
|
|
74195
|
+
// Handle individual transforms (not part of a group we already processed)
|
|
74196
|
+
const transformElement = (_c = containerRef.current) === null || _c === void 0 ? void 0 : _c.querySelector(`Transform[id="${CSS.escape(part.id)}"]`);
|
|
74197
|
+
const originalTranslation = originalTransformsRef.current.get(part.id);
|
|
74198
|
+
if (transformElement && originalTranslation) {
|
|
74199
|
+
let targetPosition;
|
|
74200
|
+
if (direction) {
|
|
74201
|
+
// Individual transform with direction
|
|
74202
|
+
targetPosition = calculateDirectionalExplodedPosition(originalTranslation, direction, factor);
|
|
74203
|
+
if (factor === 1) {
|
|
74204
|
+
console.log(`📍 Transform ${part.name} moving ${direction}`);
|
|
74205
|
+
}
|
|
74206
|
+
}
|
|
74207
|
+
else {
|
|
74208
|
+
// Individual transform without direction - use random explosion
|
|
74209
|
+
targetPosition = calculateExplodedPosition(originalTranslation, [0, 0, 0], factor, 3, part.id);
|
|
74210
|
+
if (factor === 1) {
|
|
74211
|
+
console.log(`🎲 Transform ${part.name} using random explosion`);
|
|
74212
|
+
}
|
|
74213
|
+
}
|
|
74214
|
+
transformElement.setAttribute('translation', targetPosition);
|
|
74215
|
+
processedTransforms.add(part.id);
|
|
74216
|
+
}
|
|
74202
74217
|
}
|
|
74203
74218
|
});
|
|
74204
74219
|
}, [calculateDirectionalExplodedPosition, calculateExplodedPosition]);
|
|
@@ -75275,7 +75290,7 @@ handleNext: parentHandleNext, handlePrevious: parentHandlePrevious, onCameraSett
|
|
|
75275
75290
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
75276
75291
|
// Recenter the model for optimal rotation around step parts
|
|
75277
75292
|
console.log('🎯 Starting recentering for automatic step transition...');
|
|
75278
|
-
const autoTransitionStepParts = expandGroupsToChildren(syncStepPartsWithLatestData(stepData.selectedStep.parts || [], phases.flatMap((phase) => phase.steps || [])));
|
|
75293
|
+
const autoTransitionStepParts = expandGroupsToChildren(syncStepPartsWithLatestData(stepData.selectedStep.parts || [], phases.flatMap((phase) => phase.steps || []), stepData.selectedStep.animationDirections));
|
|
75279
75294
|
if (partOperations === null || partOperations === void 0 ? void 0 : partOperations.recenterToShapeIds) {
|
|
75280
75295
|
recenterForAssemblyStep(partOperations.recenterToShapeIds, autoTransitionStepParts);
|
|
75281
75296
|
}
|
|
@@ -75290,7 +75305,7 @@ handleNext: parentHandleNext, handlePrevious: parentHandlePrevious, onCameraSett
|
|
|
75290
75305
|
const rawStepParts = stepData.selectedStep.parts || [];
|
|
75291
75306
|
// Pass ALL steps from ALL phases for complete recursive syncing
|
|
75292
75307
|
const allStepsFromAllPhases = phases.flatMap((phase) => phase.steps || []);
|
|
75293
|
-
const allStepParts = syncStepPartsWithLatestData(rawStepParts, allStepsFromAllPhases);
|
|
75308
|
+
const allStepParts = syncStepPartsWithLatestData(rawStepParts, allStepsFromAllPhases, stepData.selectedStep.animationDirections);
|
|
75294
75309
|
// Expand groups to individual transforms for animation processing
|
|
75295
75310
|
const expandedAllStepParts = expandGroupsToChildren(allStepParts);
|
|
75296
75311
|
// Separate step-specific parts (tagged with current step ID) from inherited parts
|
|
@@ -77015,11 +77030,7 @@ const AssemblyViewMode = ({ phases, htmlContent, className = "", productTitle, p
|
|
|
77015
77030
|
if (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.id) {
|
|
77016
77031
|
handlePhaseDescriptionChange(currentPhase.id, content);
|
|
77017
77032
|
}
|
|
77018
|
-
}, onUploadImage: onUploadImage, customExtensionSet: getBasicExtensions(), className: "text-white", minHeight: 20, readOnly: !editMode }, `phase-${currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.id}`) }), jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold mb-4 text-white", children: "Steps" }), jsxRuntimeExports.jsx("div", { className: "space-y-4", children: (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps) && currentPhase.steps.length > 0 ? (currentPhase.steps.map((step, index) => (jsxRuntimeExports.jsx("button", { onClick: () => handleStepClick(index), className: "w-full text-left rounded-2xl px-4 py-3 cursor-pointer border border-[#313133] transition-all",
|
|
77019
|
-
e.currentTarget.style.border = '2px solid white';
|
|
77020
|
-
}, onMouseLeave: (e) => {
|
|
77021
|
-
e.currentTarget.style.border = '1px solid #313133';
|
|
77022
|
-
}, children: jsxRuntimeExports.jsxs("span", { className: "text-white/70", children: ["Step ", index + 1, ": ", step.title] }) }, step.id)))) : (
|
|
77033
|
+
}, onUploadImage: onUploadImage, customExtensionSet: getBasicExtensions(), className: "text-white", minHeight: 20, readOnly: !editMode }, `phase-${currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.id}`) }), jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold mb-4 text-white", children: "Steps" }), jsxRuntimeExports.jsx("div", { className: "space-y-4", children: (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps) && currentPhase.steps.length > 0 ? (currentPhase.steps.map((step, index) => (jsxRuntimeExports.jsx("button", { onClick: () => handleStepClick(index), className: "w-full text-left rounded-2xl px-4 py-3 cursor-pointer border border-[#313133] transition-all hover:border-[#AA423A]", children: jsxRuntimeExports.jsxs("span", { className: "text-white/70", children: ["Step ", index + 1, ": ", step.title] }) }, step.id)))) : (
|
|
77023
77034
|
// Display message when phase has valid title but no steps
|
|
77024
77035
|
jsxRuntimeExports.jsx("p", { className: "text-white/80 text-md max-w-[31rem]", children: "No steps yet. Add an assembly step and an animation to let your readers know what to do." })) })] }), (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps) && currentPhase.steps.length > 0 && (jsxRuntimeExports.jsx("div", { className: "mt-8 max-w-[7rem] ml-auto", children: jsxRuntimeExports.jsx(Button, { onClick: handleBeginPhase, className: "bg-[#AA423A] hover:bg-[#8A322E] text-white px-6 py-2 rounded-lg font-medium w-full h-11", children: "Begin Phase" }) }))] }))) : (
|
|
77025
77036
|
// Step Details
|
|
@@ -77575,7 +77586,7 @@ const PreviewCategoryItem = ({ category, level, selectedId, onSelect, onToggleEx
|
|
|
77575
77586
|
}, className: "ml-2 p-0.5 hover:bg-gray-700 rounded transition-colors flex-shrink-0", "aria-label": isExpanded ? "Collapse" : "Expand", children: isExpanded ? (jsxRuntimeExports.jsx(lucideReact.ChevronDown, { size: 14, className: "text-gray-400" })) : (jsxRuntimeExports.jsx(lucideReact.ChevronRight, { size: 14, className: "text-gray-400" })) }))] }), isExpanded && hasChildren && (jsxRuntimeExports.jsx("div", { children: category.children.map((child) => (jsxRuntimeExports.jsx(PreviewCategoryItem, { category: child, level: level + 1, selectedId: selectedId, onSelect: onSelect, onToggleExpand: onToggleExpand }, child.id))) }))] }));
|
|
77576
77587
|
};
|
|
77577
77588
|
const PreviewSidebar = ({ categories, selectedCategoryId, onCategorySelect, onToggleExpand, className = "", }) => {
|
|
77578
|
-
return (jsxRuntimeExports.
|
|
77589
|
+
return (jsxRuntimeExports.jsxs("div", { className: cn("w-64 flex flex-col px-2", className), children: [jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto py-4", children: [categories.map((category, index) => (jsxRuntimeExports.jsx("div", { className: index > 0 ? "mt-8" : "", children: jsxRuntimeExports.jsx(PreviewCategoryItem, { category: category, level: 0, selectedId: selectedCategoryId, onSelect: onCategorySelect, onToggleExpand: onToggleExpand }) }, category.id))), categories.length === 0 && (jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center p-8 text-gray-500", children: jsxRuntimeExports.jsx("p", { children: "No content available" }) }))] }), jsxRuntimeExports.jsx("div", { className: "px-4 py-3 border-t border-[#313133]", children: jsxRuntimeExports.jsxs("a", { href: "https://tnkr.ai", target: "_blank", rel: "noopener noreferrer", className: "flex items-center justify-center gap-2 text-xs text-gray-400 hover:text-gray-300 transition-colors", children: [jsxRuntimeExports.jsx("span", { children: "Powered by" }), jsxRuntimeExports.jsx("span", { className: "font-semibold text-[#AA423A]", children: "TnkrAI" })] }) })] }));
|
|
77579
77590
|
};
|
|
77580
77591
|
|
|
77581
77592
|
const PageContentNavigator = ({ content, className = "" }) => {
|