@flowdrop/flowdrop 1.0.0 → 1.1.0

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 (388) hide show
  1. package/README.md +50 -50
  2. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  3. package/dist/adapters/WorkflowAdapter.js +25 -25
  4. package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +2 -2
  5. package/dist/adapters/agentspec/AgentSpecAdapter.js +133 -122
  6. package/dist/adapters/agentspec/agentAdapter.d.ts +2 -2
  7. package/dist/adapters/agentspec/agentAdapter.js +10 -10
  8. package/dist/adapters/agentspec/autoLayout.d.ts +1 -1
  9. package/dist/adapters/agentspec/autoLayout.js +2 -2
  10. package/dist/adapters/agentspec/componentTypeDefaults.d.ts +1 -1
  11. package/dist/adapters/agentspec/componentTypeDefaults.js +120 -120
  12. package/dist/adapters/agentspec/defaultNodeTypes.d.ts +2 -2
  13. package/dist/adapters/agentspec/defaultNodeTypes.js +307 -307
  14. package/dist/adapters/agentspec/index.d.ts +10 -10
  15. package/dist/adapters/agentspec/index.js +6 -6
  16. package/dist/adapters/agentspec/validator.d.ts +2 -2
  17. package/dist/adapters/agentspec/validator.js +22 -20
  18. package/dist/api/enhanced-client.d.ts +3 -3
  19. package/dist/api/enhanced-client.js +73 -72
  20. package/dist/components/App.svelte +1081 -961
  21. package/dist/components/App.svelte.d.ts +9 -6
  22. package/dist/components/CanvasBanner.stories.svelte +23 -20
  23. package/dist/components/CanvasBanner.stories.svelte.d.ts +1 -1
  24. package/dist/components/CanvasBanner.svelte +46 -46
  25. package/dist/components/ConfigForm.svelte +1164 -1065
  26. package/dist/components/ConfigForm.svelte.d.ts +2 -2
  27. package/dist/components/ConfigModal.svelte +180 -180
  28. package/dist/components/ConfigModal.svelte.d.ts +1 -1
  29. package/dist/components/ConfigPanel.stories.svelte +35 -35
  30. package/dist/components/ConfigPanel.stories.svelte.d.ts +1 -1
  31. package/dist/components/ConfigPanel.svelte +178 -167
  32. package/dist/components/ConfigPanel.svelte.d.ts +1 -1
  33. package/dist/components/ConnectionLine.svelte +25 -25
  34. package/dist/components/EdgeRefresher.svelte +26 -26
  35. package/dist/components/FlowDropEdge.stories.svelte +197 -0
  36. package/dist/components/FlowDropEdge.stories.svelte.d.ts +26 -0
  37. package/dist/components/FlowDropEdge.svelte +168 -0
  38. package/dist/components/FlowDropEdge.svelte.d.ts +4 -0
  39. package/dist/components/FlowDropZone.svelte +63 -60
  40. package/dist/components/FlowDropZone.svelte.d.ts +1 -1
  41. package/dist/components/LoadingSpinner.stories.svelte +19 -19
  42. package/dist/components/LoadingSpinner.stories.svelte.d.ts +1 -1
  43. package/dist/components/LoadingSpinner.svelte +21 -21
  44. package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
  45. package/dist/components/Logo.stories.svelte +13 -13
  46. package/dist/components/Logo.stories.svelte.d.ts +1 -1
  47. package/dist/components/Logo.svelte +101 -95
  48. package/dist/components/LogsSidebar.svelte +553 -546
  49. package/dist/components/LogsSidebar.svelte.d.ts +1 -1
  50. package/dist/components/MarkdownDisplay.stories.svelte +29 -23
  51. package/dist/components/MarkdownDisplay.stories.svelte.d.ts +1 -1
  52. package/dist/components/MarkdownDisplay.svelte +16 -14
  53. package/dist/components/Navbar.stories.svelte +43 -38
  54. package/dist/components/Navbar.stories.svelte.d.ts +1 -1
  55. package/dist/components/Navbar.svelte +760 -706
  56. package/dist/components/Navbar.svelte.d.ts +1 -1
  57. package/dist/components/NodeSidebar.svelte +900 -746
  58. package/dist/components/NodeSidebar.svelte.d.ts +3 -1
  59. package/dist/components/NodeStatusOverlay.stories.svelte +82 -70
  60. package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +1 -1
  61. package/dist/components/NodeStatusOverlay.svelte +295 -280
  62. package/dist/components/NodeStatusOverlay.svelte.d.ts +3 -3
  63. package/dist/components/PipelineStatus.svelte +326 -300
  64. package/dist/components/PipelineStatus.svelte.d.ts +4 -4
  65. package/dist/components/PortCoordinateTracker.svelte +49 -47
  66. package/dist/components/PortCoordinateTracker.svelte.d.ts +1 -1
  67. package/dist/components/ReadOnlyDetails.svelte +156 -156
  68. package/dist/components/SchemaForm.stories.svelte +106 -98
  69. package/dist/components/SchemaForm.stories.svelte.d.ts +1 -1
  70. package/dist/components/SchemaForm.svelte +490 -463
  71. package/dist/components/SchemaForm.svelte.d.ts +2 -2
  72. package/dist/components/SettingsModal.svelte +226 -223
  73. package/dist/components/SettingsModal.svelte.d.ts +1 -1
  74. package/dist/components/SettingsPanel.svelte +637 -601
  75. package/dist/components/SettingsPanel.svelte.d.ts +1 -1
  76. package/dist/components/StatusIcon.stories.svelte +62 -49
  77. package/dist/components/StatusIcon.stories.svelte.d.ts +1 -1
  78. package/dist/components/StatusIcon.svelte +87 -87
  79. package/dist/components/StatusIcon.svelte.d.ts +2 -2
  80. package/dist/components/StatusLabel.stories.svelte +12 -12
  81. package/dist/components/StatusLabel.stories.svelte.d.ts +1 -1
  82. package/dist/components/StatusLabel.svelte +19 -19
  83. package/dist/components/ThemeToggle.stories.svelte +16 -16
  84. package/dist/components/ThemeToggle.stories.svelte.d.ts +1 -1
  85. package/dist/components/ThemeToggle.svelte +180 -169
  86. package/dist/components/ThemeToggle.svelte.d.ts +1 -1
  87. package/dist/components/UniversalNode.svelte +150 -138
  88. package/dist/components/UniversalNode.svelte.d.ts +3 -3
  89. package/dist/components/WorkflowEditor.svelte +1069 -1007
  90. package/dist/components/WorkflowEditor.svelte.d.ts +4 -4
  91. package/dist/components/form/FormArray.svelte +1034 -973
  92. package/dist/components/form/FormArray.svelte.d.ts +1 -1
  93. package/dist/components/form/FormAutocomplete.svelte +1021 -978
  94. package/dist/components/form/FormAutocomplete.svelte.d.ts +1 -1
  95. package/dist/components/form/FormCheckboxGroup.stories.svelte +23 -20
  96. package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +1 -1
  97. package/dist/components/form/FormCheckboxGroup.svelte +136 -136
  98. package/dist/components/form/FormCodeEditor.svelte +452 -434
  99. package/dist/components/form/FormField.svelte +366 -355
  100. package/dist/components/form/FormField.svelte.d.ts +2 -2
  101. package/dist/components/form/FormFieldLight.svelte +400 -384
  102. package/dist/components/form/FormFieldLight.svelte.d.ts +1 -1
  103. package/dist/components/form/FormFieldWrapper.stories.svelte +42 -42
  104. package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +1 -1
  105. package/dist/components/form/FormFieldWrapper.svelte +100 -93
  106. package/dist/components/form/FormFieldWrapper.svelte.d.ts +1 -1
  107. package/dist/components/form/FormFieldset.svelte +108 -108
  108. package/dist/components/form/FormFieldset.svelte.d.ts +2 -2
  109. package/dist/components/form/FormMarkdownEditor.svelte +758 -725
  110. package/dist/components/form/FormNumberField.stories.svelte +25 -25
  111. package/dist/components/form/FormNumberField.stories.svelte.d.ts +1 -1
  112. package/dist/components/form/FormNumberField.svelte +88 -88
  113. package/dist/components/form/FormRangeField.stories.svelte +20 -20
  114. package/dist/components/form/FormRangeField.stories.svelte.d.ts +1 -1
  115. package/dist/components/form/FormRangeField.svelte +234 -226
  116. package/dist/components/form/FormSelect.stories.svelte +38 -38
  117. package/dist/components/form/FormSelect.stories.svelte.d.ts +1 -1
  118. package/dist/components/form/FormSelect.svelte +101 -101
  119. package/dist/components/form/FormSelect.svelte.d.ts +1 -1
  120. package/dist/components/form/FormTemplateEditor.svelte +847 -798
  121. package/dist/components/form/FormTemplateEditor.svelte.d.ts +1 -1
  122. package/dist/components/form/FormTextField.stories.svelte +29 -23
  123. package/dist/components/form/FormTextField.stories.svelte.d.ts +1 -1
  124. package/dist/components/form/FormTextField.svelte +68 -68
  125. package/dist/components/form/FormTextarea.stories.svelte +28 -25
  126. package/dist/components/form/FormTextarea.stories.svelte.d.ts +1 -1
  127. package/dist/components/form/FormTextarea.svelte +74 -74
  128. package/dist/components/form/FormToggle.stories.svelte +23 -20
  129. package/dist/components/form/FormToggle.stories.svelte.d.ts +1 -1
  130. package/dist/components/form/FormToggle.svelte +98 -98
  131. package/dist/components/form/FormUISchemaRenderer.svelte +120 -113
  132. package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +3 -3
  133. package/dist/components/form/index.d.ts +19 -19
  134. package/dist/components/form/index.js +18 -18
  135. package/dist/components/form/templateAutocomplete.d.ts +2 -2
  136. package/dist/components/form/templateAutocomplete.js +64 -55
  137. package/dist/components/form/types.d.ts +6 -6
  138. package/dist/components/form/types.js +9 -4
  139. package/dist/components/icons/AlertCircleIcon.svelte +11 -0
  140. package/dist/components/icons/AlertCircleIcon.svelte.d.ts +26 -0
  141. package/dist/components/icons/CogIcon.svelte +11 -0
  142. package/dist/components/icons/CogIcon.svelte.d.ts +26 -0
  143. package/dist/components/interrupt/ChoicePrompt.stories.svelte +54 -38
  144. package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +1 -1
  145. package/dist/components/interrupt/ChoicePrompt.svelte +407 -383
  146. package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +1 -1
  147. package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +48 -48
  148. package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +1 -1
  149. package/dist/components/interrupt/ConfirmationPrompt.svelte +280 -274
  150. package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +1 -1
  151. package/dist/components/interrupt/FormPrompt.svelte +223 -218
  152. package/dist/components/interrupt/FormPrompt.svelte.d.ts +1 -1
  153. package/dist/components/interrupt/InterruptBubble.svelte +617 -583
  154. package/dist/components/interrupt/InterruptBubble.svelte.d.ts +2 -2
  155. package/dist/components/interrupt/ReviewPrompt.stories.svelte +66 -56
  156. package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +1 -1
  157. package/dist/components/interrupt/ReviewPrompt.svelte +861 -841
  158. package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +1 -1
  159. package/dist/components/interrupt/TextInputPrompt.stories.svelte +38 -33
  160. package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +1 -1
  161. package/dist/components/interrupt/TextInputPrompt.svelte +333 -328
  162. package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +1 -1
  163. package/dist/components/interrupt/index.d.ts +5 -5
  164. package/dist/components/interrupt/index.js +5 -5
  165. package/dist/components/layouts/MainLayout.svelte +724 -691
  166. package/dist/components/layouts/MainLayout.svelte.d.ts +6 -6
  167. package/dist/components/nodes/GatewayNode.stories.svelte +100 -99
  168. package/dist/components/nodes/GatewayNode.svelte +605 -571
  169. package/dist/components/nodes/GatewayNode.svelte.d.ts +3 -3
  170. package/dist/components/nodes/IdeaNode.stories.svelte +44 -43
  171. package/dist/components/nodes/IdeaNode.svelte +451 -437
  172. package/dist/components/nodes/IdeaNode.svelte.d.ts +1 -1
  173. package/dist/components/nodes/NotesNode.stories.svelte +65 -64
  174. package/dist/components/nodes/NotesNode.svelte +380 -369
  175. package/dist/components/nodes/NotesNode.svelte.d.ts +1 -1
  176. package/dist/components/nodes/SimpleNode.stories.svelte +145 -144
  177. package/dist/components/nodes/SimpleNode.svelte +486 -424
  178. package/dist/components/nodes/SimpleNode.svelte.d.ts +1 -1
  179. package/dist/components/nodes/SquareNode.stories.svelte +73 -73
  180. package/dist/components/nodes/SquareNode.svelte +439 -380
  181. package/dist/components/nodes/SquareNode.svelte.d.ts +1 -1
  182. package/dist/components/nodes/TerminalNode.stories.svelte +13 -13
  183. package/dist/components/nodes/TerminalNode.svelte +709 -670
  184. package/dist/components/nodes/TerminalNode.svelte.d.ts +1 -1
  185. package/dist/components/nodes/ToolNode.stories.svelte +181 -180
  186. package/dist/components/nodes/ToolNode.svelte +505 -447
  187. package/dist/components/nodes/ToolNode.svelte.d.ts +1 -1
  188. package/dist/components/nodes/WorkflowNode.stories.svelte +70 -46
  189. package/dist/components/nodes/WorkflowNode.svelte +621 -551
  190. package/dist/components/nodes/WorkflowNode.svelte.d.ts +3 -3
  191. package/dist/components/playground/ChatPanel.svelte +945 -889
  192. package/dist/components/playground/ExecutionLogs.svelte +495 -472
  193. package/dist/components/playground/InputCollector.svelte +449 -428
  194. package/dist/components/playground/MessageBubble.stories.svelte +47 -47
  195. package/dist/components/playground/MessageBubble.stories.svelte.d.ts +1 -1
  196. package/dist/components/playground/MessageBubble.svelte +626 -610
  197. package/dist/components/playground/MessageBubble.svelte.d.ts +1 -1
  198. package/dist/components/playground/Playground.svelte +1088 -1057
  199. package/dist/components/playground/Playground.svelte.d.ts +3 -3
  200. package/dist/components/playground/PlaygroundModal.svelte +208 -204
  201. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -3
  202. package/dist/components/playground/SessionManager.svelte +527 -521
  203. package/dist/components/playground/SessionManager.svelte.d.ts +1 -1
  204. package/dist/config/agentSpecEndpoints.d.ts +1 -1
  205. package/dist/config/agentSpecEndpoints.js +20 -20
  206. package/dist/config/constants.d.ts +8 -0
  207. package/dist/config/constants.js +10 -2
  208. package/dist/config/defaultCategories.d.ts +1 -1
  209. package/dist/config/defaultCategories.js +86 -86
  210. package/dist/config/defaultPortConfig.d.ts +1 -1
  211. package/dist/config/defaultPortConfig.js +144 -144
  212. package/dist/config/endpoints.d.ts +4 -4
  213. package/dist/config/endpoints.js +65 -65
  214. package/dist/config/runtimeConfig.d.ts +2 -2
  215. package/dist/config/runtimeConfig.js +8 -8
  216. package/dist/core/index.d.ts +63 -59
  217. package/dist/core/index.js +35 -33
  218. package/dist/display/index.d.ts +2 -2
  219. package/dist/display/index.js +2 -2
  220. package/dist/editor/index.d.ts +62 -62
  221. package/dist/editor/index.js +53 -53
  222. package/dist/form/code.d.ts +5 -5
  223. package/dist/form/code.js +14 -14
  224. package/dist/form/fieldRegistry.d.ts +3 -3
  225. package/dist/form/fieldRegistry.js +11 -9
  226. package/dist/form/full.d.ts +8 -8
  227. package/dist/form/full.js +9 -9
  228. package/dist/form/index.d.ts +18 -18
  229. package/dist/form/index.js +16 -16
  230. package/dist/form/markdown.d.ts +4 -4
  231. package/dist/form/markdown.js +8 -8
  232. package/dist/helpers/proximityConnect.d.ts +3 -3
  233. package/dist/helpers/proximityConnect.js +34 -32
  234. package/dist/helpers/workflowEditorHelper.d.ts +5 -5
  235. package/dist/helpers/workflowEditorHelper.js +108 -96
  236. package/dist/index.d.ts +6 -6
  237. package/dist/index.js +6 -6
  238. package/dist/mocks/app-environment.js +2 -2
  239. package/dist/mocks/app-forms.js +9 -9
  240. package/dist/mocks/app-navigation.js +11 -11
  241. package/dist/mocks/app-stores.js +8 -8
  242. package/dist/playground/index.d.ts +19 -19
  243. package/dist/playground/index.js +16 -16
  244. package/dist/playground/mount.d.ts +3 -3
  245. package/dist/playground/mount.js +24 -24
  246. package/dist/registry/builtinFormats.js +13 -13
  247. package/dist/registry/builtinNodes.d.ts +2 -2
  248. package/dist/registry/builtinNodes.js +77 -77
  249. package/dist/registry/index.d.ts +4 -4
  250. package/dist/registry/index.js +4 -4
  251. package/dist/registry/nodeComponentRegistry.d.ts +8 -8
  252. package/dist/registry/nodeComponentRegistry.js +11 -9
  253. package/dist/registry/plugin.d.ts +2 -2
  254. package/dist/registry/plugin.js +11 -11
  255. package/dist/registry/workflowFormatRegistry.d.ts +3 -3
  256. package/dist/registry/workflowFormatRegistry.js +2 -2
  257. package/dist/schema/index.d.ts +1 -1
  258. package/dist/schema/index.js +2 -2
  259. package/dist/schemas/v1/workflow.schema.json +22 -107
  260. package/dist/services/agentSpecExecutionService.d.ts +3 -3
  261. package/dist/services/agentSpecExecutionService.js +59 -55
  262. package/dist/services/api.d.ts +18 -4
  263. package/dist/services/api.js +46 -43
  264. package/dist/services/apiVariableService.d.ts +1 -1
  265. package/dist/services/apiVariableService.js +41 -34
  266. package/dist/services/autoSaveService.js +8 -8
  267. package/dist/services/categoriesApi.d.ts +2 -2
  268. package/dist/services/categoriesApi.js +8 -8
  269. package/dist/services/draftStorage.d.ts +1 -1
  270. package/dist/services/draftStorage.js +11 -11
  271. package/dist/services/dynamicSchemaService.d.ts +1 -1
  272. package/dist/services/dynamicSchemaService.js +41 -39
  273. package/dist/services/globalSave.d.ts +2 -2
  274. package/dist/services/globalSave.js +53 -42
  275. package/dist/services/historyService.d.ts +1 -1
  276. package/dist/services/historyService.js +8 -8
  277. package/dist/services/interruptService.d.ts +1 -1
  278. package/dist/services/interruptService.js +35 -29
  279. package/dist/services/nodeExecutionService.d.ts +1 -1
  280. package/dist/services/nodeExecutionService.js +45 -44
  281. package/dist/services/playgroundService.d.ts +1 -1
  282. package/dist/services/playgroundService.js +29 -29
  283. package/dist/services/portConfigApi.d.ts +2 -2
  284. package/dist/services/portConfigApi.js +8 -8
  285. package/dist/services/settingsService.d.ts +2 -2
  286. package/dist/services/settingsService.js +25 -19
  287. package/dist/services/toastService.d.ts +4 -4
  288. package/dist/services/toastService.js +33 -33
  289. package/dist/services/variableService.d.ts +1 -1
  290. package/dist/services/variableService.js +36 -36
  291. package/dist/services/workflowStorage.d.ts +2 -2
  292. package/dist/services/workflowStorage.js +13 -13
  293. package/dist/settings/index.d.ts +7 -7
  294. package/dist/settings/index.js +6 -6
  295. package/dist/skins/default.d.ts +2 -0
  296. package/dist/skins/default.js +1 -0
  297. package/dist/skins/index.d.ts +13 -0
  298. package/dist/skins/index.js +30 -0
  299. package/dist/skins/slate.d.ts +2 -0
  300. package/dist/skins/slate.js +78 -0
  301. package/dist/stores/categoriesStore.svelte.d.ts +1 -1
  302. package/dist/stores/categoriesStore.svelte.js +5 -5
  303. package/dist/stores/editorStateMachine.svelte.d.ts +2 -2
  304. package/dist/stores/editorStateMachine.svelte.js +65 -33
  305. package/dist/stores/historyStore.svelte.d.ts +4 -4
  306. package/dist/stores/historyStore.svelte.js +4 -4
  307. package/dist/stores/interruptStore.svelte.d.ts +3 -3
  308. package/dist/stores/interruptStore.svelte.js +21 -21
  309. package/dist/stores/playgroundStore.svelte.d.ts +2 -2
  310. package/dist/stores/playgroundStore.svelte.js +25 -18
  311. package/dist/stores/portCoordinateStore.svelte.d.ts +2 -2
  312. package/dist/stores/portCoordinateStore.svelte.js +15 -8
  313. package/dist/stores/settingsStore.svelte.d.ts +2 -2
  314. package/dist/stores/settingsStore.svelte.js +62 -57
  315. package/dist/stores/workflowStore.svelte.d.ts +3 -3
  316. package/dist/stores/workflowStore.svelte.js +50 -47
  317. package/dist/stories/CanvasDecorator.svelte +35 -32
  318. package/dist/stories/CanvasDecorator.svelte.d.ts +2 -2
  319. package/dist/stories/EdgeDecorator.svelte +125 -0
  320. package/dist/stories/EdgeDecorator.svelte.d.ts +17 -0
  321. package/dist/stories/NodeDecorator.svelte +59 -53
  322. package/dist/stories/NodeDecorator.svelte.d.ts +1 -1
  323. package/dist/stories/utils.d.ts +2 -2
  324. package/dist/stories/utils.js +105 -67
  325. package/dist/styles/base.css +599 -595
  326. package/dist/styles/toast.css +14 -14
  327. package/dist/styles/tokens.css +409 -378
  328. package/dist/svelte-app.d.ts +9 -9
  329. package/dist/svelte-app.js +39 -39
  330. package/dist/themes/default.d.ts +2 -0
  331. package/dist/themes/default.js +9 -0
  332. package/dist/themes/index.d.ts +13 -0
  333. package/dist/themes/index.js +44 -0
  334. package/dist/themes/minimal.d.ts +2 -0
  335. package/dist/themes/minimal.js +11 -0
  336. package/dist/types/agentspec.d.ts +18 -18
  337. package/dist/types/agentspec.js +2 -2
  338. package/dist/types/auth.d.ts +1 -1
  339. package/dist/types/auth.js +6 -6
  340. package/dist/types/config.d.ts +6 -6
  341. package/dist/types/events.d.ts +2 -2
  342. package/dist/types/events.js +2 -2
  343. package/dist/types/index.d.ts +32 -32
  344. package/dist/types/index.js +6 -6
  345. package/dist/types/interrupt.d.ts +6 -6
  346. package/dist/types/interrupt.js +21 -21
  347. package/dist/types/interruptState.d.ts +12 -12
  348. package/dist/types/interruptState.js +66 -66
  349. package/dist/types/playground.d.ts +7 -7
  350. package/dist/types/playground.js +14 -14
  351. package/dist/types/settings.d.ts +5 -3
  352. package/dist/types/settings.js +25 -18
  353. package/dist/types/skin.d.ts +31 -0
  354. package/dist/types/skin.js +1 -0
  355. package/dist/types/theme.d.ts +35 -0
  356. package/dist/types/theme.js +1 -0
  357. package/dist/types/uischema.d.ts +4 -4
  358. package/dist/types/uischema.js +3 -3
  359. package/dist/utils/colors.d.ts +1 -1
  360. package/dist/utils/colors.js +97 -95
  361. package/dist/utils/config.d.ts +2 -2
  362. package/dist/utils/config.js +48 -48
  363. package/dist/utils/connections.d.ts +2 -2
  364. package/dist/utils/connections.js +15 -15
  365. package/dist/utils/errors.js +3 -3
  366. package/dist/utils/fetchWithAuth.d.ts +1 -1
  367. package/dist/utils/fetchWithAuth.js +2 -2
  368. package/dist/utils/handleIds.d.ts +2 -2
  369. package/dist/utils/handleIds.js +8 -8
  370. package/dist/utils/handlePositioning.d.ts +1 -1
  371. package/dist/utils/handlePositioning.js +2 -2
  372. package/dist/utils/icons.d.ts +1 -1
  373. package/dist/utils/icons.js +74 -74
  374. package/dist/utils/logger.d.ts +1 -1
  375. package/dist/utils/logger.js +7 -7
  376. package/dist/utils/nodeStatus.d.ts +1 -1
  377. package/dist/utils/nodeStatus.js +48 -48
  378. package/dist/utils/nodeTypes.d.ts +1 -1
  379. package/dist/utils/nodeTypes.js +21 -20
  380. package/dist/utils/nodeWrapper.d.ts +7 -7
  381. package/dist/utils/nodeWrapper.js +21 -19
  382. package/dist/utils/performanceUtils.d.ts +1 -1
  383. package/dist/utils/performanceUtils.js +2 -1
  384. package/dist/utils/sanitize.js +1 -1
  385. package/dist/utils/uischema.d.ts +2 -2
  386. package/dist/utils/uischema.js +8 -8
  387. package/dist/utils/validation.js +20 -8
  388. package/package.json +296 -291
