@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,545 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
|
4
|
+
import { Box, Button, TextInput, Text, Title, Container, Group, Stack, Card, Badge, Anchor, Image, Divider, Paper, Alert, PasswordInput, Textarea, Select, MultiSelect, NumberInput, Checkbox, Radio, Switch, Flex, Grid, GridCol, SimpleGrid, Code, Mark, Blockquote, Avatar, Indicator, Breadcrumbs, Tabs, Loader, Progress, RingProgress, Tooltip, Popover } from '@mantine/core';
|
|
5
|
+
import { useSelection } from '../../hooks/useSelection';
|
|
6
|
+
import { useVisualBuilderStore } from '../../store/visualBuilderStore';
|
|
7
|
+
import { CONTAINER_COMPONENTS, MANTINE_COMPONENTS } from '../../config/componentRegistry';
|
|
8
|
+
// Helper function to extract spacing props from component props
|
|
9
|
+
const extractSpacingProps = (props) => {
|
|
10
|
+
const spacingProps = {};
|
|
11
|
+
// Extract spacing properties and filter out undefined values
|
|
12
|
+
['m', 'mt', 'mr', 'mb', 'ml', 'mx', 'my', 'p', 'pt', 'pr', 'pb', 'pl', 'px', 'py'].forEach(key => {
|
|
13
|
+
if (props[key] !== undefined && props[key] !== null && props[key] !== '') {
|
|
14
|
+
spacingProps[key] = props[key];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return spacingProps;
|
|
18
|
+
};
|
|
19
|
+
const DropZone = ({ parentId, insertIndex, isVisible }) => {
|
|
20
|
+
const { setNodeRef, isOver } = useDroppable({
|
|
21
|
+
id: `dropzone-${parentId || 'root'}-${insertIndex}`,
|
|
22
|
+
data: {
|
|
23
|
+
isInsertionPoint: true,
|
|
24
|
+
parentId,
|
|
25
|
+
insertIndex,
|
|
26
|
+
insertPosition: 'before'
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
if (!isVisible)
|
|
30
|
+
return null;
|
|
31
|
+
return (_jsx(Box, { ref: setNodeRef, style: {
|
|
32
|
+
height: isOver ? '8px' : '2px',
|
|
33
|
+
backgroundColor: isOver ? '#3b82f6' : 'transparent',
|
|
34
|
+
border: isOver ? '2px dashed #3b82f6' : '1px dashed #e5e7eb',
|
|
35
|
+
borderRadius: '2px',
|
|
36
|
+
margin: '2px 0',
|
|
37
|
+
transition: 'all 0.2s ease-in-out',
|
|
38
|
+
opacity: isOver ? 1 : 0.5
|
|
39
|
+
} }));
|
|
40
|
+
};
|
|
41
|
+
export const ComponentRenderer = ({ component, index: _index, parentId = null, preserveOriginalLayout = false }) => {
|
|
42
|
+
const { handleComponentSelect, isSelected } = useSelection();
|
|
43
|
+
const { draggedComponent } = useVisualBuilderStore();
|
|
44
|
+
const selected = isSelected(component.id);
|
|
45
|
+
const isDraggedComponent = draggedComponent?.id === component.id;
|
|
46
|
+
// Draggable setup for existing components
|
|
47
|
+
const { attributes, listeners, setNodeRef: dragRef, transform, isDragging, } = useDraggable({
|
|
48
|
+
id: component.id,
|
|
49
|
+
data: {
|
|
50
|
+
component,
|
|
51
|
+
isFromCanvas: true,
|
|
52
|
+
parentId
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Droppable setup for container components
|
|
56
|
+
const isContainer = CONTAINER_COMPONENTS.includes(component.type);
|
|
57
|
+
// Get all component types for accepts array
|
|
58
|
+
const allComponentTypes = MANTINE_COMPONENTS.map(comp => comp.type);
|
|
59
|
+
const { setNodeRef: dropRef, isOver } = useDroppable({
|
|
60
|
+
id: `${component.id}-drop`,
|
|
61
|
+
data: {
|
|
62
|
+
isContainer: true,
|
|
63
|
+
componentId: component.id,
|
|
64
|
+
accepts: allComponentTypes
|
|
65
|
+
},
|
|
66
|
+
disabled: !isContainer
|
|
67
|
+
});
|
|
68
|
+
const style = transform ? {
|
|
69
|
+
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
|
|
70
|
+
opacity: isDragging || isDraggedComponent ? 0.5 : 1,
|
|
71
|
+
zIndex: isDragging ? 1000 : 'auto',
|
|
72
|
+
} : { opacity: isDraggedComponent ? 0.5 : 1 };
|
|
73
|
+
// Show drop zones when dragging
|
|
74
|
+
const showDropZones = Boolean(draggedComponent && !isDraggedComponent);
|
|
75
|
+
const renderComponent = () => {
|
|
76
|
+
const { type, props, children } = component;
|
|
77
|
+
// Extract spacing props for all components
|
|
78
|
+
const spacingProps = extractSpacingProps(props);
|
|
79
|
+
// Ensure style is an object, not a string
|
|
80
|
+
let styleObject = {};
|
|
81
|
+
if (props.style) {
|
|
82
|
+
if (typeof props.style === 'string') {
|
|
83
|
+
// If style is still a string, try to parse it
|
|
84
|
+
try {
|
|
85
|
+
// Handle case where style might be a stringified object
|
|
86
|
+
if (props.style.startsWith('{') && props.style.endsWith('}')) {
|
|
87
|
+
const styleStr = props.style.slice(1, -1);
|
|
88
|
+
const pairs = styleStr.split(',');
|
|
89
|
+
styleObject = {};
|
|
90
|
+
for (const pair of pairs) {
|
|
91
|
+
const colonIndex = pair.indexOf(':');
|
|
92
|
+
if (colonIndex > -1) {
|
|
93
|
+
const key = pair.substring(0, colonIndex).trim().replace(/['"]/g, '');
|
|
94
|
+
const value = pair.substring(colonIndex + 1).trim().replace(/['"]/g, '');
|
|
95
|
+
styleObject[key] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
console.warn('Failed to parse style string:', props.style);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else if (typeof props.style === 'object' && !Array.isArray(props.style)) {
|
|
105
|
+
styleObject = props.style;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const commonProps = {
|
|
109
|
+
onClick: (e) => {
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
handleComponentSelect(component);
|
|
112
|
+
},
|
|
113
|
+
style: {
|
|
114
|
+
cursor: 'pointer',
|
|
115
|
+
...styleObject
|
|
116
|
+
},
|
|
117
|
+
...spacingProps
|
|
118
|
+
};
|
|
119
|
+
// Special handling for Button components when preserveOriginalLayout is true
|
|
120
|
+
const buttonProps = type === 'Button' && preserveOriginalLayout ? {
|
|
121
|
+
onClick: (e) => {
|
|
122
|
+
e.stopPropagation();
|
|
123
|
+
handleComponentSelect(component);
|
|
124
|
+
},
|
|
125
|
+
style: {
|
|
126
|
+
cursor: 'pointer',
|
|
127
|
+
...styleObject,
|
|
128
|
+
// Ensure fullWidth is properly applied
|
|
129
|
+
width: props.fullWidth ? '100%' : styleObject.width || 'auto'
|
|
130
|
+
},
|
|
131
|
+
...spacingProps
|
|
132
|
+
} : commonProps;
|
|
133
|
+
switch (type) {
|
|
134
|
+
case 'Button':
|
|
135
|
+
const finalButtonProps = type === 'Button' ? buttonProps : commonProps;
|
|
136
|
+
console.log(`🔵 [Button] fullWidth: ${props.fullWidth}, preserveOriginalLayout: ${preserveOriginalLayout}`);
|
|
137
|
+
console.log(`🔵 [Button] Final props width:`, finalButtonProps.style?.width);
|
|
138
|
+
console.log(`🔵 [Button] All props:`, {
|
|
139
|
+
fullWidth: props.fullWidth,
|
|
140
|
+
variant: props.variant,
|
|
141
|
+
children: props.children
|
|
142
|
+
});
|
|
143
|
+
return (_jsx(Button, { ...finalButtonProps, variant: props.variant, size: props.size, color: props.color, disabled: props.disabled, fullWidth: props.fullWidth, children: props.children }));
|
|
144
|
+
case 'TextInput':
|
|
145
|
+
return (_jsx(TextInput, { ...commonProps, placeholder: props.placeholder, label: props.label, size: props.size, disabled: props.disabled }));
|
|
146
|
+
case 'Text':
|
|
147
|
+
const computedFw = typeof props.weight === 'number' ? props.weight :
|
|
148
|
+
typeof props.fw === 'number' ? props.fw :
|
|
149
|
+
props.weight === 'bold' ? 700 :
|
|
150
|
+
props.weight === 'semibold' ? 600 :
|
|
151
|
+
props.weight === 'medium' ? 500 :
|
|
152
|
+
props.weight === 'normal' ? 400 :
|
|
153
|
+
props.weight === 'lighter' ? 300 :
|
|
154
|
+
props.fw || props.weight || 400;
|
|
155
|
+
// Debug log for Text components with "Premium" or "Sport" in content
|
|
156
|
+
if (props.children && typeof props.children === 'string' &&
|
|
157
|
+
(props.children.includes('Premium') || props.children.includes('Sport'))) {
|
|
158
|
+
console.log('📝 [Text Component Title]', {
|
|
159
|
+
content: props.children,
|
|
160
|
+
preserveOriginalLayout,
|
|
161
|
+
propsWeight: props.weight,
|
|
162
|
+
propsFw: props.fw,
|
|
163
|
+
computedFw,
|
|
164
|
+
size: props.size,
|
|
165
|
+
parentId,
|
|
166
|
+
componentId: component.id
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return (_jsx(Text, { ...commonProps, size: props.size, fw: computedFw, c: props.c || props.color || undefined, children: props.children }));
|
|
170
|
+
case 'Title':
|
|
171
|
+
console.log(`🗞 [Title] preserveOriginalLayout: ${preserveOriginalLayout}, props:`, props, 'fw calculated:', props.fw || props.weight || undefined);
|
|
172
|
+
return (_jsx(Title, { ...commonProps, order: Number(props.order), fw: props.fw || props.weight || undefined, c: props.color || undefined, children: props.children }));
|
|
173
|
+
case 'Container':
|
|
174
|
+
const containerRef = (node) => {
|
|
175
|
+
dropRef(node);
|
|
176
|
+
};
|
|
177
|
+
return (_jsxs(Container, { ...commonProps, size: props.size, fluid: props.fluid, ref: containerRef, style: {
|
|
178
|
+
...commonProps.style,
|
|
179
|
+
...(preserveOriginalLayout ? {} : {
|
|
180
|
+
minHeight: children?.length === 0 ? '100px' : 'auto',
|
|
181
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
182
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
183
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
184
|
+
borderRadius: '8px',
|
|
185
|
+
padding: '1rem',
|
|
186
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
187
|
+
})
|
|
188
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
189
|
+
case 'Group':
|
|
190
|
+
const groupRef = (node) => {
|
|
191
|
+
dropRef(node);
|
|
192
|
+
};
|
|
193
|
+
return (_jsxs(Group, { ...commonProps, justify: props.justify, align: props.align, gap: props.gap, ref: groupRef, style: {
|
|
194
|
+
...commonProps.style,
|
|
195
|
+
...(preserveOriginalLayout ? {} : {
|
|
196
|
+
minHeight: children?.length === 0 ? '80px' : 'auto',
|
|
197
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
198
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
199
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
200
|
+
borderRadius: '8px',
|
|
201
|
+
padding: '1rem',
|
|
202
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
203
|
+
})
|
|
204
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", children: "Drop components here" }))] }));
|
|
205
|
+
case 'Stack':
|
|
206
|
+
const stackRef = (node) => {
|
|
207
|
+
dropRef(node);
|
|
208
|
+
};
|
|
209
|
+
console.log(`📚 [Stack] preserveOriginalLayout: ${preserveOriginalLayout}, gap: ${props.gap}`);
|
|
210
|
+
// Stack styling - preserve original when needed
|
|
211
|
+
const stackStyle = preserveOriginalLayout ? {
|
|
212
|
+
...commonProps.style
|
|
213
|
+
// No additional styling that might interfere with original layout
|
|
214
|
+
} : {
|
|
215
|
+
...commonProps.style,
|
|
216
|
+
minHeight: children?.length === 0 ? '100px' : 'auto',
|
|
217
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
218
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
219
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
220
|
+
borderRadius: '8px',
|
|
221
|
+
padding: '1rem',
|
|
222
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
223
|
+
};
|
|
224
|
+
return (_jsxs(Stack, { ...commonProps, gap: props.gap, align: props.align, ref: stackRef, style: stackStyle, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
225
|
+
case 'Card':
|
|
226
|
+
const cardRef = (node) => {
|
|
227
|
+
dropRef(node);
|
|
228
|
+
};
|
|
229
|
+
// Use specific border properties to avoid conflicts
|
|
230
|
+
const cardStyles = {
|
|
231
|
+
...commonProps.style,
|
|
232
|
+
...(preserveOriginalLayout ? {} : { minHeight: children?.length === 0 ? '120px' : 'auto' })
|
|
233
|
+
};
|
|
234
|
+
// Only apply editor styling when not preserving original layout
|
|
235
|
+
if (!preserveOriginalLayout) {
|
|
236
|
+
// Only apply border styles when withBorder is false
|
|
237
|
+
if (!props.withBorder) {
|
|
238
|
+
if (isOver) {
|
|
239
|
+
cardStyles.borderWidth = '2px';
|
|
240
|
+
cardStyles.borderStyle = 'dashed';
|
|
241
|
+
cardStyles.borderColor = '#3b82f6';
|
|
242
|
+
}
|
|
243
|
+
else if (selected) {
|
|
244
|
+
cardStyles.borderWidth = '2px';
|
|
245
|
+
cardStyles.borderStyle = 'solid';
|
|
246
|
+
cardStyles.borderColor = '#3b82f6';
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
cardStyles.borderWidth = '1px';
|
|
250
|
+
cardStyles.borderStyle = 'dashed';
|
|
251
|
+
cardStyles.borderColor = '#e9ecef';
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else if (selected || isOver) {
|
|
255
|
+
// When withBorder is true, use outline for selection
|
|
256
|
+
if (isOver) {
|
|
257
|
+
cardStyles.outline = '2px dashed #3b82f6';
|
|
258
|
+
}
|
|
259
|
+
else if (selected) {
|
|
260
|
+
cardStyles.outline = '2px solid #3b82f6';
|
|
261
|
+
}
|
|
262
|
+
cardStyles.outlineOffset = '1px';
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return (_jsxs(Card, { ...commonProps, shadow: props.shadow, padding: props.padding, radius: props.radius, withBorder: props.withBorder, ref: cardRef, style: cardStyles, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
266
|
+
case 'CardSection':
|
|
267
|
+
const cardSectionRef = (node) => {
|
|
268
|
+
dropRef(node);
|
|
269
|
+
};
|
|
270
|
+
console.log(`🖼️ [CardSection] preserveOriginalLayout: ${preserveOriginalLayout}, inheritPadding: ${props.inheritPadding}`);
|
|
271
|
+
// Special styling for CardSection when preserving original layout
|
|
272
|
+
const cardSectionStyle = preserveOriginalLayout ? {
|
|
273
|
+
...commonProps.style,
|
|
274
|
+
// Remove any extra margins/padding that might be added
|
|
275
|
+
margin: 0,
|
|
276
|
+
padding: props.inheritPadding ? undefined : 0
|
|
277
|
+
} : {
|
|
278
|
+
...commonProps.style,
|
|
279
|
+
minHeight: children?.length === 0 ? '80px' : 'auto',
|
|
280
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
281
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
282
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
283
|
+
padding: props.inheritPadding ? undefined : '1rem',
|
|
284
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
285
|
+
};
|
|
286
|
+
// For CardSection, we need to be more selective about which props to pass
|
|
287
|
+
const cardSectionProps = preserveOriginalLayout ? {
|
|
288
|
+
onClick: commonProps.onClick,
|
|
289
|
+
style: cardSectionStyle,
|
|
290
|
+
// Only pass spacing props that are actually set
|
|
291
|
+
...Object.keys(spacingProps).reduce((acc, key) => {
|
|
292
|
+
if (spacingProps[key] !== undefined && spacingProps[key] !== null && spacingProps[key] !== '') {
|
|
293
|
+
acc[key] = spacingProps[key];
|
|
294
|
+
}
|
|
295
|
+
return acc;
|
|
296
|
+
}, {})
|
|
297
|
+
} : commonProps;
|
|
298
|
+
return (_jsxs(Card.Section, { ...cardSectionProps, withBorder: props.withBorder, inheritPadding: props.inheritPadding, ref: cardSectionRef, style: cardSectionStyle, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
299
|
+
case 'Badge':
|
|
300
|
+
return (_jsx(Badge, { ...commonProps, variant: props.variant, color: props.color, size: props.size, children: props.children }));
|
|
301
|
+
case 'Anchor':
|
|
302
|
+
return (_jsx(Anchor, { ...commonProps, href: props.href, size: props.size, underline: props.underline, children: props.children }));
|
|
303
|
+
case 'Image':
|
|
304
|
+
// Convert aspect ratio to style
|
|
305
|
+
const getAspectRatioStyle = (aspectRatio) => {
|
|
306
|
+
const ratios = {
|
|
307
|
+
'16:9': '16 / 9',
|
|
308
|
+
'4:3': '4 / 3',
|
|
309
|
+
'1:1': '1 / 1',
|
|
310
|
+
'3:2': '3 / 2',
|
|
311
|
+
'21:9': '21 / 9'
|
|
312
|
+
};
|
|
313
|
+
return ratios[aspectRatio] || '16 / 9';
|
|
314
|
+
};
|
|
315
|
+
// Extract height from props if it exists
|
|
316
|
+
const imageHeight = props.height || props.h;
|
|
317
|
+
const imageStyle = {
|
|
318
|
+
...commonProps.style,
|
|
319
|
+
width: '100%',
|
|
320
|
+
objectFit: (props.fit || 'cover')
|
|
321
|
+
};
|
|
322
|
+
// Apply aspect ratio only if no explicit height is set
|
|
323
|
+
if (!imageHeight && props.aspectRatio) {
|
|
324
|
+
imageStyle.aspectRatio = getAspectRatioStyle(props.aspectRatio);
|
|
325
|
+
}
|
|
326
|
+
return (_jsx(Image, { ...commonProps, src: props.src, alt: props.alt, radius: props.radius, height: imageHeight, style: imageStyle }));
|
|
327
|
+
case 'Divider':
|
|
328
|
+
return (_jsx(Divider, { ...commonProps, size: props.size, orientation: props.orientation, label: props.label || undefined, labelPosition: props.labelPosition }));
|
|
329
|
+
case 'Paper':
|
|
330
|
+
const paperRef = (node) => {
|
|
331
|
+
dropRef(node);
|
|
332
|
+
};
|
|
333
|
+
// Use specific border properties to avoid conflicts
|
|
334
|
+
const paperStyles = {
|
|
335
|
+
...commonProps.style,
|
|
336
|
+
...(preserveOriginalLayout ? {} : { minHeight: children?.length === 0 ? '100px' : 'auto' })
|
|
337
|
+
};
|
|
338
|
+
// Only apply editor styling when not preserving original layout
|
|
339
|
+
if (!preserveOriginalLayout && !props.withBorder) {
|
|
340
|
+
if (isOver) {
|
|
341
|
+
paperStyles.borderWidth = '2px';
|
|
342
|
+
paperStyles.borderStyle = 'dashed';
|
|
343
|
+
paperStyles.borderColor = '#3b82f6';
|
|
344
|
+
}
|
|
345
|
+
else if (selected) {
|
|
346
|
+
paperStyles.borderWidth = '2px';
|
|
347
|
+
paperStyles.borderStyle = 'solid';
|
|
348
|
+
paperStyles.borderColor = '#3b82f6';
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
paperStyles.borderWidth = '1px';
|
|
352
|
+
paperStyles.borderStyle = 'dashed';
|
|
353
|
+
paperStyles.borderColor = '#e9ecef';
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else if (!preserveOriginalLayout && (selected || isOver)) {
|
|
357
|
+
// When withBorder is true, use outline for selection
|
|
358
|
+
if (isOver) {
|
|
359
|
+
paperStyles.outline = '2px dashed #3b82f6';
|
|
360
|
+
}
|
|
361
|
+
else if (selected) {
|
|
362
|
+
paperStyles.outline = '2px solid #3b82f6';
|
|
363
|
+
}
|
|
364
|
+
paperStyles.outlineOffset = '1px';
|
|
365
|
+
}
|
|
366
|
+
return (_jsxs(Paper, { ...commonProps, shadow: props.shadow, radius: props.radius, p: props.p, withBorder: props.withBorder, ref: paperRef, style: paperStyles, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
367
|
+
case 'Alert':
|
|
368
|
+
return (_jsx(Alert, { ...commonProps, title: props.title, color: props.color, variant: props.variant, children: props.children }));
|
|
369
|
+
// Additional Input Components
|
|
370
|
+
case 'PasswordInput':
|
|
371
|
+
return (_jsx(PasswordInput, { ...commonProps, placeholder: props.placeholder, label: props.label, size: props.size, visible: props.visible, disabled: props.disabled }));
|
|
372
|
+
case 'Textarea':
|
|
373
|
+
return (_jsx(Textarea, { ...commonProps, placeholder: props.placeholder, label: props.label, size: props.size, rows: props.rows, autosize: props.autosize, disabled: props.disabled }));
|
|
374
|
+
case 'Select':
|
|
375
|
+
return (_jsx(Select, { ...commonProps, placeholder: props.placeholder, label: props.label, size: props.size, data: props.data || ['Option 1', 'Option 2', 'Option 3'], searchable: props.searchable, clearable: props.clearable, disabled: props.disabled }));
|
|
376
|
+
case 'MultiSelect':
|
|
377
|
+
return (_jsx(MultiSelect, { ...commonProps, placeholder: props.placeholder, label: props.label, size: props.size, data: props.data || ['Option 1', 'Option 2', 'Option 3'], searchable: props.searchable, clearable: props.clearable, disabled: props.disabled }));
|
|
378
|
+
case 'NumberInput':
|
|
379
|
+
return (_jsx(NumberInput, { ...commonProps, placeholder: props.placeholder, label: props.label, size: props.size, min: props.min, max: props.max, step: props.step, disabled: props.disabled }));
|
|
380
|
+
case 'Checkbox':
|
|
381
|
+
return (_jsx(Checkbox, { ...commonProps, label: props.label, size: props.size, color: props.color, indeterminate: props.indeterminate, disabled: props.disabled }));
|
|
382
|
+
case 'Radio':
|
|
383
|
+
return (_jsx(Radio, { ...commonProps, label: props.label, size: props.size, color: props.color, disabled: props.disabled }));
|
|
384
|
+
case 'Switch':
|
|
385
|
+
return (_jsx(Switch, { ...commonProps, label: props.label, size: props.size, color: props.color, disabled: props.disabled }));
|
|
386
|
+
// Layout Components
|
|
387
|
+
case 'Box':
|
|
388
|
+
const boxRef = (node) => {
|
|
389
|
+
dropRef(node);
|
|
390
|
+
};
|
|
391
|
+
return (_jsxs(Box, { ...commonProps, bg: props.bg, c: props.c, ref: boxRef, style: {
|
|
392
|
+
...commonProps.style,
|
|
393
|
+
...(preserveOriginalLayout ? {} : {
|
|
394
|
+
minHeight: children?.length === 0 ? '100px' : 'auto',
|
|
395
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
396
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
397
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
398
|
+
borderRadius: '8px',
|
|
399
|
+
padding: '1rem',
|
|
400
|
+
backgroundColor: isOver ? '#f0f9ff' : props.bg || 'transparent'
|
|
401
|
+
})
|
|
402
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
403
|
+
case 'Flex':
|
|
404
|
+
const flexRef = (node) => {
|
|
405
|
+
dropRef(node);
|
|
406
|
+
};
|
|
407
|
+
return (_jsxs(Flex, { ...commonProps, direction: props.direction, justify: props.justify, align: props.align, wrap: props.wrap, gap: props.gap, ref: flexRef, style: {
|
|
408
|
+
...commonProps.style,
|
|
409
|
+
...(preserveOriginalLayout ? {} : {
|
|
410
|
+
minHeight: children?.length === 0 ? '100px' : 'auto',
|
|
411
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
412
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
413
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
414
|
+
borderRadius: '8px',
|
|
415
|
+
padding: '1rem',
|
|
416
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
417
|
+
})
|
|
418
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
419
|
+
case 'Grid':
|
|
420
|
+
const gridRef = (node) => {
|
|
421
|
+
dropRef(node);
|
|
422
|
+
};
|
|
423
|
+
return (_jsxs(Grid, { ...commonProps, columns: props.columns, gutter: props.gutter, grow: props.grow, ref: gridRef, style: {
|
|
424
|
+
...commonProps.style,
|
|
425
|
+
...(preserveOriginalLayout ? {} : {
|
|
426
|
+
minHeight: children?.length === 0 ? '100px' : 'auto',
|
|
427
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
428
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
429
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
430
|
+
borderRadius: '8px',
|
|
431
|
+
padding: '1rem',
|
|
432
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
433
|
+
})
|
|
434
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop GridCol components here" }))] }));
|
|
435
|
+
case 'GridCol':
|
|
436
|
+
const gridColRef = (node) => {
|
|
437
|
+
dropRef(node);
|
|
438
|
+
};
|
|
439
|
+
return (_jsxs(GridCol, { ...commonProps, span: props.span, offset: props.offset, ref: gridColRef, style: {
|
|
440
|
+
...commonProps.style,
|
|
441
|
+
...(preserveOriginalLayout ? {} : {
|
|
442
|
+
minHeight: children?.length === 0 ? '80px' : 'auto',
|
|
443
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
444
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
445
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
446
|
+
borderRadius: '8px',
|
|
447
|
+
padding: '1rem',
|
|
448
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
449
|
+
})
|
|
450
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
451
|
+
case 'SimpleGrid':
|
|
452
|
+
const simpleGridRef = (node) => {
|
|
453
|
+
dropRef(node);
|
|
454
|
+
};
|
|
455
|
+
return (_jsxs(SimpleGrid, { ...commonProps, cols: props.cols, spacing: props.spacing, verticalSpacing: props.verticalSpacing, ref: simpleGridRef, style: {
|
|
456
|
+
...commonProps.style,
|
|
457
|
+
...(preserveOriginalLayout ? {} : {
|
|
458
|
+
minHeight: children?.length === 0 ? '100px' : 'auto',
|
|
459
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
460
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
461
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
462
|
+
borderRadius: '8px',
|
|
463
|
+
padding: '1rem',
|
|
464
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
465
|
+
})
|
|
466
|
+
}, children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id, preserveOriginalLayout: preserveOriginalLayout })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }));
|
|
467
|
+
// Typography Components
|
|
468
|
+
case 'Code':
|
|
469
|
+
return (_jsx(Code, { ...commonProps, color: props.color, block: props.block, children: props.children }));
|
|
470
|
+
case 'Mark':
|
|
471
|
+
return (_jsx(Mark, { ...commonProps, color: props.color, children: props.children }));
|
|
472
|
+
case 'Blockquote':
|
|
473
|
+
return (_jsx(Blockquote, { ...commonProps, cite: props.cite, color: props.color, children: props.children }));
|
|
474
|
+
// Display Components
|
|
475
|
+
case 'Avatar':
|
|
476
|
+
return (_jsx(Avatar, { ...commonProps, src: props.src, alt: props.alt, size: props.size, radius: props.radius, color: props.color }));
|
|
477
|
+
case 'Indicator':
|
|
478
|
+
return (_jsx(Indicator, { ...commonProps, label: props.label, size: props.size, color: props.color, position: props.position, children: _jsx(Box, { p: "md", bg: "gray.1", children: props.children }) }));
|
|
479
|
+
// Navigation Components
|
|
480
|
+
case 'Breadcrumbs':
|
|
481
|
+
return (_jsx(Breadcrumbs, { ...commonProps, separator: props.separator, children: (props.children || ['Home', 'Products', 'Current']).map((item, idx) => (_jsx(Anchor, { href: "#", children: item }, idx))) }));
|
|
482
|
+
case 'Tabs':
|
|
483
|
+
const tabsRef = (node) => {
|
|
484
|
+
dropRef(node);
|
|
485
|
+
};
|
|
486
|
+
return (_jsxs(Tabs, { ...commonProps, variant: props.variant, color: props.color, orientation: props.orientation, defaultValue: "tab1", ref: tabsRef, style: {
|
|
487
|
+
...commonProps.style,
|
|
488
|
+
...(preserveOriginalLayout ? {} : {
|
|
489
|
+
minHeight: children?.length === 0 ? '120px' : 'auto',
|
|
490
|
+
borderWidth: isOver || selected ? '2px' : '1px',
|
|
491
|
+
borderStyle: isOver || !selected ? 'dashed' : 'solid',
|
|
492
|
+
borderColor: isOver || selected ? '#3b82f6' : '#e9ecef',
|
|
493
|
+
borderRadius: '8px',
|
|
494
|
+
padding: '1rem',
|
|
495
|
+
backgroundColor: isOver ? '#f0f9ff' : 'transparent'
|
|
496
|
+
})
|
|
497
|
+
}, children: [_jsxs(Tabs.List, { children: [_jsx(Tabs.Tab, { value: "tab1", children: "Tab 1" }), _jsx(Tabs.Tab, { value: "tab2", children: "Tab 2" })] }), _jsxs(Tabs.Panel, { value: "tab1", children: [children?.map((child, idx) => (_jsxs(React.Fragment, { children: [_jsx(DropZone, { parentId: component.id, insertIndex: idx, isVisible: showDropZones && isContainer }), _jsx(ComponentRenderer, { component: child, index: idx, isChild: true, parentId: component.id })] }, child.id))), showDropZones && isContainer && (_jsx(DropZone, { parentId: component.id, insertIndex: children?.length || 0, isVisible: true })), children?.length === 0 && (_jsx(Text, { c: "dimmed", ta: "center", children: "Drop components here" }))] }), _jsx(Tabs.Panel, { value: "tab2", children: _jsx(Text, { children: "Tab 2 content" }) })] }));
|
|
498
|
+
// Feedback Components
|
|
499
|
+
case 'Loader':
|
|
500
|
+
return (_jsx(Loader, { ...commonProps, size: props.size, color: props.color, variant: props.variant }));
|
|
501
|
+
case 'Progress':
|
|
502
|
+
return (_jsx(Progress, { ...commonProps, value: props.value, size: props.size, color: props.color, radius: props.radius, striped: props.striped, animated: props.animated }));
|
|
503
|
+
case 'RingProgress':
|
|
504
|
+
return (_jsx(RingProgress, { ...commonProps, size: props.size, thickness: props.thickness, sections: props.sections || [{ value: 40, color: 'blue' }], label: props.label && _jsx(Text, { ta: "center", size: "xs", children: props.label }) }));
|
|
505
|
+
// Overlay Components
|
|
506
|
+
case 'Tooltip':
|
|
507
|
+
return (_jsx(Tooltip, { label: props.label, position: props.position, color: props.color, children: _jsx(Box, { ...commonProps, children: props.children }) }));
|
|
508
|
+
case 'Popover':
|
|
509
|
+
return (_jsxs(Popover, { position: props.position, width: props.width, shadow: props.shadow, children: [_jsx(Popover.Target, { children: _jsx(Button, { ...commonProps, children: props.children }) }), _jsx(Popover.Dropdown, { children: _jsx(Text, { size: "sm", children: "Popover content" }) })] }));
|
|
510
|
+
default:
|
|
511
|
+
return (_jsxs(Box, { ...commonProps, children: ["Unknown component: ", type] }));
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
// DEBUG: Wrapper styling decision
|
|
515
|
+
console.log(`🔵 [Wrapper] ${component.type} - preserveOriginalLayout: ${preserveOriginalLayout}, selected: ${selected}, isContainer: ${isContainer}`);
|
|
516
|
+
// Hover state management
|
|
517
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
518
|
+
// When preserving original layout, use minimal wrapper styling with hover/selection indicators
|
|
519
|
+
const wrapperStyle = preserveOriginalLayout ? {
|
|
520
|
+
...style,
|
|
521
|
+
position: 'relative',
|
|
522
|
+
// Use box-shadow instead of outline for selection/hover - doesn't affect layout
|
|
523
|
+
boxShadow: selected ? 'inset 0 0 0 2px #3b82f6' :
|
|
524
|
+
isHovered ? 'inset 0 0 0 2px rgba(59, 130, 246, 0.3)' : 'none',
|
|
525
|
+
// Subtle background for hover - very light tint
|
|
526
|
+
backgroundColor: isHovered && !selected ? 'rgba(59, 130, 246, 0.02)' : 'transparent',
|
|
527
|
+
// Smooth transitions
|
|
528
|
+
transition: 'box-shadow 0.2s ease, background-color 0.2s ease',
|
|
529
|
+
// Keep borders at exactly 0 to not affect layout
|
|
530
|
+
borderWidth: 0,
|
|
531
|
+
borderStyle: 'none',
|
|
532
|
+
padding: 0,
|
|
533
|
+
margin: 0
|
|
534
|
+
} : {
|
|
535
|
+
...style,
|
|
536
|
+
borderWidth: selected && !isContainer ? '2px' : '0',
|
|
537
|
+
borderStyle: selected && !isContainer ? 'solid' : 'none',
|
|
538
|
+
borderColor: selected && !isContainer ? '#3b82f6' : 'transparent',
|
|
539
|
+
borderRadius: selected ? '4px' : '0',
|
|
540
|
+
padding: selected && !isContainer ? '2px' : '0',
|
|
541
|
+
outline: 'none',
|
|
542
|
+
position: 'relative'
|
|
543
|
+
};
|
|
544
|
+
return (_jsx(Box, { ref: dragRef, style: wrapperStyle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), ...attributes, ...listeners, children: renderComponent() }));
|
|
545
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Modal, Button, Group, Code, ScrollArea, Text, Box } from '@mantine/core';
|
|
3
|
+
import { useVisualBuilderStore } from '../../store/visualBuilderStore';
|
|
4
|
+
import { generateJSXCode } from './codeGenerator';
|
|
5
|
+
export const CodeExporter = () => {
|
|
6
|
+
const { isCodeModalOpen, closeCodeModal, components } = useVisualBuilderStore();
|
|
7
|
+
const jsxCode = generateJSXCode(components);
|
|
8
|
+
const handleCopyCode = async () => {
|
|
9
|
+
try {
|
|
10
|
+
await navigator.clipboard.writeText(jsxCode);
|
|
11
|
+
// You could add a notification here
|
|
12
|
+
console.log('Code copied to clipboard');
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error('Failed to copy code:', err);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
return (_jsx(Modal, { opened: isCodeModalOpen, onClose: closeCodeModal, title: "Export React Code", size: "xl", children: _jsxs(Box, { children: [_jsxs(Group, { justify: "space-between", mb: "md", children: [_jsx(Text, { size: "sm", c: "dimmed", children: "Generated React/JSX code for your components" }), _jsx(Button, { size: "xs", onClick: handleCopyCode, children: "Copy Code" })] }), _jsx(ScrollArea, { h: 400, children: _jsx(Code, { block: true, style: {
|
|
19
|
+
fontSize: '12px',
|
|
20
|
+
whiteSpace: 'pre-wrap',
|
|
21
|
+
backgroundColor: '#f8f9fa',
|
|
22
|
+
padding: '1rem',
|
|
23
|
+
borderRadius: '6px'
|
|
24
|
+
}, children: jsxCode }) }), _jsx(Group, { justify: "flex-end", mt: "md", children: _jsx(Button, { variant: "outline", onClick: closeCodeModal, children: "Close" }) })] }) }));
|
|
25
|
+
};
|