@tpitre/story-ui 2.6.1 → 2.7.1
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/README.md +36 -37
- package/dist/cli/deploy.d.ts +4 -3
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/deploy.js +542 -46
- package/dist/cli/index.js +17 -14
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +4 -110
- package/dist/cli/setup.js.map +1 -0
- package/dist/cloudflare-edge/src/mcp-session.js +462 -0
- package/dist/cloudflare-edge/src/types.js +4 -0
- package/dist/cloudflare-edge/src/worker.js +106 -0
- package/dist/cloudflare-pages/vite.config.js +14 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/mcp-server/mcp-stdio-server.js.map +1 -0
- package/dist/mcp-server/routes/claude.js.map +1 -0
- package/dist/mcp-server/routes/components.js.map +1 -0
- package/dist/mcp-server/routes/generateStory.js.map +1 -0
- package/dist/mcp-server/routes/hybridStories.js.map +1 -0
- package/dist/mcp-server/routes/memoryStories.js.map +1 -0
- package/dist/mcp-server/routes/storySync.js.map +1 -0
- package/dist/mcp-server/routes/updateStory.js +246 -0
- package/dist/mcp-server/sessionManager.js.map +1 -0
- package/dist/playground/components/AIAssistant/AIAssistant.d.ts +6 -0
- package/dist/playground/components/AIAssistant/AIAssistant.d.ts.map +1 -0
- package/dist/playground/components/AIAssistant/AIAssistant.js +109 -0
- package/dist/playground/components/AIAssistant/AIAssistant.js.map +1 -0
- package/dist/playground/components/AIAssistant/AIAssistant.module.css +166 -0
- package/dist/playground/components/Canvas/Canvas.d.ts +9 -0
- package/dist/playground/components/Canvas/Canvas.d.ts.map +1 -0
- package/dist/playground/components/Canvas/Canvas.js +58 -0
- package/dist/playground/components/Canvas/Canvas.js.map +1 -0
- package/dist/playground/components/Canvas/Canvas.module.css +189 -0
- package/dist/playground/components/Canvas/CanvasWithDnd.d.ts +9 -0
- package/dist/playground/components/Canvas/CanvasWithDnd.d.ts.map +1 -0
- package/dist/playground/components/Canvas/CanvasWithDnd.js +158 -0
- package/dist/playground/components/Canvas/CanvasWithDnd.js.map +1 -0
- package/dist/playground/components/Canvas/ComponentRenderer.d.ts +15 -0
- package/dist/playground/components/Canvas/ComponentRenderer.d.ts.map +1 -0
- package/dist/playground/components/Canvas/ComponentRenderer.js +177 -0
- package/dist/playground/components/Canvas/ComponentRenderer.js.map +1 -0
- package/dist/playground/components/Canvas/DraggableComponent.d.ts +15 -0
- package/dist/playground/components/Canvas/DraggableComponent.d.ts.map +1 -0
- package/dist/playground/components/Canvas/DraggableComponent.js +49 -0
- package/dist/playground/components/Canvas/DraggableComponent.js.map +1 -0
- package/dist/playground/components/Canvas/index.d.ts +9 -0
- package/dist/playground/components/Canvas/index.d.ts.map +1 -0
- package/dist/playground/components/Canvas/index.js +5 -0
- package/dist/playground/components/Canvas/index.js.map +1 -0
- package/dist/playground/components/CodeView/CodeView.d.ts +12 -0
- package/dist/playground/components/CodeView/CodeView.d.ts.map +1 -0
- package/dist/playground/components/CodeView/CodeView.js +77 -0
- package/dist/playground/components/CodeView/CodeView.js.map +1 -0
- package/dist/playground/components/CodeView/CodeView.module.css +178 -0
- package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts +17 -0
- package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts.map +1 -0
- package/dist/playground/components/ComponentPalette/ComponentPalette.js +138 -0
- package/dist/playground/components/ComponentPalette/ComponentPalette.js.map +1 -0
- package/dist/playground/components/ComponentPalette/ComponentPalette.module.css +217 -0
- package/dist/playground/components/ComponentPalette/index.d.ts +3 -0
- package/dist/playground/components/ComponentPalette/index.d.ts.map +1 -0
- package/dist/playground/components/ComponentPalette/index.js +2 -0
- package/dist/playground/components/ComponentPalette/index.js.map +1 -0
- package/dist/playground/components/DropZone/DropZone.d.ts +17 -0
- package/dist/playground/components/DropZone/DropZone.d.ts.map +1 -0
- package/dist/playground/components/DropZone/DropZone.js +73 -0
- package/dist/playground/components/DropZone/DropZone.js.map +1 -0
- package/dist/playground/components/DropZone/DropZone.module.css +86 -0
- package/dist/playground/components/ExportDialog/ExportDialog.d.ts +10 -0
- package/dist/playground/components/ExportDialog/ExportDialog.d.ts.map +1 -0
- package/dist/playground/components/ExportDialog/ExportDialog.js +57 -0
- package/dist/playground/components/ExportDialog/ExportDialog.js.map +1 -0
- package/dist/playground/components/ExportDialog/ExportDialog.module.css +328 -0
- package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts +134 -0
- package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts.map +1 -0
- package/dist/playground/components/LayoutHelpers/LayoutHelpers.js +254 -0
- package/dist/playground/components/LayoutHelpers/LayoutHelpers.js.map +1 -0
- package/dist/playground/components/LayoutHelpers/index.d.ts +3 -0
- package/dist/playground/components/LayoutHelpers/index.d.ts.map +1 -0
- package/dist/playground/components/LayoutHelpers/index.js +2 -0
- package/dist/playground/components/LayoutHelpers/index.js.map +1 -0
- package/dist/playground/components/Playground/Playground.d.ts +10 -0
- package/dist/playground/components/Playground/Playground.d.ts.map +1 -0
- package/dist/playground/components/Playground/Playground.js +128 -0
- package/dist/playground/components/Playground/Playground.js.map +1 -0
- package/dist/playground/components/Playground/Playground.module.css +308 -0
- package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts +10 -0
- package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts.map +1 -0
- package/dist/playground/components/PropertiesPanel/PropertiesPanel.js +150 -0
- package/dist/playground/components/PropertiesPanel/PropertiesPanel.js.map +1 -0
- package/dist/playground/components/PropertiesPanel/PropertiesPanel.module.css +155 -0
- package/dist/playground/components/PropertiesPanel/index.d.ts +3 -0
- package/dist/playground/components/PropertiesPanel/index.d.ts.map +1 -0
- package/dist/playground/components/PropertiesPanel/index.js +2 -0
- package/dist/playground/components/PropertiesPanel/index.js.map +1 -0
- package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts +12 -0
- package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/BooleanEditor.js +14 -0
- package/dist/playground/components/PropertyEditors/BooleanEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/ColorEditor.d.ts +12 -0
- package/dist/playground/components/PropertyEditors/ColorEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/ColorEditor.js +62 -0
- package/dist/playground/components/PropertyEditors/ColorEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/IconEditor.d.ts +12 -0
- package/dist/playground/components/PropertyEditors/IconEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/IconEditor.js +123 -0
- package/dist/playground/components/PropertyEditors/IconEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/NumberEditor.d.ts +15 -0
- package/dist/playground/components/PropertyEditors/NumberEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/NumberEditor.js +46 -0
- package/dist/playground/components/PropertyEditors/NumberEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/PropertyEditors.module.css +432 -0
- package/dist/playground/components/PropertyEditors/SelectEditor.d.ts +19 -0
- package/dist/playground/components/PropertyEditors/SelectEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/SelectEditor.js +17 -0
- package/dist/playground/components/PropertyEditors/SelectEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts +19 -0
- package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/SpacingEditor.js +162 -0
- package/dist/playground/components/PropertyEditors/SpacingEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/SpacingEditor.module.css +214 -0
- package/dist/playground/components/PropertyEditors/TextEditor.d.ts +14 -0
- package/dist/playground/components/PropertyEditors/TextEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/TextEditor.js +38 -0
- package/dist/playground/components/PropertyEditors/TextEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/TokenEditor.d.ts +23 -0
- package/dist/playground/components/PropertyEditors/TokenEditor.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/TokenEditor.js +50 -0
- package/dist/playground/components/PropertyEditors/TokenEditor.js.map +1 -0
- package/dist/playground/components/PropertyEditors/index.d.ts +20 -0
- package/dist/playground/components/PropertyEditors/index.d.ts.map +1 -0
- package/dist/playground/components/PropertyEditors/index.js +12 -0
- package/dist/playground/components/PropertyEditors/index.js.map +1 -0
- package/dist/playground/components/TreeView/TreeView.d.ts +10 -0
- package/dist/playground/components/TreeView/TreeView.d.ts.map +1 -0
- package/dist/playground/components/TreeView/TreeView.js +146 -0
- package/dist/playground/components/TreeView/TreeView.js.map +1 -0
- package/dist/playground/components/TreeView/TreeView.module.css +214 -0
- package/dist/playground/components/TreeView/index.d.ts +3 -0
- package/dist/playground/components/TreeView/index.d.ts.map +1 -0
- package/dist/playground/components/TreeView/index.js +2 -0
- package/dist/playground/components/TreeView/index.js.map +1 -0
- package/dist/playground/config/propertyDefinitions.d.ts +73 -0
- package/dist/playground/config/propertyDefinitions.d.ts.map +1 -0
- package/dist/playground/config/propertyDefinitions.js +809 -0
- package/dist/playground/config/propertyDefinitions.js.map +1 -0
- package/dist/playground/hooks/useKeyboardShortcuts.d.ts +38 -0
- package/dist/playground/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/playground/hooks/useKeyboardShortcuts.js +191 -0
- package/dist/playground/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/playground/index.d.ts +21 -0
- package/dist/playground/index.d.ts.map +1 -0
- package/dist/playground/index.js +23 -0
- package/dist/playground/index.js.map +1 -0
- package/dist/playground/services/CodeGenerator.d.ts +73 -0
- package/dist/playground/services/CodeGenerator.d.ts.map +1 -0
- package/dist/playground/services/CodeGenerator.js +359 -0
- package/dist/playground/services/CodeGenerator.js.map +1 -0
- package/dist/playground/services/DragDropManager.d.ts +95 -0
- package/dist/playground/services/DragDropManager.d.ts.map +1 -0
- package/dist/playground/services/DragDropManager.js +408 -0
- package/dist/playground/services/DragDropManager.js.map +1 -0
- package/dist/playground/services/StoryParser.d.ts +73 -0
- package/dist/playground/services/StoryParser.d.ts.map +1 -0
- package/dist/playground/services/StoryParser.js +419 -0
- package/dist/playground/services/StoryParser.js.map +1 -0
- package/dist/playground/store/playgroundStore.d.ts +86 -0
- package/dist/playground/store/playgroundStore.d.ts.map +1 -0
- package/dist/playground/store/playgroundStore.js +337 -0
- package/dist/playground/store/playgroundStore.js.map +1 -0
- package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts +13 -0
- package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts.map +1 -0
- package/dist/playground/stories/PlaygroundDragDrop.stories.js +227 -0
- package/dist/playground/stories/PlaygroundDragDrop.stories.js.map +1 -0
- package/dist/playground/stories/PlaygroundPhase4.stories.d.ts +13 -0
- package/dist/playground/stories/PlaygroundPhase4.stories.d.ts.map +1 -0
- package/dist/playground/stories/PlaygroundPhase4.stories.js +334 -0
- package/dist/playground/stories/PlaygroundPhase4.stories.js.map +1 -0
- package/dist/playground/stories/PlaygroundPhase5.stories.d.ts +14 -0
- package/dist/playground/stories/PlaygroundPhase5.stories.d.ts.map +1 -0
- package/dist/playground/stories/PlaygroundPhase5.stories.js +512 -0
- package/dist/playground/stories/PlaygroundPhase5.stories.js.map +1 -0
- package/dist/playground/stories/PlaygroundProperties.stories.d.ts +13 -0
- package/dist/playground/stories/PlaygroundProperties.stories.d.ts.map +1 -0
- package/dist/playground/stories/PlaygroundProperties.stories.js +342 -0
- package/dist/playground/stories/PlaygroundProperties.stories.js.map +1 -0
- package/dist/playground/types/index.d.ts +251 -0
- package/dist/playground/types/index.d.ts.map +1 -0
- package/dist/playground/types/index.js +5 -0
- package/dist/playground/types/index.js.map +1 -0
- package/dist/scripts/verify-framework-adapters.js +105 -0
- package/dist/story-generator/componentBlacklist.js.map +1 -0
- package/dist/story-generator/componentDiscovery.js.map +1 -0
- package/dist/story-generator/configLoader.js.map +1 -0
- package/dist/story-generator/considerationsLoader.js.map +1 -0
- package/dist/story-generator/documentation-sources.js.map +1 -0
- package/dist/story-generator/documentationLoader.js.map +1 -0
- package/dist/story-generator/dynamicPackageDiscovery.js.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -1
- package/dist/story-generator/enhancedComponentDiscovery.js +4 -6
- package/dist/story-generator/enhancedComponentDiscovery.js.map +1 -0
- package/dist/story-generator/generateStory.js.map +1 -0
- package/dist/story-generator/gitignoreManager.js.map +1 -0
- package/dist/story-generator/inMemoryStoryService.js.map +1 -0
- package/dist/story-generator/llm-providers/settings-manager.js +4 -4
- package/dist/story-generator/logger.js.map +1 -0
- package/dist/story-generator/postProcessStory.js.map +1 -0
- package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -1
- package/dist/story-generator/productionGitignoreManager.js +6 -0
- package/dist/story-generator/productionGitignoreManager.js.map +1 -0
- package/dist/story-generator/promptGenerator.js.map +1 -0
- package/dist/story-generator/providerPresets.d.ts +54 -0
- package/dist/story-generator/providerPresets.d.ts.map +1 -0
- package/dist/story-generator/providerPresets.js +214 -0
- package/dist/story-generator/storyHistory.js.map +1 -0
- package/dist/story-generator/storySync.js.map +1 -0
- package/dist/story-generator/storyTracker.js.map +1 -0
- package/dist/story-generator/storyValidator.js.map +1 -0
- package/dist/story-generator/test_validation.d.ts +2 -0
- package/dist/story-generator/test_validation.d.ts.map +1 -0
- package/dist/story-generator/test_validation.js +51 -0
- package/dist/story-generator/universalDesignSystemAdapter.js.map +1 -0
- package/dist/story-generator/urlRedirectService.js.map +1 -0
- package/dist/story-generator/validateStory.js.map +1 -0
- package/dist/story-ui.config.js.map +1 -0
- package/dist/story-ui.config.loader.d.ts +36 -0
- package/dist/story-ui.config.loader.d.ts.map +1 -0
- package/dist/story-ui.config.loader.js +205 -0
- package/dist/story-ui.config.loader.js.map +1 -0
- package/dist/temp/package/templates/StoryUI/StoryUIPanel.js +807 -0
- package/dist/temp/package/templates/StoryUI/StoryUIPanel.stories.js +37 -0
- package/dist/temp/package/templates/StoryUI/index.js +2 -0
- package/dist/templates/StoryUI/StoryUIPanel.js.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.js.map +1 -0
- package/dist/templates/StoryUI/index.js.map +1 -0
- package/dist/templates/StoryUI/manager.d.ts +14 -0
- package/dist/templates/StoryUI/manager.d.ts.map +1 -0
- package/dist/templates/production-app/src/App.d.ts +10 -0
- package/dist/templates/production-app/src/App.d.ts.map +1 -0
- package/dist/templates/production-app/src/App.js +653 -0
- package/dist/templates/production-app/src/LivePreviewRenderer.d.ts +24 -0
- package/dist/templates/production-app/src/LivePreviewRenderer.d.ts.map +1 -0
- package/dist/templates/production-app/src/LivePreviewRenderer.js +199 -0
- package/dist/templates/production-app/src/componentRegistry.d.ts +20 -0
- package/dist/templates/production-app/src/componentRegistry.d.ts.map +1 -0
- package/dist/templates/production-app/src/componentRegistry.js +316 -0
- package/dist/templates/production-app/src/main.d.ts +9 -0
- package/dist/templates/production-app/src/main.d.ts.map +1 -0
- package/dist/templates/production-app/src/main.js +18 -0
- package/dist/templates/production-app/vite.config.d.ts +3 -0
- package/dist/templates/production-app/vite.config.d.ts.map +1 -0
- package/dist/templates/production-app/vite.config.js +71 -0
- package/dist/test-storybooks/angular-material-storybook/src/main.js +66 -0
- package/dist/test-storybooks/chakra-storybook/vite.config.js +6 -0
- package/dist/test-storybooks/mantine-storybook/vite.config.js +93 -0
- package/dist/test-storybooks/web-components-shoelace/vite.config.js +9 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/visual-builder/components/Canvas/Canvas.js +70 -0
- package/dist/visual-builder/components/Canvas/ComponentRenderer.js +545 -0
- package/dist/visual-builder/components/CodeExporter/CodeExporter.js +25 -0
- package/dist/visual-builder/components/CodeExporter/codeGenerator.js +99 -0
- package/dist/visual-builder/components/ComponentPalette/ComponentPalette.js +8 -0
- package/dist/visual-builder/components/ComponentPalette/ComponentPaletteItem.js +51 -0
- package/dist/visual-builder/components/EmbeddedVisualBuilder.js +107 -0
- package/dist/visual-builder/components/PropertyEditor/PropertyEditor.js +16 -0
- package/dist/visual-builder/components/PropertyEditor/PropertyForm.js +88 -0
- package/dist/visual-builder/components/PropertyEditor/SpacingControl.js +145 -0
- package/dist/visual-builder/components/PropertyEditor/SpacingEditor.js +32 -0
- package/dist/visual-builder/components/StoryManager/SaveOnlyManager.js +94 -0
- package/dist/visual-builder/components/StoryManager/StoryManager.js +68 -0
- package/dist/visual-builder/components/StoryManager/index.js +1 -0
- package/dist/visual-builder/components/VisualBuilder.js +256 -0
- package/dist/visual-builder/config/componentRegistry.js +1758 -0
- package/dist/visual-builder/decorators/VisualBuilderDecorator.js +184 -0
- package/dist/visual-builder/example-integration.js +59 -0
- package/dist/visual-builder/example.js +23 -0
- package/dist/visual-builder/hooks/useDragAndDrop.js +137 -0
- package/dist/visual-builder/hooks/useSelection.js +27 -0
- package/dist/visual-builder/index.js +7 -0
- package/dist/visual-builder/store/visualBuilderStore.js +305 -0
- package/dist/visual-builder/types/index.js +1 -0
- package/dist/visual-builder/utils/__tests__/storyFileUpdater.test.js +145 -0
- package/dist/visual-builder/utils/aiParser.js +336 -0
- package/dist/visual-builder/utils/componentTreeUtils.js +111 -0
- package/dist/visual-builder/utils/parserValidation.js +122 -0
- package/dist/visual-builder/utils/storyFileManager.js +73 -0
- package/dist/visual-builder/utils/storyFileUpdater.js +326 -0
- package/dist/visual-builder/utils/storyNameExtraction.test.js +211 -0
- package/dist/visual-builder/utils/storyPersistence.js +180 -0
- package/dist/visual-builder/utils/storyToBuilder.js +813 -0
- package/package.json +1 -1
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import { devtools } from 'zustand/middleware';
|
|
3
|
+
import { removeComponentFromTree, insertComponentInTree, findComponentWithParent, isDescendant } from '../utils/componentTreeUtils';
|
|
4
|
+
import { saveStory, loadStory, scheduleAutoSave, cancelAutoSave } from '../utils/storyPersistence';
|
|
5
|
+
export const useVisualBuilderStore = create()(devtools((set, _get) => ({
|
|
6
|
+
// Initial state
|
|
7
|
+
components: [],
|
|
8
|
+
selectedComponent: null,
|
|
9
|
+
draggedComponent: null,
|
|
10
|
+
isCodeModalOpen: false,
|
|
11
|
+
isImportedFromStory: false,
|
|
12
|
+
// Story management state
|
|
13
|
+
currentStoryId: null,
|
|
14
|
+
currentStoryName: 'Untitled Story',
|
|
15
|
+
isDirty: false,
|
|
16
|
+
// Actions
|
|
17
|
+
addComponent: (component, targetId, insertIndex) => {
|
|
18
|
+
set((state) => {
|
|
19
|
+
const newComponent = { ...component, id: `${component.type}-${Date.now()}` };
|
|
20
|
+
let newComponents;
|
|
21
|
+
if (targetId) {
|
|
22
|
+
// Add as child to target component
|
|
23
|
+
const updateComponents = (components) => {
|
|
24
|
+
return components.map(comp => {
|
|
25
|
+
if (comp.id === targetId) {
|
|
26
|
+
const children = comp.children || [];
|
|
27
|
+
const newChildren = insertIndex !== undefined
|
|
28
|
+
? [...children.slice(0, insertIndex), newComponent, ...children.slice(insertIndex)]
|
|
29
|
+
: [...children, newComponent];
|
|
30
|
+
return {
|
|
31
|
+
...comp,
|
|
32
|
+
children: newChildren
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (comp.children) {
|
|
36
|
+
return {
|
|
37
|
+
...comp,
|
|
38
|
+
children: updateComponents(comp.children)
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return comp;
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
newComponents = updateComponents(state.components);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Add to root level
|
|
48
|
+
newComponents = insertIndex !== undefined
|
|
49
|
+
? [...state.components.slice(0, insertIndex), newComponent, ...state.components.slice(insertIndex)]
|
|
50
|
+
: [...state.components, newComponent];
|
|
51
|
+
}
|
|
52
|
+
// Mark as dirty and schedule auto-save
|
|
53
|
+
scheduleAutoSave(state.currentStoryName, newComponents, state.currentStoryId || undefined);
|
|
54
|
+
return { components: newComponents, isDirty: true };
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
removeComponent: (id) => {
|
|
58
|
+
set((state) => {
|
|
59
|
+
const removeFromComponents = (components) => {
|
|
60
|
+
return components
|
|
61
|
+
.filter(comp => comp.id !== id)
|
|
62
|
+
.map(comp => ({
|
|
63
|
+
...comp,
|
|
64
|
+
children: comp.children ? removeFromComponents(comp.children) : undefined
|
|
65
|
+
}));
|
|
66
|
+
};
|
|
67
|
+
const newComponents = removeFromComponents(state.components);
|
|
68
|
+
// Mark as dirty and schedule auto-save
|
|
69
|
+
scheduleAutoSave(state.currentStoryName, newComponents, state.currentStoryId || undefined);
|
|
70
|
+
return {
|
|
71
|
+
components: newComponents,
|
|
72
|
+
selectedComponent: state.selectedComponent?.id === id ? null : state.selectedComponent,
|
|
73
|
+
isDirty: true
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
updateComponent: (id, updates) => {
|
|
78
|
+
set((state) => {
|
|
79
|
+
const updateComponents = (components) => {
|
|
80
|
+
return components.map(comp => {
|
|
81
|
+
if (comp.id === id) {
|
|
82
|
+
return { ...comp, ...updates };
|
|
83
|
+
}
|
|
84
|
+
if (comp.children) {
|
|
85
|
+
return {
|
|
86
|
+
...comp,
|
|
87
|
+
children: updateComponents(comp.children)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return comp;
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
const newComponents = updateComponents(state.components);
|
|
94
|
+
// Mark as dirty and schedule auto-save
|
|
95
|
+
scheduleAutoSave(state.currentStoryName, newComponents, state.currentStoryId || undefined);
|
|
96
|
+
return { components: newComponents, isDirty: true };
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
selectComponent: (component) => {
|
|
100
|
+
set({ selectedComponent: component });
|
|
101
|
+
},
|
|
102
|
+
setDraggedComponent: (component) => {
|
|
103
|
+
set({ draggedComponent: component });
|
|
104
|
+
},
|
|
105
|
+
openCodeModal: () => {
|
|
106
|
+
set({ isCodeModalOpen: true });
|
|
107
|
+
},
|
|
108
|
+
closeCodeModal: () => {
|
|
109
|
+
set({ isCodeModalOpen: false });
|
|
110
|
+
},
|
|
111
|
+
clearCanvas: () => {
|
|
112
|
+
set({
|
|
113
|
+
components: [],
|
|
114
|
+
selectedComponent: null,
|
|
115
|
+
isImportedFromStory: false,
|
|
116
|
+
isDirty: true
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
moveComponent: (activeId, overId, insertIndex, insertPosition) => {
|
|
120
|
+
set((state) => {
|
|
121
|
+
// Prevent moving a component into itself or its descendants
|
|
122
|
+
if (activeId === overId || isDescendant(state.components, activeId, overId)) {
|
|
123
|
+
return state;
|
|
124
|
+
}
|
|
125
|
+
// Remove the component from its current location
|
|
126
|
+
const { components: updatedComponents, removed } = removeComponentFromTree(state.components, activeId);
|
|
127
|
+
if (!removed) {
|
|
128
|
+
return state; // Component not found
|
|
129
|
+
}
|
|
130
|
+
// Determine insertion target and index
|
|
131
|
+
let targetContainerId = null;
|
|
132
|
+
let insertionIndex = insertIndex;
|
|
133
|
+
if (insertIndex !== undefined) {
|
|
134
|
+
// Direct insertion at specific index (root level)
|
|
135
|
+
targetContainerId = null;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// Insert relative to another component
|
|
139
|
+
const overComponent = findComponentWithParent(updatedComponents, overId);
|
|
140
|
+
if (overComponent) {
|
|
141
|
+
if (overComponent.parent) {
|
|
142
|
+
targetContainerId = overComponent.parent.id;
|
|
143
|
+
insertionIndex = overComponent.index + (insertPosition === 'after' ? 1 : 0);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// Insert at root level
|
|
147
|
+
targetContainerId = null;
|
|
148
|
+
insertionIndex = overComponent.index + (insertPosition === 'after' ? 1 : 0);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Insert the component at the new location
|
|
153
|
+
const finalComponents = insertComponentInTree(updatedComponents, removed, targetContainerId, insertionIndex);
|
|
154
|
+
// Mark as dirty and schedule auto-save
|
|
155
|
+
scheduleAutoSave(state.currentStoryName, finalComponents, state.currentStoryId || undefined);
|
|
156
|
+
return { components: finalComponents, isDirty: true };
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
moveComponentBetweenContainers: (activeId, _fromParentId, toParentId, insertIndex) => {
|
|
160
|
+
set((state) => {
|
|
161
|
+
// Prevent moving a component into itself or its descendants
|
|
162
|
+
if (activeId === toParentId || (toParentId && isDescendant(state.components, activeId, toParentId))) {
|
|
163
|
+
return state;
|
|
164
|
+
}
|
|
165
|
+
// Remove component from its current location
|
|
166
|
+
const { components: afterRemoval, removed } = removeComponentFromTree(state.components, activeId);
|
|
167
|
+
if (!removed) {
|
|
168
|
+
return state; // Component not found
|
|
169
|
+
}
|
|
170
|
+
// Add component to new location
|
|
171
|
+
const finalComponents = insertComponentInTree(afterRemoval, removed, toParentId, insertIndex);
|
|
172
|
+
// Mark as dirty and schedule auto-save
|
|
173
|
+
scheduleAutoSave(state.currentStoryName, finalComponents, state.currentStoryId || undefined);
|
|
174
|
+
return { components: finalComponents, isDirty: true };
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
loadFromAI: (components) => {
|
|
178
|
+
set({
|
|
179
|
+
components,
|
|
180
|
+
selectedComponent: null,
|
|
181
|
+
isImportedFromStory: false,
|
|
182
|
+
isDirty: true
|
|
183
|
+
});
|
|
184
|
+
},
|
|
185
|
+
loadFromCode: async (code) => {
|
|
186
|
+
try {
|
|
187
|
+
const { parseAIGeneratedCode } = await import('../utils/aiParser');
|
|
188
|
+
const result = parseAIGeneratedCode(code);
|
|
189
|
+
if (result.errors.length === 0) {
|
|
190
|
+
set({
|
|
191
|
+
components: result.components,
|
|
192
|
+
selectedComponent: null,
|
|
193
|
+
isImportedFromStory: false,
|
|
194
|
+
isDirty: true
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
success: result.errors.length === 0,
|
|
199
|
+
errors: result.errors,
|
|
200
|
+
warnings: result.warnings
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
errors: [`Failed to load parser: ${error instanceof Error ? error.message : 'Unknown error'}`],
|
|
207
|
+
warnings: []
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
importFromStoryUI: async (storyCode) => {
|
|
212
|
+
try {
|
|
213
|
+
const { parseStoryUIToBuilder, validateParsedComponents, extractStoryName } = await import('../utils/storyToBuilder');
|
|
214
|
+
const parseResult = parseStoryUIToBuilder(storyCode);
|
|
215
|
+
// Validate the parsed components
|
|
216
|
+
const validationIssues = validateParsedComponents(parseResult.components);
|
|
217
|
+
const allWarnings = [...parseResult.warnings, ...validationIssues];
|
|
218
|
+
// Extract story name using the improved extraction function
|
|
219
|
+
const storyName = extractStoryName(storyCode);
|
|
220
|
+
// Determine if this is an existing story (has a valid extracted name)
|
|
221
|
+
const isEditingExistingStory = storyName !== 'Imported Story' && storyName !== 'Untitled Story';
|
|
222
|
+
if (parseResult.errors.length === 0) {
|
|
223
|
+
// Generate or use existing story ID
|
|
224
|
+
const state = _get();
|
|
225
|
+
const storyId = state.currentStoryId || `story-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
226
|
+
set({
|
|
227
|
+
components: parseResult.components,
|
|
228
|
+
selectedComponent: null,
|
|
229
|
+
isImportedFromStory: true, // Mark as imported from story
|
|
230
|
+
currentStoryName: storyName, // Set the extracted story name
|
|
231
|
+
currentStoryId: storyId, // Set the story ID
|
|
232
|
+
isDirty: isEditingExistingStory ? false : true // Start clean for existing stories, dirty for new imports
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
success: parseResult.errors.length === 0,
|
|
237
|
+
errors: parseResult.errors,
|
|
238
|
+
warnings: allWarnings
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
return {
|
|
243
|
+
success: false,
|
|
244
|
+
errors: [`Failed to import from Story UI: ${error instanceof Error ? error.message : 'Unknown error'}`],
|
|
245
|
+
warnings: []
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
// Story management actions
|
|
250
|
+
saveCurrentStory: (name) => {
|
|
251
|
+
const state = _get();
|
|
252
|
+
const storyName = name || state.currentStoryName;
|
|
253
|
+
const savedStory = saveStory(storyName, state.components, state.currentStoryId || undefined);
|
|
254
|
+
set({
|
|
255
|
+
currentStoryId: savedStory.id,
|
|
256
|
+
currentStoryName: savedStory.name,
|
|
257
|
+
isDirty: false
|
|
258
|
+
});
|
|
259
|
+
// Update URL with story ID
|
|
260
|
+
const url = new URL(window.location.href);
|
|
261
|
+
url.searchParams.set('story', savedStory.id);
|
|
262
|
+
window.history.replaceState({}, '', url.toString());
|
|
263
|
+
return savedStory;
|
|
264
|
+
},
|
|
265
|
+
loadStoryById: (id) => {
|
|
266
|
+
const story = loadStory(id);
|
|
267
|
+
if (story) {
|
|
268
|
+
cancelAutoSave(); // Cancel any pending auto-save
|
|
269
|
+
set({
|
|
270
|
+
components: story.components,
|
|
271
|
+
currentStoryId: story.id,
|
|
272
|
+
currentStoryName: story.name,
|
|
273
|
+
isDirty: false,
|
|
274
|
+
selectedComponent: null,
|
|
275
|
+
isImportedFromStory: false
|
|
276
|
+
});
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
},
|
|
281
|
+
markDirty: () => {
|
|
282
|
+
set({ isDirty: true });
|
|
283
|
+
},
|
|
284
|
+
markClean: () => {
|
|
285
|
+
set({ isDirty: false });
|
|
286
|
+
},
|
|
287
|
+
setCurrentStoryName: (name) => {
|
|
288
|
+
set({ currentStoryName: name, isDirty: true });
|
|
289
|
+
},
|
|
290
|
+
newStory: () => {
|
|
291
|
+
cancelAutoSave();
|
|
292
|
+
set({
|
|
293
|
+
components: [],
|
|
294
|
+
selectedComponent: null,
|
|
295
|
+
currentStoryId: null,
|
|
296
|
+
currentStoryName: 'Untitled Story',
|
|
297
|
+
isDirty: false,
|
|
298
|
+
isImportedFromStory: false
|
|
299
|
+
});
|
|
300
|
+
// Remove story parameter from URL
|
|
301
|
+
const url = new URL(window.location.href);
|
|
302
|
+
url.searchParams.delete('story');
|
|
303
|
+
window.history.replaceState({}, '', url.toString());
|
|
304
|
+
}
|
|
305
|
+
}), { name: 'visual-builder-store' }));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { generateStoryFileContent, generatePropsString } from '../storyFileUpdater';
|
|
2
|
+
describe('storyFileUpdater', () => {
|
|
3
|
+
describe('generatePropsString', () => {
|
|
4
|
+
it('should generate correct style props with double curly braces', () => {
|
|
5
|
+
const props = {
|
|
6
|
+
style: { maxWidth: 400, padding: '1rem' }
|
|
7
|
+
};
|
|
8
|
+
const result = generatePropsString(props, 'Card');
|
|
9
|
+
// Should have double curly braces for style object
|
|
10
|
+
expect(result).toBe(' style={{ maxWidth: 400, padding: \'1rem\' }}');
|
|
11
|
+
expect(result).not.toContain('style="');
|
|
12
|
+
expect(result).toContain('style={{');
|
|
13
|
+
});
|
|
14
|
+
it('should handle numeric values in style objects correctly', () => {
|
|
15
|
+
const props = {
|
|
16
|
+
style: { width: 300, height: 200, zIndex: 10 }
|
|
17
|
+
};
|
|
18
|
+
const result = generatePropsString(props, 'div');
|
|
19
|
+
expect(result).toBe(' style={{ width: 300, height: 200, zIndex: 10 }}');
|
|
20
|
+
});
|
|
21
|
+
it('should handle string values in style objects with quotes', () => {
|
|
22
|
+
const props = {
|
|
23
|
+
style: { color: 'red', backgroundColor: '#fff', display: 'flex' }
|
|
24
|
+
};
|
|
25
|
+
const result = generatePropsString(props, 'div');
|
|
26
|
+
expect(result).toBe(' style={{ color: \'red\', backgroundColor: \'#fff\', display: \'flex\' }}');
|
|
27
|
+
});
|
|
28
|
+
it('should handle mixed style values correctly', () => {
|
|
29
|
+
const props = {
|
|
30
|
+
style: {
|
|
31
|
+
maxWidth: 400,
|
|
32
|
+
padding: '1rem',
|
|
33
|
+
margin: 0,
|
|
34
|
+
display: 'block'
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const result = generatePropsString(props, 'Card');
|
|
38
|
+
expect(result).toBe(' style={{ maxWidth: 400, padding: \'1rem\', margin: 0, display: \'block\' }}');
|
|
39
|
+
});
|
|
40
|
+
it('should handle other prop types correctly alongside style', () => {
|
|
41
|
+
const props = {
|
|
42
|
+
shadow: 'md',
|
|
43
|
+
padding: 'xl',
|
|
44
|
+
radius: 'md',
|
|
45
|
+
withBorder: true,
|
|
46
|
+
style: { maxWidth: 400 }
|
|
47
|
+
};
|
|
48
|
+
const result = generatePropsString(props, 'Card');
|
|
49
|
+
expect(result).toContain('shadow="md"');
|
|
50
|
+
expect(result).toContain('padding="xl"');
|
|
51
|
+
expect(result).toContain('radius="md"');
|
|
52
|
+
expect(result).toContain('withBorder');
|
|
53
|
+
expect(result).toContain('style={{ maxWidth: 400 }}');
|
|
54
|
+
expect(result).not.toContain('style="');
|
|
55
|
+
});
|
|
56
|
+
it('should filter out children prop for Text components', () => {
|
|
57
|
+
const props = {
|
|
58
|
+
children: 'Some text',
|
|
59
|
+
size: 'lg'
|
|
60
|
+
};
|
|
61
|
+
const result = generatePropsString(props, 'Text');
|
|
62
|
+
expect(result).toBe(' size="lg"');
|
|
63
|
+
expect(result).not.toContain('children');
|
|
64
|
+
});
|
|
65
|
+
it('should keep children prop for Button components', () => {
|
|
66
|
+
const props = {
|
|
67
|
+
children: 'Click me',
|
|
68
|
+
variant: 'outline'
|
|
69
|
+
};
|
|
70
|
+
const result = generatePropsString(props, 'Button');
|
|
71
|
+
expect(result).toContain('children="Click me"');
|
|
72
|
+
expect(result).toContain('variant="outline"');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('generateStoryFileContent', () => {
|
|
76
|
+
it('should generate story with correct style syntax', () => {
|
|
77
|
+
const components = [{
|
|
78
|
+
id: 'card1',
|
|
79
|
+
type: 'Card',
|
|
80
|
+
displayName: 'Card',
|
|
81
|
+
category: 'mantine',
|
|
82
|
+
props: {
|
|
83
|
+
shadow: 'md',
|
|
84
|
+
padding: 'xl',
|
|
85
|
+
radius: 'md',
|
|
86
|
+
withBorder: true,
|
|
87
|
+
style: { maxWidth: 400 }
|
|
88
|
+
},
|
|
89
|
+
children: []
|
|
90
|
+
}];
|
|
91
|
+
const result = generateStoryFileContent(components, 'TestStory', 'test.stories.tsx');
|
|
92
|
+
// Should contain double curly braces, not single quotes around object
|
|
93
|
+
expect(result).toContain('style={{ maxWidth: 400 }}');
|
|
94
|
+
expect(result).not.toContain('style="{ maxWidth: 400 }"');
|
|
95
|
+
expect(result).not.toContain('style="');
|
|
96
|
+
});
|
|
97
|
+
it('should generate story with complex style objects correctly', () => {
|
|
98
|
+
const components = [{
|
|
99
|
+
id: 'div1',
|
|
100
|
+
type: 'div',
|
|
101
|
+
displayName: 'div',
|
|
102
|
+
category: 'html',
|
|
103
|
+
props: {
|
|
104
|
+
style: {
|
|
105
|
+
maxWidth: 400,
|
|
106
|
+
padding: '1rem',
|
|
107
|
+
margin: 0,
|
|
108
|
+
backgroundColor: '#f8f9fa',
|
|
109
|
+
borderRadius: '8px'
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
children: []
|
|
113
|
+
}];
|
|
114
|
+
const result = generateStoryFileContent(components, 'ComplexStyle', 'complex.stories.tsx');
|
|
115
|
+
expect(result).toContain('style={{ maxWidth: 400, padding: \'1rem\', margin: 0, backgroundColor: \'#f8f9fa\', borderRadius: \'8px\' }}');
|
|
116
|
+
expect(result).not.toContain('style="');
|
|
117
|
+
});
|
|
118
|
+
it('should handle nested components with styles correctly', () => {
|
|
119
|
+
const components = [{
|
|
120
|
+
id: 'card1',
|
|
121
|
+
type: 'Card',
|
|
122
|
+
displayName: 'Card',
|
|
123
|
+
category: 'mantine',
|
|
124
|
+
props: {
|
|
125
|
+
style: { maxWidth: 400 }
|
|
126
|
+
},
|
|
127
|
+
children: [{
|
|
128
|
+
id: 'stack1',
|
|
129
|
+
type: 'Stack',
|
|
130
|
+
displayName: 'Stack',
|
|
131
|
+
category: 'mantine',
|
|
132
|
+
props: {
|
|
133
|
+
gap: 'md',
|
|
134
|
+
style: { padding: '1rem' }
|
|
135
|
+
},
|
|
136
|
+
children: []
|
|
137
|
+
}]
|
|
138
|
+
}];
|
|
139
|
+
const result = generateStoryFileContent(components, 'NestedStyles', 'nested.stories.tsx');
|
|
140
|
+
expect(result).toContain('style={{ maxWidth: 400 }}');
|
|
141
|
+
expect(result).toContain('style={{ padding: \'1rem\' }}');
|
|
142
|
+
expect(result).not.toContain('style="');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|