@@ -28,611 +28,647 @@
28
28
  -->
29
29
 
30
30
  <script lang="ts">
31
- import Icon from '@iconify/svelte';
32
- import { SchemaForm } from '../form/index.js';
33
- import type { ConfigSchema } from '../types/index.js';
34
- import type { SettingsCategory } from '../types/settings.js';
35
- import {
36
- SETTINGS_CATEGORIES,
37
- SETTINGS_CATEGORY_LABELS,
38
- SETTINGS_CATEGORY_ICONS
39
- } from '../types/settings.js';
40
- import {
41
- getSettings,
42
- updateSettings,
43
- resetSettings,
44
- syncSettingsToApi,
45
- getSyncStatus
46
- } from '../stores/settingsStore.svelte.js';
47
- import { logger } from '../utils/logger.js';
48
-
49
- /**
50
- * Props interface for SettingsPanel component
51
- */
52
- interface Props {
53
- /** Categories to display (defaults to all) */
54
- categories?: SettingsCategory[];
55
- /** Show the "Sync to Cloud" button */
56
- showSyncButton?: boolean;
57
- /** Show the reset button */
58
- showResetButton?: boolean;
59
- /** Callback when settings change */
60
- onSettingsChange?: (category: SettingsCategory, values: Record<string, unknown>) => void;
61
- /** Callback when close is requested */
62
- onClose?: () => void;
63
- /** Custom CSS class */
64
- class?: string;
65
- }
66
-
67
- const {
68
- categories = SETTINGS_CATEGORIES,
69
- showSyncButton = true,
70
- showResetButton = true,
71
- onSettingsChange,
72
- onClose,
73
- class: className = ''
74
- }: Props = $props();
75
-
76
- /**
77
- * Currently active tab
78
- */
79
- // svelte-ignore state_referenced_locally — initial default, user switches tabs
80
- let activeTab = $state<SettingsCategory>(categories[0] ?? 'theme');
81
-
82
- /**
83
- * Whether sync is in progress
84
- */
85
- let isSyncing = $derived(getSyncStatus().status === 'syncing');
86
-
87
- /**
88
- * JSON Schema definitions for each settings category
89
- */
90
- const schemas: Record<SettingsCategory, ConfigSchema> = {
91
- theme: {
92
- type: 'object',
93
- properties: {
94
- preference: {
95
- type: 'string',
96
- title: 'Theme Preference',
97
- description: 'Choose your preferred color scheme',
98
- oneOf: [
99
- { const: 'light', title: 'Light' },
100
- { const: 'dark', title: 'Dark' },
101
- { const: 'auto', title: 'Auto (System)' }
102
- ],
103
- default: 'auto'
104
- }
105
- }
106
- },
107
- editor: {
108
- type: 'object',
109
- properties: {
110
- showGrid: {
111
- type: 'boolean',
112
- title: 'Show Grid',
113
- description: 'Display grid lines on the canvas',
114
- default: true
115
- },
116
- snapToGrid: {
117
- type: 'boolean',
118
- title: 'Snap to Grid',
119
- description: 'Snap nodes to grid when dragging',
120
- default: true
121
- },
122
- gridSize: {
123
- type: 'number',
124
- title: 'Grid Size',
125
- description: 'Grid cell size in pixels',
126
- minimum: 5,
127
- maximum: 50,
128
- default: 20
129
- },
130
- showMinimap: {
131
- type: 'boolean',
132
- title: 'Show Minimap',
133
- description: 'Display navigation minimap',
134
- default: true
135
- },
136
- defaultZoom: {
137
- type: 'number',
138
- title: 'Default Zoom',
139
- description: 'Initial zoom level (1 = 100%)',
140
- minimum: 0.25,
141
- maximum: 2,
142
- default: 1
143
- },
144
- fitViewOnLoad: {
145
- type: 'boolean',
146
- title: 'Fit View on Load',
147
- description: 'Automatically fit workflow to view when loading',
148
- default: true
149
- },
150
- proximityConnect: {
151
- type: 'boolean',
152
- title: 'Proximity Connect',
153
- description: 'Auto-connect compatible ports when dragging nodes near each other',
154
- default: false
155
- },
156
- proximityConnectDistance: {
157
- type: 'number',
158
- title: 'Proximity Distance',
159
- description: 'Distance threshold in pixels for proximity connect',
160
- minimum: 50,
161
- maximum: 500,
162
- default: 150
163
- }
164
- }
165
- },
166
- ui: {
167
- type: 'object',
168
- properties: {
169
- sidebarWidth: {
170
- type: 'number',
171
- title: 'Sidebar Width',
172
- description: 'Width of the node sidebar in pixels',
173
- minimum: 200,
174
- maximum: 500,
175
- default: 280
176
- },
177
- sidebarCollapsed: {
178
- type: 'boolean',
179
- title: 'Sidebar Collapsed',
180
- description: 'Start with sidebar collapsed',
181
- default: false
182
- },
183
- compactMode: {
184
- type: 'boolean',
185
- title: 'Compact Mode',
186
- description: 'Use compact UI with smaller spacing',
187
- default: false
188
- }
189
- }
190
- },
191
- behavior: {
192
- type: 'object',
193
- properties: {
194
- autoSave: {
195
- type: 'boolean',
196
- title: 'Auto Save',
197
- description: 'Automatically save changes',
198
- default: false
199
- },
200
- autoSaveInterval: {
201
- type: 'number',
202
- title: 'Auto Save Interval',
203
- description: 'Time between auto-saves in milliseconds',
204
- minimum: 5000,
205
- maximum: 300000,
206
- default: 30000
207
- },
208
- undoHistoryLimit: {
209
- type: 'number',
210
- title: 'Undo History Limit',
211
- description: 'Maximum number of undo steps (0 to disable)',
212
- minimum: 0,
213
- maximum: 200,
214
- default: 0
215
- },
216
- confirmDelete: {
217
- type: 'boolean',
218
- title: 'Confirm Delete',
219
- description: 'Show confirmation before deleting nodes',
220
- default: true
221
- }
222
- }
223
- },
224
- api: {
225
- type: 'object',
226
- properties: {
227
- timeout: {
228
- type: 'number',
229
- title: 'Request Timeout',
230
- description: 'API request timeout in milliseconds',
231
- minimum: 5000,
232
- maximum: 120000,
233
- default: 30000
234
- },
235
- retryEnabled: {
236
- type: 'boolean',
237
- title: 'Enable Retry',
238
- description: 'Automatically retry failed requests',
239
- default: true
240
- },
241
- retryAttempts: {
242
- type: 'number',
243
- title: 'Retry Attempts',
244
- description: 'Maximum number of retry attempts',
245
- minimum: 1,
246
- maximum: 10,
247
- default: 3
248
- },
249
- cacheEnabled: {
250
- type: 'boolean',
251
- title: 'Enable Caching',
252
- description: 'Cache API responses for better performance',
253
- default: true
254
- }
255
- }
256
- }
257
- };
258
-
259
- /**
260
- * Get current values for a category from the store
261
- */
262
- function getCategoryValues(category: SettingsCategory): Record<string, unknown> {
263
- const settings = getSettings();
264
- const categorySettings = settings[category];
265
- // Convert to Record<string, unknown> for SchemaForm compatibility
266
- return Object.fromEntries(Object.entries(categorySettings));
267
- }
268
-
269
- /**
270
- * Handle form value changes
271
- */
272
- function handleChange(category: SettingsCategory, values: Record<string, unknown>): void {
273
- // Update the store
274
- updateSettings({ [category]: values });
275
-
276
- // Notify parent if callback provided
277
- if (onSettingsChange) {
278
- onSettingsChange(category, values);
279
- }
280
- }
281
-
282
- /**
283
- * Handle sync to cloud button click
284
- */
285
- async function handleSync(): Promise<void> {
286
- try {
287
- await syncSettingsToApi();
288
- } catch (error) {
289
- logger.error('Failed to sync settings:', error);
290
- }
291
- }
292
-
293
- /**
294
- * Handle reset button click
295
- */
296
- function handleReset(): void {
297
- if (confirm(`Reset ${SETTINGS_CATEGORY_LABELS[activeTab]} settings to defaults?`)) {
298
- resetSettings([activeTab]);
299
- }
300
- }
301
-
302
- /**
303
- * Handle reset all button click
304
- */
305
- function handleResetAll(): void {
306
- if (confirm('Reset all settings to defaults?')) {
307
- resetSettings();
308
- }
309
- }
310
-
311
- /**
312
- * Handle tab keyboard navigation
313
- */
314
- function handleTabKeydown(event: KeyboardEvent, index: number): void {
315
- const tabs = categories;
316
- let newIndex = index;
317
-
318
- switch (event.key) {
319
- case 'ArrowLeft':
320
- newIndex = index > 0 ? index - 1 : tabs.length - 1;
321
- break;
322
- case 'ArrowRight':
323
- newIndex = index < tabs.length - 1 ? index + 1 : 0;
324
- break;
325
- case 'Home':
326
- newIndex = 0;
327
- break;
328
- case 'End':
329
- newIndex = tabs.length - 1;
330
- break;
331
- default:
332
- return;
333
- }
334
-
335
- event.preventDefault();
336
- activeTab = tabs[newIndex];
337
-
338
- // Focus the new tab
339
- const tabElement = document.querySelector(
340
- `[data-tab="${tabs[newIndex]}"]`
341
- ) as HTMLElement | null;
342
- tabElement?.focus();
343
- }
31
+ import Icon from "@iconify/svelte";
32
+ import { SchemaForm } from "../form/index.js";
33
+ import type { ConfigSchema } from "../types/index.js";
34
+ import type { SettingsCategory } from "../types/settings.js";
35
+ import {
36
+ SETTINGS_CATEGORIES,
37
+ SETTINGS_CATEGORY_LABELS,
38
+ SETTINGS_CATEGORY_ICONS,
39
+ } from "../types/settings.js";
40
+ import {
41
+ getSettings,
42
+ updateSettings,
43
+ resetSettings,
44
+ syncSettingsToApi,
45
+ getSyncStatus,
46
+ } from "../stores/settingsStore.svelte.js";
47
+ import { logger } from "../utils/logger.js";
48
+
49
+ /**
50
+ * Props interface for SettingsPanel component
51
+ */
52
+ interface Props {
53
+ /** Categories to display (defaults to all) */
54
+ categories?: SettingsCategory[];
55
+ /** Show the "Sync to Cloud" button */
56
+ showSyncButton?: boolean;
57
+ /** Show the reset button */
58
+ showResetButton?: boolean;
59
+ /** Callback when settings change */
60
+ onSettingsChange?: (
61
+ category: SettingsCategory,
62
+ values: Record<string, unknown>,
63
+ ) => void;
64
+ /** Callback when close is requested */
65
+ onClose?: () => void;
66
+ /** Custom CSS class */
67
+ class?: string;
68
+ }
69
+
70
+ const {
71
+ categories = SETTINGS_CATEGORIES,
72
+ showSyncButton = true,
73
+ showResetButton = true,
74
+ onSettingsChange,
75
+ onClose,
76
+ class: className = "",
77
+ }: Props = $props();
78
+
79
+ /**
80
+ * Currently active tab
81
+ */
82
+ // svelte-ignore state_referenced_locally — initial default, user switches tabs
83
+ let activeTab = $state<SettingsCategory>(categories[0] ?? "theme");
84
+
85
+ /**
86
+ * Whether sync is in progress
87
+ */
88
+ let isSyncing = $derived(getSyncStatus().status === "syncing");
89
+
90
+ /**
91
+ * JSON Schema definitions for each settings category
92
+ */
93
+ const schemas: Record<SettingsCategory, ConfigSchema> = {
94
+ theme: {
95
+ type: "object",
96
+ properties: {
97
+ preference: {
98
+ type: "string",
99
+ title: "Theme Preference",
100
+ description: "Choose your preferred color scheme",
101
+ oneOf: [
102
+ { const: "light", title: "Light" },
103
+ { const: "dark", title: "Dark" },
104
+ { const: "auto", title: "Auto (System)" },
105
+ ],
106
+ default: "auto",
107
+ },
108
+ },
109
+ },
110
+ editor: {
111
+ type: "object",
112
+ properties: {
113
+ showGrid: {
114
+ type: "boolean",
115
+ title: "Show Grid",
116
+ description: "Display grid lines on the canvas",
117
+ default: true,
118
+ },
119
+ snapToGrid: {
120
+ type: "boolean",
121
+ title: "Snap to Grid",
122
+ description: "Snap nodes to grid when dragging",
123
+ default: true,
124
+ },
125
+ gridSize: {
126
+ type: "number",
127
+ title: "Grid Size",
128
+ description: "Grid cell size in pixels",
129
+ minimum: 5,
130
+ maximum: 50,
131
+ default: 20,
132
+ },
133
+ showMinimap: {
134
+ type: "boolean",
135
+ title: "Show Minimap",
136
+ description: "Display navigation minimap",
137
+ default: true,
138
+ },
139
+ defaultZoom: {
140
+ type: "number",
141
+ title: "Default Zoom",
142
+ description: "Initial zoom level (1 = 100%)",
143
+ minimum: 0.25,
144
+ maximum: 2,
145
+ default: 1,
146
+ },
147
+ fitViewOnLoad: {
148
+ type: "boolean",
149
+ title: "Fit View on Load",
150
+ description: "Automatically fit workflow to view when loading",
151
+ default: true,
152
+ },
153
+ proximityConnect: {
154
+ type: "boolean",
155
+ title: "Proximity Connect",
156
+ description:
157
+ "Auto-connect compatible ports when dragging nodes near each other",
158
+ default: false,
159
+ },
160
+ proximityConnectDistance: {
161
+ type: "number",
162
+ title: "Proximity Distance",
163
+ description: "Distance threshold in pixels for proximity connect",
164
+ minimum: 50,
165
+ maximum: 500,
166
+ default: 150,
167
+ },
168
+ },
169
+ },
170
+ ui: {
171
+ type: "object",
172
+ properties: {
173
+ sidebarWidth: {
174
+ type: "number",
175
+ title: "Sidebar Width",
176
+ description: "Width of the node sidebar in pixels",
177
+ minimum: 200,
178
+ maximum: 500,
179
+ default: 280,
180
+ },
181
+ sidebarCollapsed: {
182
+ type: "boolean",
183
+ title: "Sidebar Collapsed",
184
+ description: "Start with sidebar collapsed",
185
+ default: false,
186
+ },
187
+ compactMode: {
188
+ type: "boolean",
189
+ title: "Compact Mode",
190
+ description: "Use compact UI with smaller spacing",
191
+ default: false,
192
+ },
193
+ theme: {
194
+ type: "string",
195
+ title: "UI Theme",
196
+ description: "Visual style and layout of the editor",
197
+ oneOf: [
198
+ { const: "default", title: "Default" },
199
+ { const: "minimal", title: "Minimal" },
200
+ ],
201
+ default: "default",
202
+ },
203
+ },
204
+ },
205
+ behavior: {
206
+ type: "object",
207
+ properties: {
208
+ autoSave: {
209
+ type: "boolean",
210
+ title: "Auto Save",
211
+ description: "Automatically save changes",
212
+ default: false,
213
+ },
214
+ autoSaveInterval: {
215
+ type: "number",
216
+ title: "Auto Save Interval",
217
+ description: "Time between auto-saves in milliseconds",
218
+ minimum: 5000,
219
+ maximum: 300000,
220
+ default: 30000,
221
+ },
222
+ undoHistoryLimit: {
223
+ type: "number",
224
+ title: "Undo History Limit",
225
+ description: "Maximum number of undo steps (0 to disable)",
226
+ minimum: 0,
227
+ maximum: 200,
228
+ default: 0,
229
+ },
230
+ confirmDelete: {
231
+ type: "boolean",
232
+ title: "Confirm Delete",
233
+ description: "Show confirmation before deleting nodes",
234
+ default: true,
235
+ },
236
+ },
237
+ },
238
+ api: {
239
+ type: "object",
240
+ properties: {
241
+ timeout: {
242
+ type: "number",
243
+ title: "Request Timeout",
244
+ description: "API request timeout in milliseconds",
245
+ minimum: 5000,
246
+ maximum: 120000,
247
+ default: 30000,
248
+ },
249
+ retryEnabled: {
250
+ type: "boolean",
251
+ title: "Enable Retry",
252
+ description: "Automatically retry failed requests",
253
+ default: true,
254
+ },
255
+ retryAttempts: {
256
+ type: "number",
257
+ title: "Retry Attempts",
258
+ description: "Maximum number of retry attempts",
259
+ minimum: 1,
260
+ maximum: 10,
261
+ default: 3,
262
+ },
263
+ cacheEnabled: {
264
+ type: "boolean",
265
+ title: "Enable Caching",
266
+ description: "Cache API responses for better performance",
267
+ default: true,
268
+ },
269
+ },
270
+ },
271
+ };
272
+
273
+ /**
274
+ * Get current values for a category from the store
275
+ */
276
+ function getCategoryValues(
277
+ category: SettingsCategory,
278
+ ): Record<string, unknown> {
279
+ const settings = getSettings();
280
+ const categorySettings = settings[category];
281
+ // Convert to Record<string, unknown> for SchemaForm compatibility
282
+ return Object.fromEntries(Object.entries(categorySettings));
283
+ }
284
+
285
+ /**
286
+ * Handle form value changes
287
+ */
288
+ function handleChange(
289
+ category: SettingsCategory,
290
+ values: Record<string, unknown>,
291
+ ): void {
292
+ // Update the store
293
+ updateSettings({ [category]: values });
294
+
295
+ // Notify parent if callback provided
296
+ if (onSettingsChange) {
297
+ onSettingsChange(category, values);
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Handle sync to cloud button click
303
+ */
304
+ async function handleSync(): Promise<void> {
305
+ try {
306
+ await syncSettingsToApi();
307
+ } catch (error) {
308
+ logger.error("Failed to sync settings:", error);
309
+ }
310
+ }
311
+
312
+ /**
313
+ * Handle reset button click
314
+ */
315
+ function handleReset(): void {
316
+ if (
317
+ confirm(
318
+ `Reset ${SETTINGS_CATEGORY_LABELS[activeTab]} settings to defaults?`,
319
+ )
320
+ ) {
321
+ resetSettings([activeTab]);
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Handle reset all button click
327
+ */
328
+ function handleResetAll(): void {
329
+ if (confirm("Reset all settings to defaults?")) {
330
+ resetSettings();
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Handle tab keyboard navigation
336
+ */
337
+ function handleTabKeydown(event: KeyboardEvent, index: number): void {
338
+ const tabs = categories;
339
+ let newIndex = index;
340
+
341
+ switch (event.key) {
342
+ case "ArrowLeft":
343
+ newIndex = index > 0 ? index - 1 : tabs.length - 1;
344
+ break;
345
+ case "ArrowRight":
346
+ newIndex = index < tabs.length - 1 ? index + 1 : 0;
347
+ break;
348
+ case "Home":
349
+ newIndex = 0;
350
+ break;
351
+ case "End":
352
+ newIndex = tabs.length - 1;
353
+ break;
354
+ default:
355
+ return;
356
+ }
357
+
358
+ event.preventDefault();
359
+ activeTab = tabs[newIndex];
360
+
361
+ // Focus the new tab
362
+ const tabElement = document.querySelector(
363
+ `[data-tab="${tabs[newIndex]}"]`,
364
+ ) as HTMLElement | null;
365
+ tabElement?.focus();
366
+ }
344
367
  </script>
345
368
 
346
369
  <div class="flowdrop-settings-panel {className}">
347
- <!-- Tab Navigation -->
348
- <div class="flowdrop-settings-panel__tabs" role="tablist" aria-label="Settings categories">
349
- {#each categories as category, index (category)}
350
- <button
351
- class="flowdrop-settings-panel__tab"
352
- class:flowdrop-settings-panel__tab--active={activeTab === category}
353
- role="tab"
354
- aria-selected={activeTab === category}
355
- aria-controls="panel-{category}"
356
- data-tab={category}
357
- tabindex={activeTab === category ? 0 : -1}
358
- onclick={() => (activeTab = category)}
359
- onkeydown={(e) => handleTabKeydown(e, index)}
360
- >
361
- <Icon icon={SETTINGS_CATEGORY_ICONS[category]} class="flowdrop-settings-panel__tab-icon" />
362
- <span class="flowdrop-settings-panel__tab-label">{SETTINGS_CATEGORY_LABELS[category]}</span>
363
- </button>
364
- {/each}
365
- </div>
366
-
367
- <!-- Tab Panels -->
368
- <div class="flowdrop-settings-panel__content">
369
- {#each categories as category (category)}
370
- <div
371
- id="panel-{category}"
372
- class="flowdrop-settings-panel__panel"
373
- class:flowdrop-settings-panel__panel--active={activeTab === category}
374
- role="tabpanel"
375
- aria-labelledby="tab-{category}"
376
- hidden={activeTab !== category}
377
- >
378
- {#if activeTab === category}
379
- <SchemaForm
380
- schema={schemas[category]}
381
- values={getCategoryValues(category)}
382
- onChange={(values) => handleChange(category, values)}
383
- showActions={false}
384
- />
385
- {/if}
386
- </div>
387
- {/each}
388
- </div>
389
-
390
- <!-- Footer Actions -->
391
- <div class="flowdrop-settings-panel__footer">
392
- <div class="flowdrop-settings-panel__footer-start">
393
- {#if showResetButton}
394
- <button
395
- class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--outline"
396
- onclick={handleReset}
397
- title="Reset current category to defaults"
398
- >
399
- <Icon icon="mdi:refresh" />
400
- <span>Reset</span>
401
- </button>
402
- <button
403
- class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--ghost"
404
- onclick={handleResetAll}
405
- title="Reset all settings to defaults"
406
- >
407
- Reset All
408
- </button>
409
- {/if}
410
- </div>
411
-
412
- <div class="flowdrop-settings-panel__footer-end">
413
- {#if showSyncButton}
414
- <button
415
- class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--secondary"
416
- onclick={handleSync}
417
- disabled={isSyncing}
418
- title="Sync settings to cloud"
419
- >
420
- {#if isSyncing}
421
- <Icon icon="mdi:loading" class="flowdrop-settings-panel__spin" />
422
- <span>Syncing...</span>
423
- {:else}
424
- <Icon icon="mdi:cloud-upload" />
425
- <span>Sync to Cloud</span>
426
- {/if}
427
- </button>
428
- {/if}
429
-
430
- {#if onClose}
431
- <button
432
- class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--primary"
433
- onclick={onClose}
434
- >
435
- <span>Close</span>
436
- </button>
437
- {/if}
438
- </div>
439
- </div>
440
-
441
- <!-- Sync Status Indicator -->
442
- {#if getSyncStatus().error}
443
- <div class="flowdrop-settings-panel__error">
444
- <Icon icon="mdi:alert-circle" />
445
- <span>{getSyncStatus().error}</span>
446
- </div>
447
- {:else if getSyncStatus().status === 'synced' && getSyncStatus().lastSyncedAt}
448
- <div class="flowdrop-settings-panel__synced">
449
- <Icon icon="mdi:check-circle" />
450
- <span>Synced {new Date(getSyncStatus().lastSyncedAt!).toLocaleTimeString()}</span>
451
- </div>
452
- {/if}
370
+ <!-- Tab Navigation -->
371
+ <div
372
+ class="flowdrop-settings-panel__tabs"
373
+ role="tablist"
374
+ aria-label="Settings categories"
375
+ >
376
+ {#each categories as category, index (category)}
377
+ <button
378
+ class="flowdrop-settings-panel__tab"
379
+ class:flowdrop-settings-panel__tab--active={activeTab === category}
380
+ role="tab"
381
+ aria-selected={activeTab === category}
382
+ aria-controls="panel-{category}"
383
+ data-tab={category}
384
+ tabindex={activeTab === category ? 0 : -1}
385
+ onclick={() => (activeTab = category)}
386
+ onkeydown={(e) => handleTabKeydown(e, index)}
387
+ >
388
+ <Icon
389
+ icon={SETTINGS_CATEGORY_ICONS[category]}
390
+ class="flowdrop-settings-panel__tab-icon"
391
+ />
392
+ <span class="flowdrop-settings-panel__tab-label"
393
+ >{SETTINGS_CATEGORY_LABELS[category]}</span
394
+ >
395
+ </button>
396
+ {/each}
397
+ </div>
398
+
399
+ <!-- Tab Panels -->
400
+ <div class="flowdrop-settings-panel__content">
401
+ {#each categories as category (category)}
402
+ <div
403
+ id="panel-{category}"
404
+ class="flowdrop-settings-panel__panel"
405
+ class:flowdrop-settings-panel__panel--active={activeTab === category}
406
+ role="tabpanel"
407
+ aria-labelledby="tab-{category}"
408
+ hidden={activeTab !== category}
409
+ >
410
+ {#if activeTab === category}
411
+ <SchemaForm
412
+ schema={schemas[category]}
413
+ values={getCategoryValues(category)}
414
+ onChange={(values) => handleChange(category, values)}
415
+ showActions={false}
416
+ />
417
+ {/if}
418
+ </div>
419
+ {/each}
420
+ </div>
421
+
422
+ <!-- Footer Actions -->
423
+ <div class="flowdrop-settings-panel__footer">
424
+ <div class="flowdrop-settings-panel__footer-start">
425
+ {#if showResetButton}
426
+ <button
427
+ class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--outline"
428
+ onclick={handleReset}
429
+ title="Reset current category to defaults"
430
+ >
431
+ <Icon icon="mdi:refresh" />
432
+ <span>Reset</span>
433
+ </button>
434
+ <button
435
+ class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--ghost"
436
+ onclick={handleResetAll}
437
+ title="Reset all settings to defaults"
438
+ >
439
+ Reset All
440
+ </button>
441
+ {/if}
442
+ </div>
443
+
444
+ <div class="flowdrop-settings-panel__footer-end">
445
+ {#if showSyncButton}
446
+ <button
447
+ class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--secondary"
448
+ onclick={handleSync}
449
+ disabled={isSyncing}
450
+ title="Sync settings to cloud"
451
+ >
452
+ {#if isSyncing}
453
+ <Icon icon="mdi:loading" class="flowdrop-settings-panel__spin" />
454
+ <span>Syncing...</span>
455
+ {:else}
456
+ <Icon icon="mdi:cloud-upload" />
457
+ <span>Sync to Cloud</span>
458
+ {/if}
459
+ </button>
460
+ {/if}
461
+
462
+ {#if onClose}
463
+ <button
464
+ class="flowdrop-settings-panel__btn flowdrop-settings-panel__btn--primary"
465
+ onclick={onClose}
466
+ >
467
+ <span>Close</span>
468
+ </button>
469
+ {/if}
470
+ </div>
471
+ </div>
472
+
473
+ <!-- Sync Status Indicator -->
474
+ {#if getSyncStatus().error}
475
+ <div class="flowdrop-settings-panel__error">
476
+ <Icon icon="mdi:alert-circle" />
477
+ <span>{getSyncStatus().error}</span>
478
+ </div>
479
+ {:else if getSyncStatus().status === "synced" && getSyncStatus().lastSyncedAt}
480
+ <div class="flowdrop-settings-panel__synced">
481
+ <Icon icon="mdi:check-circle" />
482
+ <span
483
+ >Synced {new Date(
484
+ getSyncStatus().lastSyncedAt!,
485
+ ).toLocaleTimeString()}</span
486
+ >
487
+ </div>
488
+ {/if}
453
489
  </div>
454
490
 
455
491
  <style>
456
- .flowdrop-settings-panel {
457
- display: flex;
458
- flex-direction: column;
459
- height: 100%;
460
- background-color: var(--fd-background);
461
- color: var(--fd-foreground);
462
- }
463
-
464
- /* Tabs */
465
- .flowdrop-settings-panel__tabs {
466
- display: flex;
467
- gap: var(--fd-space-3xs);
468
- padding: var(--fd-space-md);
469
- border-bottom: 1px solid var(--fd-border);
470
- overflow-x: auto;
471
- }
472
-
473
- .flowdrop-settings-panel__tab {
474
- display: flex;
475
- align-items: center;
476
- gap: var(--fd-space-xs);
477
- padding: var(--fd-space-xs) var(--fd-space-md);
478
- border: none;
479
- border-radius: var(--fd-radius-md);
480
- background-color: transparent;
481
- color: var(--fd-muted-foreground);
482
- font-size: var(--fd-text-sm);
483
- font-weight: 500;
484
- cursor: pointer;
485
- transition: all var(--fd-transition-fast);
486
- white-space: nowrap;
487
- }
488
-
489
- .flowdrop-settings-panel__tab:hover {
490
- background-color: var(--fd-muted);
491
- color: var(--fd-foreground);
492
- }
493
-
494
- .flowdrop-settings-panel__tab--active {
495
- background-color: var(--fd-primary);
496
- color: var(--fd-primary-foreground);
497
- }
498
-
499
- .flowdrop-settings-panel__tab--active:hover {
500
- background-color: var(--fd-primary);
501
- color: var(--fd-primary-foreground);
502
- }
503
-
504
- .flowdrop-settings-panel__tab:focus {
505
- outline: none;
506
- box-shadow: 0 0 0 2px var(--fd-ring);
507
- }
508
-
509
- :global(.flowdrop-settings-panel__tab-icon) {
510
- font-size: var(--fd-text-base);
511
- }
512
-
513
- /* Content */
514
- .flowdrop-settings-panel__content {
515
- flex: 1;
516
- overflow-y: auto;
517
- padding: var(--fd-space-xl);
518
- }
519
-
520
- .flowdrop-settings-panel__panel {
521
- display: none;
522
- }
523
-
524
- .flowdrop-settings-panel__panel--active {
525
- display: block;
526
- }
527
-
528
- /* Footer */
529
- .flowdrop-settings-panel__footer {
530
- display: flex;
531
- justify-content: space-between;
532
- align-items: center;
533
- padding: var(--fd-space-md) var(--fd-space-xl);
534
- border-top: 1px solid var(--fd-border);
535
- gap: var(--fd-space-md);
536
- }
537
-
538
- .flowdrop-settings-panel__footer-start,
539
- .flowdrop-settings-panel__footer-end {
540
- display: flex;
541
- gap: var(--fd-space-xs);
542
- align-items: center;
543
- }
544
-
545
- /* Buttons */
546
- .flowdrop-settings-panel__btn {
547
- display: inline-flex;
548
- align-items: center;
549
- gap: var(--fd-space-xs);
550
- padding: var(--fd-space-xs) var(--fd-space-md);
551
- border-radius: var(--fd-radius-md);
552
- font-size: var(--fd-text-sm);
553
- font-weight: 500;
554
- cursor: pointer;
555
- transition: all var(--fd-transition-fast);
556
- border: 1px solid transparent;
557
- }
558
-
559
- .flowdrop-settings-panel__btn:disabled {
560
- opacity: 0.5;
561
- cursor: not-allowed;
562
- }
563
-
564
- .flowdrop-settings-panel__btn--primary {
565
- background-color: var(--fd-primary);
566
- color: var(--fd-primary-foreground);
567
- border-color: var(--fd-primary);
568
- }
569
-
570
- .flowdrop-settings-panel__btn--primary:hover:not(:disabled) {
571
- opacity: 0.9;
572
- }
573
-
574
- .flowdrop-settings-panel__btn--secondary {
575
- background-color: var(--fd-secondary);
576
- color: var(--fd-secondary-foreground);
577
- border-color: var(--fd-border);
578
- }
579
-
580
- .flowdrop-settings-panel__btn--secondary:hover:not(:disabled) {
581
- background-color: var(--fd-muted);
582
- }
583
-
584
- .flowdrop-settings-panel__btn--outline {
585
- background-color: transparent;
586
- color: var(--fd-foreground);
587
- border-color: var(--fd-border);
588
- }
589
-
590
- .flowdrop-settings-panel__btn--outline:hover:not(:disabled) {
591
- background-color: var(--fd-muted);
592
- }
593
-
594
- .flowdrop-settings-panel__btn--ghost {
595
- background-color: transparent;
596
- color: var(--fd-muted-foreground);
597
- border-color: transparent;
598
- }
599
-
600
- .flowdrop-settings-panel__btn--ghost:hover:not(:disabled) {
601
- background-color: var(--fd-muted);
602
- color: var(--fd-foreground);
603
- }
604
-
605
- /* Status Indicators */
606
- .flowdrop-settings-panel__error,
607
- .flowdrop-settings-panel__synced {
608
- display: flex;
609
- align-items: center;
610
- gap: var(--fd-space-xs);
611
- padding: var(--fd-space-xs) var(--fd-space-xl);
612
- font-size: var(--fd-text-xs);
613
- }
614
-
615
- .flowdrop-settings-panel__error {
616
- background-color: var(--fd-destructive);
617
- color: var(--fd-destructive-foreground);
618
- }
619
-
620
- .flowdrop-settings-panel__synced {
621
- background-color: var(--fd-success, #22c55e);
622
- color: white;
623
- }
624
-
625
- /* Spin Animation */
626
- :global(.flowdrop-settings-panel__spin) {
627
- animation: flowdrop-spin 1s linear infinite;
628
- }
629
-
630
- @keyframes flowdrop-spin {
631
- from {
632
- transform: rotate(0deg);
633
- }
634
- to {
635
- transform: rotate(360deg);
636
- }
637
- }
492
+ .flowdrop-settings-panel {
493
+ display: flex;
494
+ flex-direction: column;
495
+ height: 100%;
496
+ background-color: var(--fd-background);
497
+ color: var(--fd-foreground);
498
+ }
499
+
500
+ /* Tabs */
501
+ .flowdrop-settings-panel__tabs {
502
+ display: flex;
503
+ gap: var(--fd-space-3xs);
504
+ padding: var(--fd-space-md);
505
+ border-bottom: 1px solid var(--fd-border);
506
+ overflow-x: auto;
507
+ }
508
+
509
+ .flowdrop-settings-panel__tab {
510
+ display: flex;
511
+ align-items: center;
512
+ gap: var(--fd-space-xs);
513
+ padding: var(--fd-space-xs) var(--fd-space-md);
514
+ border: none;
515
+ border-radius: var(--fd-radius-md);
516
+ background-color: transparent;
517
+ color: var(--fd-muted-foreground);
518
+ font-size: var(--fd-text-sm);
519
+ font-weight: 500;
520
+ cursor: pointer;
521
+ transition: all var(--fd-transition-fast);
522
+ white-space: nowrap;
523
+ }
524
+
525
+ .flowdrop-settings-panel__tab:hover {
526
+ background-color: var(--fd-muted);
527
+ color: var(--fd-foreground);
528
+ }
529
+
530
+ .flowdrop-settings-panel__tab--active {
531
+ background-color: var(--fd-primary);
532
+ color: var(--fd-primary-foreground);
533
+ }
534
+
535
+ .flowdrop-settings-panel__tab--active:hover {
536
+ background-color: var(--fd-primary);
537
+ color: var(--fd-primary-foreground);
538
+ }
539
+
540
+ .flowdrop-settings-panel__tab:focus {
541
+ outline: none;
542
+ box-shadow: 0 0 0 2px var(--fd-ring);
543
+ }
544
+
545
+ :global(.flowdrop-settings-panel__tab-icon) {
546
+ font-size: var(--fd-text-base);
547
+ }
548
+
549
+ /* Content */
550
+ .flowdrop-settings-panel__content {
551
+ flex: 1;
552
+ overflow-y: auto;
553
+ padding: var(--fd-space-xl);
554
+ }
555
+
556
+ .flowdrop-settings-panel__panel {
557
+ display: none;
558
+ }
559
+
560
+ .flowdrop-settings-panel__panel--active {
561
+ display: block;
562
+ }
563
+
564
+ /* Footer */
565
+ .flowdrop-settings-panel__footer {
566
+ display: flex;
567
+ justify-content: space-between;
568
+ align-items: center;
569
+ padding: var(--fd-space-md) var(--fd-space-xl);
570
+ border-top: 1px solid var(--fd-border);
571
+ gap: var(--fd-space-md);
572
+ }
573
+
574
+ .flowdrop-settings-panel__footer-start,
575
+ .flowdrop-settings-panel__footer-end {
576
+ display: flex;
577
+ gap: var(--fd-space-xs);
578
+ align-items: center;
579
+ }
580
+
581
+ /* Buttons */
582
+ .flowdrop-settings-panel__btn {
583
+ display: inline-flex;
584
+ align-items: center;
585
+ gap: var(--fd-space-xs);
586
+ padding: var(--fd-space-xs) var(--fd-space-md);
587
+ border-radius: var(--fd-radius-md);
588
+ font-size: var(--fd-text-sm);
589
+ font-weight: 500;
590
+ cursor: pointer;
591
+ transition: all var(--fd-transition-fast);
592
+ border: 1px solid transparent;
593
+ }
594
+
595
+ .flowdrop-settings-panel__btn:disabled {
596
+ opacity: 0.5;
597
+ cursor: not-allowed;
598
+ }
599
+
600
+ .flowdrop-settings-panel__btn--primary {
601
+ background-color: var(--fd-primary);
602
+ color: var(--fd-primary-foreground);
603
+ border-color: var(--fd-primary);
604
+ }
605
+
606
+ .flowdrop-settings-panel__btn--primary:hover:not(:disabled) {
607
+ opacity: 0.9;
608
+ }
609
+
610
+ .flowdrop-settings-panel__btn--secondary {
611
+ background-color: var(--fd-secondary);
612
+ color: var(--fd-secondary-foreground);
613
+ border-color: var(--fd-border);
614
+ }
615
+
616
+ .flowdrop-settings-panel__btn--secondary:hover:not(:disabled) {
617
+ background-color: var(--fd-muted);
618
+ }
619
+
620
+ .flowdrop-settings-panel__btn--outline {
621
+ background-color: transparent;
622
+ color: var(--fd-foreground);
623
+ border-color: var(--fd-border);
624
+ }
625
+
626
+ .flowdrop-settings-panel__btn--outline:hover:not(:disabled) {
627
+ background-color: var(--fd-muted);
628
+ }
629
+
630
+ .flowdrop-settings-panel__btn--ghost {
631
+ background-color: transparent;
632
+ color: var(--fd-muted-foreground);
633
+ border-color: transparent;
634
+ }
635
+
636
+ .flowdrop-settings-panel__btn--ghost:hover:not(:disabled) {
637
+ background-color: var(--fd-muted);
638
+ color: var(--fd-foreground);
639
+ }
640
+
641
+ /* Status Indicators */
642
+ .flowdrop-settings-panel__error,
643
+ .flowdrop-settings-panel__synced {
644
+ display: flex;
645
+ align-items: center;
646
+ gap: var(--fd-space-xs);
647
+ padding: var(--fd-space-xs) var(--fd-space-xl);
648
+ font-size: var(--fd-text-xs);
649
+ }
650
+
651
+ .flowdrop-settings-panel__error {
652
+ background-color: var(--fd-destructive);
653
+ color: var(--fd-destructive-foreground);
654
+ }
655
+
656
+ .flowdrop-settings-panel__synced {
657
+ background-color: var(--fd-success, #22c55e);
658
+ color: white;
659
+ }
660
+
661
+ /* Spin Animation */
662
+ :global(.flowdrop-settings-panel__spin) {
663
+ animation: flowdrop-spin 1s linear infinite;
664
+ }
665
+
666
+ @keyframes flowdrop-spin {
667
+ from {
668
+ transform: rotate(0deg);
669
+ }
670
+ to {
671
+ transform: rotate(360deg);
672
+ }
673
+ }
638
674
  </style>