@tpitre/story-ui 3.4.0 → 3.4.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.
Files changed (282) hide show
  1. package/dist/cli/index.js +0 -0
  2. package/dist/mcp-server/index.js +32 -0
  3. package/package.json +2 -1
  4. package/dist/cli/index.js.map +0 -1
  5. package/dist/cli/setup.js.map +0 -1
  6. package/dist/cloudflare-edge/src/mcp-session.js +0 -462
  7. package/dist/cloudflare-edge/src/types.js +0 -4
  8. package/dist/cloudflare-edge/src/worker.js +0 -106
  9. package/dist/cloudflare-pages/vite.config.js +0 -14
  10. package/dist/index.d.ts +0 -13
  11. package/dist/index.d.ts.map +0 -1
  12. package/dist/index.js +0 -12
  13. package/dist/index.js.map +0 -1
  14. package/dist/mcp-server/index.js.map +0 -1
  15. package/dist/mcp-server/mcp-stdio-server.js.map +0 -1
  16. package/dist/mcp-server/routes/claude.js.map +0 -1
  17. package/dist/mcp-server/routes/components.js.map +0 -1
  18. package/dist/mcp-server/routes/generateStory.js.map +0 -1
  19. package/dist/mcp-server/routes/hybridStories.d.ts +0 -18
  20. package/dist/mcp-server/routes/hybridStories.d.ts.map +0 -1
  21. package/dist/mcp-server/routes/hybridStories.js +0 -216
  22. package/dist/mcp-server/routes/hybridStories.js.map +0 -1
  23. package/dist/mcp-server/routes/memoryStories.d.ts +0 -26
  24. package/dist/mcp-server/routes/memoryStories.d.ts.map +0 -1
  25. package/dist/mcp-server/routes/memoryStories.js +0 -158
  26. package/dist/mcp-server/routes/memoryStories.js.map +0 -1
  27. package/dist/mcp-server/routes/storySync.d.ts +0 -26
  28. package/dist/mcp-server/routes/storySync.d.ts.map +0 -1
  29. package/dist/mcp-server/routes/storySync.js +0 -147
  30. package/dist/mcp-server/routes/storySync.js.map +0 -1
  31. package/dist/mcp-server/routes/updateStory.js +0 -246
  32. package/dist/mcp-server/sessionManager.d.ts +0 -50
  33. package/dist/mcp-server/sessionManager.d.ts.map +0 -1
  34. package/dist/mcp-server/sessionManager.js +0 -125
  35. package/dist/mcp-server/sessionManager.js.map +0 -1
  36. package/dist/playground/components/AIAssistant/AIAssistant.d.ts +0 -6
  37. package/dist/playground/components/AIAssistant/AIAssistant.d.ts.map +0 -1
  38. package/dist/playground/components/AIAssistant/AIAssistant.js +0 -109
  39. package/dist/playground/components/AIAssistant/AIAssistant.js.map +0 -1
  40. package/dist/playground/components/AIAssistant/AIAssistant.module.css +0 -166
  41. package/dist/playground/components/Canvas/Canvas.d.ts +0 -9
  42. package/dist/playground/components/Canvas/Canvas.d.ts.map +0 -1
  43. package/dist/playground/components/Canvas/Canvas.js +0 -58
  44. package/dist/playground/components/Canvas/Canvas.js.map +0 -1
  45. package/dist/playground/components/Canvas/Canvas.module.css +0 -189
  46. package/dist/playground/components/Canvas/CanvasWithDnd.d.ts +0 -9
  47. package/dist/playground/components/Canvas/CanvasWithDnd.d.ts.map +0 -1
  48. package/dist/playground/components/Canvas/CanvasWithDnd.js +0 -158
  49. package/dist/playground/components/Canvas/CanvasWithDnd.js.map +0 -1
  50. package/dist/playground/components/Canvas/ComponentRenderer.d.ts +0 -15
  51. package/dist/playground/components/Canvas/ComponentRenderer.d.ts.map +0 -1
  52. package/dist/playground/components/Canvas/ComponentRenderer.js +0 -177
  53. package/dist/playground/components/Canvas/ComponentRenderer.js.map +0 -1
  54. package/dist/playground/components/Canvas/DraggableComponent.d.ts +0 -15
  55. package/dist/playground/components/Canvas/DraggableComponent.d.ts.map +0 -1
  56. package/dist/playground/components/Canvas/DraggableComponent.js +0 -49
  57. package/dist/playground/components/Canvas/DraggableComponent.js.map +0 -1
  58. package/dist/playground/components/Canvas/index.d.ts +0 -9
  59. package/dist/playground/components/Canvas/index.d.ts.map +0 -1
  60. package/dist/playground/components/Canvas/index.js +0 -5
  61. package/dist/playground/components/Canvas/index.js.map +0 -1
  62. package/dist/playground/components/CodeView/CodeView.d.ts +0 -12
  63. package/dist/playground/components/CodeView/CodeView.d.ts.map +0 -1
  64. package/dist/playground/components/CodeView/CodeView.js +0 -77
  65. package/dist/playground/components/CodeView/CodeView.js.map +0 -1
  66. package/dist/playground/components/CodeView/CodeView.module.css +0 -178
  67. package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts +0 -17
  68. package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts.map +0 -1
  69. package/dist/playground/components/ComponentPalette/ComponentPalette.js +0 -138
  70. package/dist/playground/components/ComponentPalette/ComponentPalette.js.map +0 -1
  71. package/dist/playground/components/ComponentPalette/ComponentPalette.module.css +0 -217
  72. package/dist/playground/components/ComponentPalette/index.d.ts +0 -3
  73. package/dist/playground/components/ComponentPalette/index.d.ts.map +0 -1
  74. package/dist/playground/components/ComponentPalette/index.js +0 -2
  75. package/dist/playground/components/ComponentPalette/index.js.map +0 -1
  76. package/dist/playground/components/DropZone/DropZone.d.ts +0 -17
  77. package/dist/playground/components/DropZone/DropZone.d.ts.map +0 -1
  78. package/dist/playground/components/DropZone/DropZone.js +0 -73
  79. package/dist/playground/components/DropZone/DropZone.js.map +0 -1
  80. package/dist/playground/components/DropZone/DropZone.module.css +0 -86
  81. package/dist/playground/components/ExportDialog/ExportDialog.d.ts +0 -10
  82. package/dist/playground/components/ExportDialog/ExportDialog.d.ts.map +0 -1
  83. package/dist/playground/components/ExportDialog/ExportDialog.js +0 -57
  84. package/dist/playground/components/ExportDialog/ExportDialog.js.map +0 -1
  85. package/dist/playground/components/ExportDialog/ExportDialog.module.css +0 -328
  86. package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts +0 -134
  87. package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts.map +0 -1
  88. package/dist/playground/components/LayoutHelpers/LayoutHelpers.js +0 -254
  89. package/dist/playground/components/LayoutHelpers/LayoutHelpers.js.map +0 -1
  90. package/dist/playground/components/LayoutHelpers/index.d.ts +0 -3
  91. package/dist/playground/components/LayoutHelpers/index.d.ts.map +0 -1
  92. package/dist/playground/components/LayoutHelpers/index.js +0 -2
  93. package/dist/playground/components/LayoutHelpers/index.js.map +0 -1
  94. package/dist/playground/components/Playground/Playground.d.ts +0 -10
  95. package/dist/playground/components/Playground/Playground.d.ts.map +0 -1
  96. package/dist/playground/components/Playground/Playground.js +0 -128
  97. package/dist/playground/components/Playground/Playground.js.map +0 -1
  98. package/dist/playground/components/Playground/Playground.module.css +0 -308
  99. package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts +0 -10
  100. package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts.map +0 -1
  101. package/dist/playground/components/PropertiesPanel/PropertiesPanel.js +0 -150
  102. package/dist/playground/components/PropertiesPanel/PropertiesPanel.js.map +0 -1
  103. package/dist/playground/components/PropertiesPanel/PropertiesPanel.module.css +0 -155
  104. package/dist/playground/components/PropertiesPanel/index.d.ts +0 -3
  105. package/dist/playground/components/PropertiesPanel/index.d.ts.map +0 -1
  106. package/dist/playground/components/PropertiesPanel/index.js +0 -2
  107. package/dist/playground/components/PropertiesPanel/index.js.map +0 -1
  108. package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts +0 -12
  109. package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts.map +0 -1
  110. package/dist/playground/components/PropertyEditors/BooleanEditor.js +0 -14
  111. package/dist/playground/components/PropertyEditors/BooleanEditor.js.map +0 -1
  112. package/dist/playground/components/PropertyEditors/ColorEditor.d.ts +0 -12
  113. package/dist/playground/components/PropertyEditors/ColorEditor.d.ts.map +0 -1
  114. package/dist/playground/components/PropertyEditors/ColorEditor.js +0 -62
  115. package/dist/playground/components/PropertyEditors/ColorEditor.js.map +0 -1
  116. package/dist/playground/components/PropertyEditors/IconEditor.d.ts +0 -12
  117. package/dist/playground/components/PropertyEditors/IconEditor.d.ts.map +0 -1
  118. package/dist/playground/components/PropertyEditors/IconEditor.js +0 -123
  119. package/dist/playground/components/PropertyEditors/IconEditor.js.map +0 -1
  120. package/dist/playground/components/PropertyEditors/NumberEditor.d.ts +0 -15
  121. package/dist/playground/components/PropertyEditors/NumberEditor.d.ts.map +0 -1
  122. package/dist/playground/components/PropertyEditors/NumberEditor.js +0 -46
  123. package/dist/playground/components/PropertyEditors/NumberEditor.js.map +0 -1
  124. package/dist/playground/components/PropertyEditors/PropertyEditors.module.css +0 -432
  125. package/dist/playground/components/PropertyEditors/SelectEditor.d.ts +0 -19
  126. package/dist/playground/components/PropertyEditors/SelectEditor.d.ts.map +0 -1
  127. package/dist/playground/components/PropertyEditors/SelectEditor.js +0 -17
  128. package/dist/playground/components/PropertyEditors/SelectEditor.js.map +0 -1
  129. package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts +0 -19
  130. package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts.map +0 -1
  131. package/dist/playground/components/PropertyEditors/SpacingEditor.js +0 -162
  132. package/dist/playground/components/PropertyEditors/SpacingEditor.js.map +0 -1
  133. package/dist/playground/components/PropertyEditors/SpacingEditor.module.css +0 -214
  134. package/dist/playground/components/PropertyEditors/TextEditor.d.ts +0 -14
  135. package/dist/playground/components/PropertyEditors/TextEditor.d.ts.map +0 -1
  136. package/dist/playground/components/PropertyEditors/TextEditor.js +0 -38
  137. package/dist/playground/components/PropertyEditors/TextEditor.js.map +0 -1
  138. package/dist/playground/components/PropertyEditors/TokenEditor.d.ts +0 -23
  139. package/dist/playground/components/PropertyEditors/TokenEditor.d.ts.map +0 -1
  140. package/dist/playground/components/PropertyEditors/TokenEditor.js +0 -50
  141. package/dist/playground/components/PropertyEditors/TokenEditor.js.map +0 -1
  142. package/dist/playground/components/PropertyEditors/index.d.ts +0 -20
  143. package/dist/playground/components/PropertyEditors/index.d.ts.map +0 -1
  144. package/dist/playground/components/PropertyEditors/index.js +0 -12
  145. package/dist/playground/components/PropertyEditors/index.js.map +0 -1
  146. package/dist/playground/components/TreeView/TreeView.d.ts +0 -10
  147. package/dist/playground/components/TreeView/TreeView.d.ts.map +0 -1
  148. package/dist/playground/components/TreeView/TreeView.js +0 -146
  149. package/dist/playground/components/TreeView/TreeView.js.map +0 -1
  150. package/dist/playground/components/TreeView/TreeView.module.css +0 -214
  151. package/dist/playground/components/TreeView/index.d.ts +0 -3
  152. package/dist/playground/components/TreeView/index.d.ts.map +0 -1
  153. package/dist/playground/components/TreeView/index.js +0 -2
  154. package/dist/playground/components/TreeView/index.js.map +0 -1
  155. package/dist/playground/config/propertyDefinitions.d.ts +0 -73
  156. package/dist/playground/config/propertyDefinitions.d.ts.map +0 -1
  157. package/dist/playground/config/propertyDefinitions.js +0 -809
  158. package/dist/playground/config/propertyDefinitions.js.map +0 -1
  159. package/dist/playground/hooks/useKeyboardShortcuts.d.ts +0 -38
  160. package/dist/playground/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  161. package/dist/playground/hooks/useKeyboardShortcuts.js +0 -191
  162. package/dist/playground/hooks/useKeyboardShortcuts.js.map +0 -1
  163. package/dist/playground/index.d.ts +0 -21
  164. package/dist/playground/index.d.ts.map +0 -1
  165. package/dist/playground/index.js +0 -23
  166. package/dist/playground/index.js.map +0 -1
  167. package/dist/playground/services/CodeGenerator.d.ts +0 -73
  168. package/dist/playground/services/CodeGenerator.d.ts.map +0 -1
  169. package/dist/playground/services/CodeGenerator.js +0 -359
  170. package/dist/playground/services/CodeGenerator.js.map +0 -1
  171. package/dist/playground/services/DragDropManager.d.ts +0 -95
  172. package/dist/playground/services/DragDropManager.d.ts.map +0 -1
  173. package/dist/playground/services/DragDropManager.js +0 -408
  174. package/dist/playground/services/DragDropManager.js.map +0 -1
  175. package/dist/playground/services/StoryParser.d.ts +0 -73
  176. package/dist/playground/services/StoryParser.d.ts.map +0 -1
  177. package/dist/playground/services/StoryParser.js +0 -419
  178. package/dist/playground/services/StoryParser.js.map +0 -1
  179. package/dist/playground/store/playgroundStore.d.ts +0 -86
  180. package/dist/playground/store/playgroundStore.d.ts.map +0 -1
  181. package/dist/playground/store/playgroundStore.js +0 -337
  182. package/dist/playground/store/playgroundStore.js.map +0 -1
  183. package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts +0 -13
  184. package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts.map +0 -1
  185. package/dist/playground/stories/PlaygroundDragDrop.stories.js +0 -227
  186. package/dist/playground/stories/PlaygroundDragDrop.stories.js.map +0 -1
  187. package/dist/playground/stories/PlaygroundPhase4.stories.d.ts +0 -13
  188. package/dist/playground/stories/PlaygroundPhase4.stories.d.ts.map +0 -1
  189. package/dist/playground/stories/PlaygroundPhase4.stories.js +0 -334
  190. package/dist/playground/stories/PlaygroundPhase4.stories.js.map +0 -1
  191. package/dist/playground/stories/PlaygroundPhase5.stories.d.ts +0 -14
  192. package/dist/playground/stories/PlaygroundPhase5.stories.d.ts.map +0 -1
  193. package/dist/playground/stories/PlaygroundPhase5.stories.js +0 -512
  194. package/dist/playground/stories/PlaygroundPhase5.stories.js.map +0 -1
  195. package/dist/playground/stories/PlaygroundProperties.stories.d.ts +0 -13
  196. package/dist/playground/stories/PlaygroundProperties.stories.d.ts.map +0 -1
  197. package/dist/playground/stories/PlaygroundProperties.stories.js +0 -342
  198. package/dist/playground/stories/PlaygroundProperties.stories.js.map +0 -1
  199. package/dist/playground/types/index.d.ts +0 -251
  200. package/dist/playground/types/index.d.ts.map +0 -1
  201. package/dist/playground/types/index.js +0 -5
  202. package/dist/playground/types/index.js.map +0 -1
  203. package/dist/scripts/verify-framework-adapters.js +0 -105
  204. package/dist/story-generator/componentBlacklist.js.map +0 -1
  205. package/dist/story-generator/componentDiscovery.js.map +0 -1
  206. package/dist/story-generator/configLoader.js.map +0 -1
  207. package/dist/story-generator/considerationsLoader.js.map +0 -1
  208. package/dist/story-generator/documentation-sources.js.map +0 -1
  209. package/dist/story-generator/documentationLoader.js.map +0 -1
  210. package/dist/story-generator/dynamicPackageDiscovery.js.map +0 -1
  211. package/dist/story-generator/enhancedComponentDiscovery.js.map +0 -1
  212. package/dist/story-generator/generateStory.js.map +0 -1
  213. package/dist/story-generator/gitignoreManager.js.map +0 -1
  214. package/dist/story-generator/inMemoryStoryService.d.ts +0 -89
  215. package/dist/story-generator/inMemoryStoryService.d.ts.map +0 -1
  216. package/dist/story-generator/inMemoryStoryService.js +0 -128
  217. package/dist/story-generator/inMemoryStoryService.js.map +0 -1
  218. package/dist/story-generator/logger.js.map +0 -1
  219. package/dist/story-generator/postProcessStory.js.map +0 -1
  220. package/dist/story-generator/postgresStoryService.d.ts +0 -56
  221. package/dist/story-generator/postgresStoryService.d.ts.map +0 -1
  222. package/dist/story-generator/postgresStoryService.js +0 -240
  223. package/dist/story-generator/productionGitignoreManager.d.ts +0 -91
  224. package/dist/story-generator/productionGitignoreManager.d.ts.map +0 -1
  225. package/dist/story-generator/productionGitignoreManager.js +0 -340
  226. package/dist/story-generator/productionGitignoreManager.js.map +0 -1
  227. package/dist/story-generator/promptGenerator.js.map +0 -1
  228. package/dist/story-generator/providerPresets.d.ts +0 -54
  229. package/dist/story-generator/providerPresets.d.ts.map +0 -1
  230. package/dist/story-generator/providerPresets.js +0 -214
  231. package/dist/story-generator/storyHistory.js.map +0 -1
  232. package/dist/story-generator/storyServiceFactory.d.ts +0 -22
  233. package/dist/story-generator/storyServiceFactory.d.ts.map +0 -1
  234. package/dist/story-generator/storyServiceFactory.js +0 -97
  235. package/dist/story-generator/storyServiceInterface.d.ts +0 -85
  236. package/dist/story-generator/storyServiceInterface.d.ts.map +0 -1
  237. package/dist/story-generator/storyServiceInterface.js +0 -5
  238. package/dist/story-generator/storySync.d.ts +0 -68
  239. package/dist/story-generator/storySync.d.ts.map +0 -1
  240. package/dist/story-generator/storySync.js +0 -201
  241. package/dist/story-generator/storySync.js.map +0 -1
  242. package/dist/story-generator/storyTracker.js.map +0 -1
  243. package/dist/story-generator/storyValidator.js.map +0 -1
  244. package/dist/story-generator/test_validation.d.ts +0 -2
  245. package/dist/story-generator/test_validation.d.ts.map +0 -1
  246. package/dist/story-generator/test_validation.js +0 -51
  247. package/dist/story-generator/universalDesignSystemAdapter.js.map +0 -1
  248. package/dist/story-generator/urlRedirectService.js.map +0 -1
  249. package/dist/story-generator/validateStory.js.map +0 -1
  250. package/dist/story-ui.config.js.map +0 -1
  251. package/dist/story-ui.config.loader.d.ts +0 -36
  252. package/dist/story-ui.config.loader.d.ts.map +0 -1
  253. package/dist/story-ui.config.loader.js +0 -205
  254. package/dist/story-ui.config.loader.js.map +0 -1
  255. package/dist/temp/package/templates/StoryUI/StoryUIPanel.js +0 -807
  256. package/dist/temp/package/templates/StoryUI/StoryUIPanel.stories.js +0 -37
  257. package/dist/temp/package/templates/StoryUI/index.js +0 -2
  258. package/dist/templates/StoryUI/StoryUIPanel.js.map +0 -1
  259. package/dist/templates/StoryUI/StoryUIPanel.stories.js.map +0 -1
  260. package/dist/templates/StoryUI/index.js.map +0 -1
  261. package/dist/templates/StoryUI/manager.d.ts +0 -14
  262. package/dist/templates/StoryUI/manager.d.ts.map +0 -1
  263. package/dist/templates/production-app/src/App.d.ts +0 -10
  264. package/dist/templates/production-app/src/App.d.ts.map +0 -1
  265. package/dist/templates/production-app/src/App.js +0 -653
  266. package/dist/templates/production-app/src/LivePreviewRenderer.d.ts +0 -24
  267. package/dist/templates/production-app/src/LivePreviewRenderer.d.ts.map +0 -1
  268. package/dist/templates/production-app/src/LivePreviewRenderer.js +0 -199
  269. package/dist/templates/production-app/src/componentRegistry.d.ts +0 -20
  270. package/dist/templates/production-app/src/componentRegistry.d.ts.map +0 -1
  271. package/dist/templates/production-app/src/componentRegistry.js +0 -316
  272. package/dist/templates/production-app/src/main.d.ts +0 -9
  273. package/dist/templates/production-app/src/main.d.ts.map +0 -1
  274. package/dist/templates/production-app/src/main.js +0 -18
  275. package/dist/templates/production-app/vite.config.d.ts +0 -3
  276. package/dist/templates/production-app/vite.config.d.ts.map +0 -1
  277. package/dist/templates/production-app/vite.config.js +0 -71
  278. package/dist/test-storybooks/angular-material-storybook/src/main.js +0 -66
  279. package/dist/test-storybooks/chakra-storybook/vite.config.js +0 -6
  280. package/dist/test-storybooks/mantine-storybook/vite.config.js +0 -93
  281. package/dist/test-storybooks/web-components-shoelace/vite.config.js +0 -9
  282. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,653 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Story UI Production App
4
- *
5
- * A Lovable/Bolt-style interface for generating UI components
6
- * using AI and a user's component library.
7
- */
8
- import { useState, useEffect, useRef, useCallback } from 'react';
9
- import { LivePreviewRenderer } from './LivePreviewRenderer';
10
- import { availableComponents } from './componentRegistry';
11
- // ============================================================================
12
- // CONSTANTS & CONFIG
13
- // ============================================================================
14
- const getServerUrl = () => {
15
- if (import.meta.env.VITE_STORY_UI_SERVER) {
16
- return import.meta.env.VITE_STORY_UI_SERVER;
17
- }
18
- return window.location.origin;
19
- };
20
- const SERVER_URL = getServerUrl();
21
- const THEME = {
22
- bg: '#09090b',
23
- bgSurface: '#18181b',
24
- bgElevated: '#27272a',
25
- bgHover: '#3f3f46',
26
- border: '#27272a',
27
- borderSubtle: '#3f3f46',
28
- text: '#fafafa',
29
- textMuted: '#a1a1aa',
30
- textSubtle: '#71717a',
31
- accent: '#3b82f6',
32
- accentHover: '#2563eb',
33
- accentMuted: 'rgba(59, 130, 246, 0.15)',
34
- success: '#22c55e',
35
- error: '#ef4444',
36
- warning: '#f59e0b',
37
- };
38
- const generateId = () => Math.random().toString(36).substring(2, 15);
39
- // ============================================================================
40
- // HOOKS
41
- // ============================================================================
42
- const useLocalStorage = (key, initialValue) => {
43
- const [storedValue, setStoredValue] = useState(() => {
44
- try {
45
- const item = window.localStorage.getItem(key);
46
- return item ? JSON.parse(item) : initialValue;
47
- }
48
- catch {
49
- return initialValue;
50
- }
51
- });
52
- const setValue = (value) => {
53
- const valueToStore = value instanceof Function ? value(storedValue) : value;
54
- setStoredValue(valueToStore);
55
- window.localStorage.setItem(key, JSON.stringify(valueToStore));
56
- };
57
- return [storedValue, setValue];
58
- };
59
- const useResizable = (initialWidth, minWidth, maxWidth) => {
60
- const [width, setWidth] = useState(initialWidth);
61
- const isDragging = useRef(false);
62
- const startX = useRef(0);
63
- const startWidth = useRef(0);
64
- const startResize = useCallback((e) => {
65
- isDragging.current = true;
66
- startX.current = e.clientX;
67
- startWidth.current = width;
68
- document.body.style.cursor = 'col-resize';
69
- document.body.style.userSelect = 'none';
70
- }, [width]);
71
- useEffect(() => {
72
- const handleMouseMove = (e) => {
73
- if (!isDragging.current)
74
- return;
75
- const delta = e.clientX - startX.current;
76
- const newWidth = Math.min(Math.max(startWidth.current + delta, minWidth), maxWidth);
77
- setWidth(newWidth);
78
- };
79
- const handleMouseUp = () => {
80
- isDragging.current = false;
81
- document.body.style.cursor = '';
82
- document.body.style.userSelect = '';
83
- };
84
- document.addEventListener('mousemove', handleMouseMove);
85
- document.addEventListener('mouseup', handleMouseUp);
86
- return () => {
87
- document.removeEventListener('mousemove', handleMouseMove);
88
- document.removeEventListener('mouseup', handleMouseUp);
89
- };
90
- }, [minWidth, maxWidth]);
91
- return { width, startResize };
92
- };
93
- // ============================================================================
94
- // ICON COMPONENTS
95
- // ============================================================================
96
- const Icons = {
97
- Plus: () => (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M8 3v10M3 8h10" }) })),
98
- Trash: () => (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: _jsx("path", { d: "M3 4h10M6 4V3a1 1 0 011-1h2a1 1 0 011 1v1M5 4v9a1 1 0 001 1h4a1 1 0 001-1V4" }) })),
99
- Send: () => (_jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" }) })),
100
- Image: () => (_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }), _jsx("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), _jsx("path", { d: "M21 15l-5-5L5 21" })] })),
101
- Code: () => (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M16 18l6-6-6-6M8 6l-6 6 6 6" }) })),
102
- Eye: () => (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }), _jsx("circle", { cx: "12", cy: "12", r: "3" })] })),
103
- Copy: () => (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }), _jsx("path", { d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" })] })),
104
- Sidebar: () => (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }), _jsx("path", { d: "M9 3v18" })] })),
105
- Check: () => (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M20 6L9 17l-5-5" }) })),
106
- X: () => (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })),
107
- };
108
- // ============================================================================
109
- // SUB-COMPONENTS
110
- // ============================================================================
111
- const LoadingDots = () => (_jsx("div", { style: { display: 'flex', gap: '4px', alignItems: 'center' }, children: [0, 1, 2].map(i => (_jsx("div", { style: {
112
- width: '6px',
113
- height: '6px',
114
- borderRadius: '50%',
115
- background: THEME.accent,
116
- animation: `pulse 1.4s ease-in-out ${i * 0.2}s infinite`,
117
- } }, i))) }));
118
- const ImageUploadArea = ({ images, onImagesChange, disabled }) => {
119
- const fileInputRef = useRef(null);
120
- const handleFiles = useCallback((files) => {
121
- Array.from(files).forEach(file => {
122
- if (file.type.startsWith('image/')) {
123
- const reader = new FileReader();
124
- reader.onload = (e) => {
125
- const newImage = {
126
- id: generateId(),
127
- data: e.target?.result,
128
- type: file.type,
129
- name: file.name,
130
- };
131
- onImagesChange([...images, newImage]);
132
- };
133
- reader.readAsDataURL(file);
134
- }
135
- });
136
- }, [images, onImagesChange]);
137
- const removeImage = (id) => {
138
- onImagesChange(images.filter(img => img.id !== id));
139
- };
140
- return (_jsxs("div", { style: { marginBottom: images.length > 0 ? '12px' : 0 }, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", multiple: true, style: { display: 'none' }, onChange: (e) => e.target.files && handleFiles(e.target.files), disabled: disabled }), images.length > 0 && (_jsx("div", { style: { display: 'flex', gap: '8px', flexWrap: 'wrap', marginBottom: '8px' }, children: images.map(img => (_jsxs("div", { style: {
141
- position: 'relative',
142
- width: '64px',
143
- height: '64px',
144
- borderRadius: '8px',
145
- overflow: 'hidden',
146
- border: `1px solid ${THEME.border}`,
147
- }, children: [_jsx("img", { src: img.data, alt: img.name, style: { width: '100%', height: '100%', objectFit: 'cover' } }), _jsx("button", { onClick: () => removeImage(img.id), style: {
148
- position: 'absolute',
149
- top: '2px',
150
- right: '2px',
151
- width: '18px',
152
- height: '18px',
153
- borderRadius: '50%',
154
- background: 'rgba(0,0,0,0.7)',
155
- border: 'none',
156
- color: '#fff',
157
- cursor: 'pointer',
158
- display: 'flex',
159
- alignItems: 'center',
160
- justifyContent: 'center',
161
- fontSize: '10px',
162
- }, children: _jsx(Icons.X, {}) })] }, img.id))) })), _jsxs("button", { onClick: () => fileInputRef.current?.click(), disabled: disabled, style: {
163
- display: 'flex',
164
- alignItems: 'center',
165
- gap: '6px',
166
- padding: '6px 10px',
167
- background: 'transparent',
168
- border: `1px dashed ${THEME.border}`,
169
- borderRadius: '6px',
170
- color: THEME.textMuted,
171
- fontSize: '12px',
172
- cursor: disabled ? 'not-allowed' : 'pointer',
173
- transition: 'all 0.2s',
174
- opacity: disabled ? 0.5 : 1,
175
- }, children: [_jsx(Icons.Image, {}), _jsx("span", { children: "Add image" })] })] }));
176
- };
177
- const CodeViewer = ({ code }) => {
178
- const [copied, setCopied] = useState(false);
179
- const handleCopy = async () => {
180
- await navigator.clipboard.writeText(code);
181
- setCopied(true);
182
- setTimeout(() => setCopied(false), 2000);
183
- };
184
- return (_jsxs("div", { style: { height: '100%', display: 'flex', flexDirection: 'column' }, children: [_jsxs("div", { style: {
185
- padding: '8px 12px',
186
- borderBottom: `1px solid ${THEME.border}`,
187
- display: 'flex',
188
- justifyContent: 'space-between',
189
- alignItems: 'center',
190
- }, children: [_jsx("span", { style: { fontSize: '12px', color: THEME.textMuted }, children: "Generated Code" }), _jsxs("button", { onClick: handleCopy, style: {
191
- display: 'flex',
192
- alignItems: 'center',
193
- gap: '4px',
194
- padding: '4px 8px',
195
- background: copied ? 'rgba(34, 197, 94, 0.2)' : 'transparent',
196
- border: `1px solid ${copied ? THEME.success : THEME.border}`,
197
- borderRadius: '4px',
198
- color: copied ? THEME.success : THEME.textMuted,
199
- fontSize: '11px',
200
- cursor: 'pointer',
201
- transition: 'all 0.2s',
202
- }, children: [copied ? _jsx(Icons.Check, {}) : _jsx(Icons.Copy, {}), copied ? 'Copied!' : 'Copy'] })] }), _jsx("pre", { style: {
203
- flex: 1,
204
- margin: 0,
205
- padding: '16px',
206
- overflow: 'auto',
207
- fontSize: '13px',
208
- lineHeight: 1.6,
209
- fontFamily: '"Fira Code", "SF Mono", Monaco, monospace',
210
- background: '#0d1117',
211
- color: '#e6edf3',
212
- }, children: code })] }));
213
- };
214
- // ============================================================================
215
- // MAIN APP
216
- // ============================================================================
217
- const App = () => {
218
- const [conversations, setConversations] = useLocalStorage('storyui_conversations', []);
219
- const [activeConversationId, setActiveConversationId] = useState(null);
220
- const [inputValue, setInputValue] = useState('');
221
- const [isGenerating, setIsGenerating] = useState(false);
222
- const [previewCode, setPreviewCode] = useState(null);
223
- const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
224
- const [previewTab, setPreviewTab] = useState('preview');
225
- const [images, setImages] = useState([]);
226
- const messagesEndRef = useRef(null);
227
- const inputRef = useRef(null);
228
- const { width: chatWidth, startResize } = useResizable(400, 320, 600);
229
- const activeConversation = conversations.find(c => c.id === activeConversationId);
230
- // Auto-scroll messages
231
- useEffect(() => {
232
- messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
233
- }, [activeConversation?.messages]);
234
- // Initialize first conversation
235
- useEffect(() => {
236
- if (conversations.length > 0 && !activeConversationId) {
237
- setActiveConversationId(conversations[0].id);
238
- const lastMsgWithCode = [...conversations[0].messages].reverse().find(m => m.generatedCode);
239
- setPreviewCode(lastMsgWithCode?.generatedCode || null);
240
- }
241
- else if (conversations.length === 0) {
242
- createNewConversation();
243
- }
244
- }, [conversations.length, activeConversationId]);
245
- const createNewConversation = useCallback(() => {
246
- const newConversation = {
247
- id: generateId(),
248
- title: 'New Conversation',
249
- messages: [],
250
- createdAt: Date.now(),
251
- updatedAt: Date.now(),
252
- };
253
- setConversations(prev => [newConversation, ...prev]);
254
- setActiveConversationId(newConversation.id);
255
- setPreviewCode(null);
256
- setImages([]);
257
- inputRef.current?.focus();
258
- }, [setConversations]);
259
- const deleteConversation = (id) => {
260
- setConversations(prev => prev.filter(c => c.id !== id));
261
- if (activeConversationId === id) {
262
- const remaining = conversations.filter(c => c.id !== id);
263
- if (remaining.length > 0) {
264
- setActiveConversationId(remaining[0].id);
265
- }
266
- else {
267
- createNewConversation();
268
- }
269
- }
270
- };
271
- const generateComponent = async (prompt, imageAttachments) => {
272
- const conversationHistory = activeConversation?.messages.map(msg => ({
273
- role: msg.role,
274
- content: msg.role === 'assistant' && msg.generatedCode
275
- ? `Generated component:\n${msg.generatedCode}`
276
- : msg.content
277
- })) || [];
278
- const systemPrompt = `You are a UI component generator. Generate React JSX code using ONLY these available components: ${availableComponents.join(', ')}.
279
-
280
- IMPORTANT RULES:
281
- 1. Return ONLY the JSX code - a single JSX expression that can be rendered
282
- 2. Use ONLY the components listed above - they are from the user's component library
283
- 3. Do NOT include imports, exports, or component definitions
284
- 4. Generate professional, polished UI layouts
285
- 5. Use proper props for each component based on their typical API
286
-
287
- Example response format:
288
- <Card>
289
- <Text>Hello World</Text>
290
- <Button>Click me</Button>
291
- </Card>
292
-
293
- Only respond with the JSX code, nothing else.`;
294
- const response = await fetch(`${SERVER_URL}/story-ui/claude`, {
295
- method: 'POST',
296
- headers: { 'Content-Type': 'application/json' },
297
- body: JSON.stringify({
298
- prompt,
299
- messages: conversationHistory,
300
- systemPrompt,
301
- maxTokens: 4096,
302
- images: imageAttachments.map(img => ({
303
- type: img.type,
304
- data: img.data.split(',')[1],
305
- })),
306
- }),
307
- });
308
- if (!response.ok) {
309
- const errorData = await response.json().catch(() => ({}));
310
- throw new Error(errorData.error || `Server Error: ${response.status}`);
311
- }
312
- const data = await response.json();
313
- const content = data.content?.[0]?.text || data.content || '';
314
- // Clean up the response
315
- let cleanCode = content.trim();
316
- if (cleanCode.startsWith('```')) {
317
- cleanCode = cleanCode
318
- .replace(/^```(?:jsx|tsx|javascript|js)?\n?/, '')
319
- .replace(/\n?```$/, '');
320
- }
321
- return cleanCode;
322
- };
323
- const sendMessage = async () => {
324
- if (!inputValue.trim() || !activeConversationId || isGenerating)
325
- return;
326
- const userMessage = {
327
- id: generateId(),
328
- role: 'user',
329
- content: inputValue.trim(),
330
- timestamp: Date.now(),
331
- images: images.length > 0 ? [...images] : undefined,
332
- };
333
- setConversations(prev => prev.map(conv => {
334
- if (conv.id === activeConversationId) {
335
- return {
336
- ...conv,
337
- messages: [...conv.messages, userMessage],
338
- updatedAt: Date.now(),
339
- title: conv.messages.length === 0 ? inputValue.trim().substring(0, 40) : conv.title,
340
- };
341
- }
342
- return conv;
343
- }));
344
- const currentImages = [...images];
345
- setInputValue('');
346
- setImages([]);
347
- setIsGenerating(true);
348
- try {
349
- const generatedCode = await generateComponent(inputValue.trim(), currentImages);
350
- const assistantMessage = {
351
- id: generateId(),
352
- role: 'assistant',
353
- content: 'Component generated successfully.',
354
- timestamp: Date.now(),
355
- generatedCode,
356
- };
357
- setConversations(prev => prev.map(conv => {
358
- if (conv.id === activeConversationId) {
359
- return {
360
- ...conv,
361
- messages: [...conv.messages, assistantMessage],
362
- updatedAt: Date.now(),
363
- };
364
- }
365
- return conv;
366
- }));
367
- if (generatedCode) {
368
- setPreviewCode(generatedCode);
369
- setPreviewTab('preview');
370
- }
371
- }
372
- catch (error) {
373
- const errorMessage = {
374
- id: generateId(),
375
- role: 'assistant',
376
- content: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
377
- timestamp: Date.now(),
378
- };
379
- setConversations(prev => prev.map(conv => {
380
- if (conv.id === activeConversationId) {
381
- return {
382
- ...conv,
383
- messages: [...conv.messages, errorMessage],
384
- updatedAt: Date.now(),
385
- };
386
- }
387
- return conv;
388
- }));
389
- }
390
- finally {
391
- setIsGenerating(false);
392
- }
393
- };
394
- const handleKeyPress = (e) => {
395
- if (e.key === 'Enter' && !e.shiftKey) {
396
- e.preventDefault();
397
- sendMessage();
398
- }
399
- };
400
- return (_jsxs("div", { style: {
401
- display: 'flex',
402
- height: '100vh',
403
- overflow: 'hidden',
404
- background: THEME.bg,
405
- color: THEME.text,
406
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
407
- }, children: [_jsx("style", { children: `
408
- @keyframes pulse {
409
- 0%, 100% { opacity: 0.4; transform: scale(0.8); }
410
- 50% { opacity: 1; transform: scale(1); }
411
- }
412
- ::-webkit-scrollbar { width: 6px; height: 6px; }
413
- ::-webkit-scrollbar-track { background: transparent; }
414
- ::-webkit-scrollbar-thumb { background: ${THEME.bgElevated}; border-radius: 3px; }
415
- ::-webkit-scrollbar-thumb:hover { background: ${THEME.bgHover}; }
416
- ` }), _jsxs("aside", { style: {
417
- width: sidebarCollapsed ? '60px' : '240px',
418
- background: THEME.bgSurface,
419
- borderRight: `1px solid ${THEME.border}`,
420
- display: 'flex',
421
- flexDirection: 'column',
422
- transition: 'width 0.2s ease',
423
- overflow: 'hidden',
424
- }, children: [_jsxs("div", { style: {
425
- padding: '16px',
426
- borderBottom: `1px solid ${THEME.border}`,
427
- display: 'flex',
428
- alignItems: 'center',
429
- justifyContent: sidebarCollapsed ? 'center' : 'space-between',
430
- }, children: [!sidebarCollapsed && (_jsx("h1", { style: {
431
- fontSize: '16px',
432
- fontWeight: 600,
433
- background: `linear-gradient(135deg, ${THEME.accent}, #8b5cf6)`,
434
- WebkitBackgroundClip: 'text',
435
- WebkitTextFillColor: 'transparent',
436
- letterSpacing: '-0.5px',
437
- }, children: "Story UI" })), _jsx("button", { onClick: () => setSidebarCollapsed(!sidebarCollapsed), style: {
438
- padding: '8px',
439
- background: 'transparent',
440
- border: 'none',
441
- color: THEME.textMuted,
442
- cursor: 'pointer',
443
- borderRadius: '6px',
444
- }, children: _jsx(Icons.Sidebar, {}) })] }), _jsx("div", { style: { padding: sidebarCollapsed ? '8px' : '12px' }, children: _jsxs("button", { onClick: createNewConversation, style: {
445
- width: '100%',
446
- padding: sidebarCollapsed ? '10px' : '10px 14px',
447
- background: THEME.accent,
448
- border: 'none',
449
- borderRadius: '8px',
450
- color: '#fff',
451
- fontSize: '13px',
452
- fontWeight: 500,
453
- cursor: 'pointer',
454
- display: 'flex',
455
- alignItems: 'center',
456
- justifyContent: 'center',
457
- gap: '8px',
458
- }, children: [_jsx(Icons.Plus, {}), !sidebarCollapsed && 'New Chat'] }) }), !sidebarCollapsed && (_jsx("div", { style: { flex: 1, overflow: 'auto', padding: '8px 12px' }, children: conversations.map(conv => (_jsxs("div", { onClick: () => {
459
- setActiveConversationId(conv.id);
460
- const lastMsgWithCode = [...conv.messages].reverse().find(m => m.generatedCode);
461
- setPreviewCode(lastMsgWithCode?.generatedCode || null);
462
- }, style: {
463
- padding: '10px 12px',
464
- marginBottom: '4px',
465
- borderRadius: '8px',
466
- cursor: 'pointer',
467
- display: 'flex',
468
- alignItems: 'center',
469
- justifyContent: 'space-between',
470
- background: conv.id === activeConversationId ? THEME.bgElevated : 'transparent',
471
- }, children: [_jsx("span", { style: {
472
- fontSize: '13px',
473
- color: conv.id === activeConversationId ? THEME.text : THEME.textMuted,
474
- overflow: 'hidden',
475
- textOverflow: 'ellipsis',
476
- whiteSpace: 'nowrap',
477
- flex: 1,
478
- }, children: conv.title }), _jsx("button", { onClick: (e) => {
479
- e.stopPropagation();
480
- deleteConversation(conv.id);
481
- }, style: {
482
- padding: '4px',
483
- background: 'transparent',
484
- border: 'none',
485
- color: THEME.textSubtle,
486
- cursor: 'pointer',
487
- opacity: 0.5,
488
- }, children: _jsx(Icons.Trash, {}) })] }, conv.id))) })), !sidebarCollapsed && (_jsx("div", { style: {
489
- padding: '12px',
490
- borderTop: `1px solid ${THEME.border}`,
491
- fontSize: '11px',
492
- color: THEME.textSubtle,
493
- }, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '6px' }, children: [_jsx("div", { style: {
494
- width: '6px',
495
- height: '6px',
496
- borderRadius: '50%',
497
- background: THEME.success,
498
- } }), _jsxs("span", { children: [availableComponents.length, " components available"] })] }) }))] }), _jsxs("div", { style: {
499
- width: `${chatWidth}px`,
500
- display: 'flex',
501
- flexDirection: 'column',
502
- background: THEME.bg,
503
- borderRight: `1px solid ${THEME.border}`,
504
- position: 'relative',
505
- }, children: [_jsxs("div", { style: { flex: 1, overflow: 'auto', padding: '16px' }, children: [activeConversation?.messages.length === 0 && (_jsxs("div", { style: {
506
- padding: '32px 16px',
507
- textAlign: 'center',
508
- }, children: [_jsx("h2", { style: {
509
- fontSize: '24px',
510
- fontWeight: 600,
511
- marginBottom: '8px',
512
- background: `linear-gradient(135deg, ${THEME.text}, ${THEME.textMuted})`,
513
- WebkitBackgroundClip: 'text',
514
- WebkitTextFillColor: 'transparent',
515
- }, children: "Build UI Components" }), _jsx("p", { style: {
516
- color: THEME.textMuted,
517
- fontSize: '14px',
518
- marginBottom: '24px',
519
- lineHeight: 1.6,
520
- }, children: "Describe what you want to build using your component library." }), _jsx("div", { style: { display: 'flex', flexWrap: 'wrap', gap: '8px', justifyContent: 'center' }, children: ['Create a pricing card', 'Build a dashboard', 'Design a login form'].map(suggestion => (_jsx("button", { onClick: () => setInputValue(suggestion), style: {
521
- padding: '8px 14px',
522
- background: THEME.bgSurface,
523
- border: `1px solid ${THEME.border}`,
524
- borderRadius: '20px',
525
- color: THEME.textMuted,
526
- fontSize: '13px',
527
- cursor: 'pointer',
528
- }, children: suggestion }, suggestion))) })] })), activeConversation?.messages.map(message => (_jsxs("div", { style: {
529
- marginBottom: '16px',
530
- padding: '14px 16px',
531
- borderRadius: '12px',
532
- maxWidth: '90%',
533
- marginLeft: message.role === 'user' ? 'auto' : '0',
534
- marginRight: message.role === 'user' ? '0' : 'auto',
535
- background: message.role === 'user' ? THEME.bgElevated : THEME.bgSurface,
536
- border: `1px solid ${THEME.border}`,
537
- }, children: [message.images && message.images.length > 0 && (_jsx("div", { style: { display: 'flex', gap: '8px', marginBottom: '10px', flexWrap: 'wrap' }, children: message.images.map(img => (_jsx("img", { src: img.data, alt: img.name, style: {
538
- width: '80px',
539
- height: '80px',
540
- objectFit: 'cover',
541
- borderRadius: '8px',
542
- border: `1px solid ${THEME.border}`,
543
- } }, img.id))) })), _jsx("div", { style: { fontSize: '14px', lineHeight: 1.6, color: THEME.text }, children: message.content }), message.generatedCode && (_jsxs("button", { onClick: () => {
544
- setPreviewCode(message.generatedCode);
545
- setPreviewTab('preview');
546
- }, style: {
547
- marginTop: '10px',
548
- padding: '6px 12px',
549
- background: THEME.accentMuted,
550
- border: `1px solid ${THEME.accent}`,
551
- borderRadius: '6px',
552
- color: THEME.accent,
553
- fontSize: '12px',
554
- cursor: 'pointer',
555
- display: 'flex',
556
- alignItems: 'center',
557
- gap: '6px',
558
- }, children: [_jsx(Icons.Eye, {}), "View Component"] }))] }, message.id))), isGenerating && (_jsx("div", { style: {
559
- marginBottom: '16px',
560
- padding: '14px 16px',
561
- borderRadius: '12px',
562
- maxWidth: '90%',
563
- background: THEME.bgSurface,
564
- border: `1px solid ${THEME.border}`,
565
- }, children: _jsx(LoadingDots, {}) })), _jsx("div", { ref: messagesEndRef })] }), _jsxs("div", { style: {
566
- padding: '16px',
567
- borderTop: `1px solid ${THEME.border}`,
568
- background: THEME.bgSurface,
569
- }, children: [_jsx(ImageUploadArea, { images: images, onImagesChange: setImages, disabled: isGenerating }), _jsxs("div", { style: { display: 'flex', gap: '10px', alignItems: 'flex-end' }, children: [_jsx("textarea", { ref: inputRef, value: inputValue, onChange: e => setInputValue(e.target.value), onKeyDown: handleKeyPress, placeholder: "Describe the component you want to create...", disabled: isGenerating, style: {
570
- flex: 1,
571
- padding: '12px 14px',
572
- background: THEME.bgElevated,
573
- border: `1px solid ${THEME.border}`,
574
- borderRadius: '10px',
575
- color: THEME.text,
576
- fontSize: '14px',
577
- resize: 'none',
578
- outline: 'none',
579
- fontFamily: 'inherit',
580
- minHeight: '44px',
581
- maxHeight: '120px',
582
- }, rows: 1 }), _jsx("button", { onClick: sendMessage, disabled: isGenerating || !inputValue.trim(), style: {
583
- padding: '12px',
584
- background: (isGenerating || !inputValue.trim()) ? THEME.bgElevated : THEME.accent,
585
- border: 'none',
586
- borderRadius: '10px',
587
- color: (isGenerating || !inputValue.trim()) ? THEME.textSubtle : '#fff',
588
- cursor: (isGenerating || !inputValue.trim()) ? 'not-allowed' : 'pointer',
589
- minWidth: '44px',
590
- height: '44px',
591
- }, children: _jsx(Icons.Send, {}) })] })] }), _jsx("div", { onMouseDown: startResize, style: {
592
- position: 'absolute',
593
- right: 0,
594
- top: 0,
595
- bottom: 0,
596
- width: '4px',
597
- cursor: 'col-resize',
598
- background: 'transparent',
599
- } })] }), _jsxs("div", { style: {
600
- flex: 1,
601
- display: 'flex',
602
- flexDirection: 'column',
603
- background: THEME.bg,
604
- minWidth: 0,
605
- }, children: [_jsxs("div", { style: {
606
- padding: '12px 16px',
607
- borderBottom: `1px solid ${THEME.border}`,
608
- display: 'flex',
609
- alignItems: 'center',
610
- justifyContent: 'space-between',
611
- }, children: [_jsxs("div", { style: { display: 'flex', gap: '4px' }, children: [_jsxs("button", { onClick: () => setPreviewTab('preview'), style: {
612
- padding: '8px 14px',
613
- background: previewTab === 'preview' ? THEME.bgElevated : 'transparent',
614
- border: 'none',
615
- borderRadius: '6px',
616
- color: previewTab === 'preview' ? THEME.text : THEME.textMuted,
617
- fontSize: '13px',
618
- cursor: 'pointer',
619
- display: 'flex',
620
- alignItems: 'center',
621
- gap: '6px',
622
- }, children: [_jsx(Icons.Eye, {}), "Preview"] }), _jsxs("button", { onClick: () => setPreviewTab('code'), style: {
623
- padding: '8px 14px',
624
- background: previewTab === 'code' ? THEME.bgElevated : 'transparent',
625
- border: 'none',
626
- borderRadius: '6px',
627
- color: previewTab === 'code' ? THEME.text : THEME.textMuted,
628
- fontSize: '13px',
629
- cursor: 'pointer',
630
- display: 'flex',
631
- alignItems: 'center',
632
- gap: '6px',
633
- }, children: [_jsx(Icons.Code, {}), "Code"] })] }), previewCode && previewTab === 'preview' && (_jsx("span", { style: { fontSize: '12px', color: THEME.textMuted }, children: "Live Preview" }))] }), _jsx("div", { style: { flex: 1, overflow: 'hidden' }, children: previewCode ? (previewTab === 'preview' ? (_jsx(LivePreviewRenderer, { code: previewCode, containerStyle: { height: '100%', background: THEME.bgSurface }, onError: (err) => console.error('Preview error:', err) })) : (_jsx(CodeViewer, { code: previewCode }))) : (_jsxs("div", { style: {
634
- height: '100%',
635
- display: 'flex',
636
- flexDirection: 'column',
637
- alignItems: 'center',
638
- justifyContent: 'center',
639
- color: THEME.textSubtle,
640
- padding: '40px',
641
- }, children: [_jsx("div", { style: {
642
- width: '80px',
643
- height: '80px',
644
- borderRadius: '20px',
645
- background: THEME.bgSurface,
646
- display: 'flex',
647
- alignItems: 'center',
648
- justifyContent: 'center',
649
- marginBottom: '20px',
650
- border: `1px solid ${THEME.border}`,
651
- }, children: _jsxs("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [_jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }), _jsx("path", { d: "M3 9h18M9 21V9" })] }) }), _jsx("p", { style: { fontSize: '16px', fontWeight: 500, marginBottom: '8px', color: THEME.textMuted }, children: "Ready to Build" }), _jsx("p", { style: { fontSize: '14px', maxWidth: '260px', textAlign: 'center', lineHeight: 1.5 }, children: "Describe a component and watch it come to life" })] })) })] })] }));
652
- };
653
- export default App;