@dfosco/storyboard-core 4.2.0-beta.2 → 4.2.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commandpalette.config.json +109 -24
- package/dist/storyboard-ui.css +1 -1
- package/dist/storyboard-ui.js +17379 -28568
- package/dist/storyboard-ui.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +5 -2
- package/scaffold/agents/prompt-agent.agent.md +181 -0
- package/scaffold/agents/terminal-agent.agent.md +351 -0
- package/scaffold/codex/config.toml +246 -0
- package/scaffold/manifest.json +5 -0
- package/scaffold/skills/canvas/SKILL.md +5 -4
- package/scaffold/skills/ship/SKILL.md +1 -1
- package/scaffold/storyboard.config.json +14 -1
- package/scaffold/toolbar.config.json +1 -1
- package/src/ActionMenuButton.jsx +100 -0
- package/src/AutosyncMenuButton.css +67 -0
- package/src/AutosyncMenuButton.jsx +241 -0
- package/src/BranchSelect.jsx +29 -0
- package/src/BranchSelect.module.css +30 -0
- package/src/CanvasAgentsMenu.jsx +87 -0
- package/src/CanvasCreateMenu.jsx +609 -0
- package/src/CanvasSnap.css +27 -0
- package/src/CanvasSnap.jsx +51 -0
- package/src/CanvasUndoRedo.css +36 -0
- package/src/CanvasUndoRedo.jsx +62 -0
- package/src/CanvasZoomControl.css +53 -0
- package/src/CanvasZoomControl.jsx +49 -0
- package/src/CanvasZoomToFit.css +18 -0
- package/src/CanvasZoomToFit.jsx +26 -0
- package/src/CommandMenu.css +8 -0
- package/src/CommandMenu.jsx +286 -0
- package/src/CommandPalette.jsx +35 -0
- package/src/CommandPaletteTrigger.jsx +25 -0
- package/src/CommentsMenuButton.jsx +38 -0
- package/src/CoreUIBar.css +47 -0
- package/src/CoreUIBar.jsx +855 -0
- package/src/CreateMenuButton.jsx +116 -0
- package/src/HideChromeTrigger.jsx +40 -0
- package/src/InspectorPanel.css +109 -0
- package/src/InspectorPanel.jsx +629 -0
- package/src/PwaInstallBanner.css +42 -0
- package/src/PwaInstallBanner.jsx +124 -0
- package/src/SidePanel.jsx +260 -0
- package/src/ThemeMenuButton.jsx +136 -0
- package/src/autosync/server.js +202 -5
- package/src/autosync/server.test.js +112 -0
- package/src/canvas/__tests__/agent-integration.test.js +593 -0
- package/src/canvas/__tests__/helpers/browser.js +95 -0
- package/src/canvas/__tests__/helpers/canvas-api.js +129 -0
- package/src/canvas/__tests__/helpers/perf.js +118 -0
- package/src/canvas/__tests__/helpers/setup.js +176 -0
- package/src/canvas/__tests__/helpers/tmux.js +130 -0
- package/src/canvas/__tests__/helpers/transcript.js +129 -0
- package/src/canvas/__tests__/terminal-integration.test.js +175 -0
- package/src/canvas/hot-pool.js +757 -0
- package/src/canvas/materializer.js +31 -0
- package/src/canvas/materializer.test.js +56 -0
- package/src/canvas/selectedWidgets.js +65 -7
- package/src/canvas/server.js +1801 -22
- package/src/canvas/server.test.js +239 -0
- package/src/canvas/terminal-config.js +331 -0
- package/src/canvas/terminal-registry.js +38 -0
- package/src/canvas/terminal-server.js +1037 -29
- package/src/canvas/writeGuard.js +51 -3
- package/src/canvasConfig.js +67 -1
- package/src/canvasConfig.test.js +79 -1
- package/src/cli/agent.js +85 -0
- package/src/cli/branch.js +232 -0
- package/src/cli/canvasAdd.js +59 -12
- package/src/cli/canvasBatch.js +98 -0
- package/src/cli/canvasBounds.js +1 -1
- package/src/cli/canvasRead.js +1 -1
- package/src/cli/canvasUpdate.js +179 -0
- package/src/cli/create.js +38 -14
- package/src/cli/dev.js +157 -83
- package/src/cli/exit.js +23 -24
- package/src/cli/index.js +55 -2
- package/src/cli/proxy.js +96 -37
- package/src/cli/schemas.js +22 -4
- package/src/cli/server.js +148 -25
- package/src/cli/serverUrl.js +8 -3
- package/src/cli/sessions.js +131 -5
- package/src/cli/setup.js +109 -11
- package/src/cli/terminal-commands.js +16 -8
- package/src/cli/terminal-messaging.js +231 -0
- package/src/cli/terminal-welcome.js +365 -33
- package/src/commandActions.js +1 -0
- package/src/commandPaletteConfig.js +9 -0
- package/src/comments/auth.js +2 -1
- package/src/comments/ui/AuthModal.jsx +114 -0
- package/src/comments/ui/CommentWindow.jsx +329 -0
- package/src/comments/ui/CommentsDrawer.jsx +102 -0
- package/src/comments/ui/Composer.jsx +64 -0
- package/src/comments/ui/authModal.test.js +1 -1
- package/src/comments/ui/commentWindow.js +16 -17
- package/src/comments/ui/commentsDrawer.js +25 -26
- package/src/comments/ui/composer.js +23 -24
- package/src/comments/ui/index.js +2 -3
- package/src/configSchema.js +59 -1
- package/src/configStore.js +161 -0
- package/src/core-ui-colors.css +12 -0
- package/src/devtools.js +17 -19
- package/src/devtools.test.js +18 -9
- package/src/featureFlags.js +12 -5
- package/src/fuzzySearch.test.js +10 -0
- package/src/index.js +14 -2
- package/src/lib/components/ui/alert/alert-action.jsx +11 -0
- package/src/lib/components/ui/alert/alert-description.jsx +11 -0
- package/src/lib/components/ui/alert/alert-title.jsx +11 -0
- package/src/lib/components/ui/alert/alert.jsx +25 -0
- package/src/lib/components/ui/alert/index.js +15 -15
- package/src/lib/components/ui/avatar/avatar-badge.jsx +22 -0
- package/src/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
- package/src/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
- package/src/lib/components/ui/avatar/avatar-group.jsx +19 -0
- package/src/lib/components/ui/avatar/avatar-image.jsx +15 -0
- package/src/lib/components/ui/avatar/avatar.jsx +19 -0
- package/src/lib/components/ui/avatar/index.js +20 -20
- package/src/lib/components/ui/badge/badge.jsx +31 -0
- package/src/lib/components/ui/badge/index.js +2 -2
- package/src/lib/components/ui/button/button.jsx +100 -0
- package/src/lib/components/ui/button/index.js +9 -9
- package/src/lib/components/ui/card/card-action.jsx +11 -0
- package/src/lib/components/ui/card/card-content.jsx +11 -0
- package/src/lib/components/ui/card/card-description.jsx +11 -0
- package/src/lib/components/ui/card/card-footer.jsx +11 -0
- package/src/lib/components/ui/card/card-header.jsx +19 -0
- package/src/lib/components/ui/card/card-title.jsx +11 -0
- package/src/lib/components/ui/card/card.jsx +17 -0
- package/src/lib/components/ui/card/index.js +23 -23
- package/src/lib/components/ui/checkbox/checkbox.jsx +29 -0
- package/src/lib/components/ui/checkbox/index.js +5 -5
- package/src/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
- package/src/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
- package/src/lib/components/ui/collapsible/collapsible.jsx +7 -0
- package/src/lib/components/ui/collapsible/index.js +11 -11
- package/src/lib/components/ui/dialog/dialog-close.jsx +7 -0
- package/src/lib/components/ui/dialog/dialog-content.jsx +34 -0
- package/src/lib/components/ui/dialog/dialog-description.jsx +15 -0
- package/src/lib/components/ui/dialog/dialog-footer.jsx +23 -0
- package/src/lib/components/ui/dialog/dialog-header.jsx +11 -0
- package/src/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
- package/src/lib/components/ui/dialog/dialog-portal.jsx +4 -0
- package/src/lib/components/ui/dialog/dialog-title.jsx +15 -0
- package/src/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
- package/src/lib/components/ui/dialog/dialog.jsx +4 -0
- package/src/lib/components/ui/dialog/index.js +32 -32
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
- package/src/lib/components/ui/dropdown-menu/index.js +52 -52
- package/src/lib/components/ui/input/index.js +5 -5
- package/src/lib/components/ui/input/input.jsx +19 -0
- package/src/lib/components/ui/label/index.js +5 -5
- package/src/lib/components/ui/label/label.jsx +19 -0
- package/src/lib/components/ui/panel/index.js +21 -21
- package/src/lib/components/ui/panel/panel-body.jsx +11 -0
- package/src/lib/components/ui/panel/panel-close.jsx +16 -0
- package/src/lib/components/ui/panel/panel-content.jsx +29 -0
- package/src/lib/components/ui/panel/panel-footer.jsx +11 -0
- package/src/lib/components/ui/panel/panel-header.jsx +11 -0
- package/src/lib/components/ui/panel/panel-title.jsx +12 -0
- package/src/lib/components/ui/panel/panel.jsx +4 -0
- package/src/lib/components/ui/popover/index.js +26 -26
- package/src/lib/components/ui/popover/popover-close.jsx +7 -0
- package/src/lib/components/ui/popover/popover-content.jsx +22 -0
- package/src/lib/components/ui/popover/popover-description.jsx +11 -0
- package/src/lib/components/ui/popover/popover-header.jsx +11 -0
- package/src/lib/components/ui/popover/popover-portal.jsx +4 -0
- package/src/lib/components/ui/popover/popover-title.jsx +11 -0
- package/src/lib/components/ui/popover/popover-trigger.jsx +8 -0
- package/src/lib/components/ui/popover/popover.jsx +4 -0
- package/src/lib/components/ui/searchable-list.jsx +159 -0
- package/src/lib/components/ui/select/index.js +35 -35
- package/src/lib/components/ui/select/select-content.jsx +30 -0
- package/src/lib/components/ui/select/select-group-heading.jsx +17 -0
- package/src/lib/components/ui/select/select-group.jsx +15 -0
- package/src/lib/components/ui/select/select-item.jsx +26 -0
- package/src/lib/components/ui/select/select-label.jsx +11 -0
- package/src/lib/components/ui/select/select-portal.jsx +4 -0
- package/src/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
- package/src/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
- package/src/lib/components/ui/select/select-separator.jsx +15 -0
- package/src/lib/components/ui/select/select-trigger.jsx +25 -0
- package/src/lib/components/ui/select/select.jsx +4 -0
- package/src/lib/components/ui/separator/index.js +5 -5
- package/src/lib/components/ui/separator/separator.jsx +22 -0
- package/src/lib/components/ui/sheet/index.js +32 -32
- package/src/lib/components/ui/sheet/sheet-close.jsx +7 -0
- package/src/lib/components/ui/sheet/sheet-content.jsx +35 -0
- package/src/lib/components/ui/sheet/sheet-description.jsx +15 -0
- package/src/lib/components/ui/sheet/sheet-footer.jsx +11 -0
- package/src/lib/components/ui/sheet/sheet-header.jsx +11 -0
- package/src/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
- package/src/lib/components/ui/sheet/sheet-portal.jsx +4 -0
- package/src/lib/components/ui/sheet/sheet-title.jsx +15 -0
- package/src/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
- package/src/lib/components/ui/sheet/sheet.jsx +4 -0
- package/src/lib/components/ui/textarea/index.js +5 -5
- package/src/lib/components/ui/textarea/textarea.jsx +18 -0
- package/src/lib/components/ui/toggle/index.js +6 -9
- package/src/lib/components/ui/toggle/toggle.jsx +36 -0
- package/src/lib/components/ui/toggle-group/index.js +8 -8
- package/src/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
- package/src/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
- package/src/lib/components/ui/tooltip/index.js +3 -3
- package/src/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
- package/src/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
- package/src/lib/components/ui/tooltip/tooltip.jsx +11 -0
- package/src/lib/components/ui/trigger-button/index.js +3 -3
- package/src/lib/components/ui/trigger-button/trigger-button.css +38 -0
- package/src/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
- package/src/logger/devLogger.js +238 -0
- package/src/logger/devLogger.test.js +193 -0
- package/src/modes.test.js +4 -4
- package/src/mountStoryboardCore.js +123 -27
- package/src/paletteProviders.js +3 -0
- package/src/paletteProviders.test.js +2 -2
- package/src/server/index.js +98 -36
- package/src/sidepanel.css +214 -0
- package/src/styles/tailwind.css +1 -1
- package/src/svelte-plugin-ui/__tests__/ModeSwitch.test.ts +8 -8
- package/src/svelte-plugin-ui/__tests__/ToolbarShell.test.ts +11 -10
- package/src/svelte-plugin-ui/components/Icon.css +11 -0
- package/src/svelte-plugin-ui/components/Icon.jsx +281 -0
- package/src/svelte-plugin-ui/components/ModeSwitch.css +90 -0
- package/src/svelte-plugin-ui/components/ModeSwitch.jsx +47 -0
- package/src/svelte-plugin-ui/components/ToolbarShell.css +80 -0
- package/src/svelte-plugin-ui/components/ToolbarShell.jsx +84 -0
- package/src/svelte-plugin-ui/components/Viewfinder.css +412 -0
- package/src/svelte-plugin-ui/components/Viewfinder.jsx +512 -0
- package/src/svelte-plugin-ui/mount.ts +12 -16
- package/src/toolRegistry.js +4 -4
- package/src/toolbarConfigStore.js +30 -0
- package/src/tools/handlers/autosync.js +1 -1
- package/src/tools/handlers/canvasAddWidget.js +1 -1
- package/src/tools/handlers/canvasAgents.js +19 -0
- package/src/tools/handlers/canvasToolbar.js +8 -8
- package/src/tools/handlers/commandPalette.js +9 -0
- package/src/tools/handlers/comments.js +1 -1
- package/src/tools/handlers/create.js +1 -1
- package/src/tools/handlers/devtools.js +16 -0
- package/src/tools/handlers/devtools.test.js +38 -0
- package/src/tools/handlers/flows.js +1 -1
- package/src/tools/handlers/hideChrome.js +9 -0
- package/src/tools/handlers/paletteTheme.js +35 -0
- package/src/tools/handlers/theme.js +1 -1
- package/src/tools/registry.js +4 -1
- package/src/tools/surfaces/commandList.js +3 -3
- package/src/tools/surfaces/mainToolbar.js +3 -3
- package/src/tools/surfaces/registry.js +4 -4
- package/src/ui/design-modes.ts +2 -2
- package/src/ui/viewfinder.ts +1 -1
- package/src/vite/server-plugin.js +242 -60
- package/src/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
- package/src/workshop/features/createCanvas/index.js +1 -1
- package/src/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
- package/src/workshop/features/createFlow/index.js +1 -1
- package/src/workshop/features/createPage/CreatePageForm.jsx +304 -0
- package/src/workshop/features/createPage/index.js +1 -1
- package/src/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
- package/src/workshop/features/createPrototype/index.js +1 -1
- package/src/workshop/features/createPrototype/server.js +98 -0
- package/src/workshop/features/createStory/CreateStoryForm.jsx +208 -0
- package/src/workshop/features/createStory/index.js +1 -1
- package/src/workshop/ui/WorkshopPanel.jsx +98 -0
- package/src/workshop/ui/mount.ts +1 -1
- package/src/worktree/port.js +48 -0
- package/src/worktree/serverRegistry.js +120 -0
- package/toolbar.config.json +93 -42
- package/widgets.config.json +580 -12
- package/src/ActionMenuButton.svelte +0 -119
- package/src/AutosyncMenuButton.svelte +0 -397
- package/src/CanvasCreateMenu.svelte +0 -295
- package/src/CanvasSnap.svelte +0 -87
- package/src/CanvasUndoRedo.svelte +0 -108
- package/src/CanvasZoomControl.svelte +0 -111
- package/src/CanvasZoomToFit.svelte +0 -52
- package/src/CommandMenu.svelte +0 -249
- package/src/CommandPalette.svelte +0 -33
- package/src/CommentsMenuButton.svelte +0 -53
- package/src/CoreUIBar.svelte +0 -847
- package/src/CreateMenuButton.svelte +0 -133
- package/src/DocPanel.svelte +0 -299
- package/src/InspectorPanel.svelte +0 -745
- package/src/PwaInstallBanner.svelte +0 -124
- package/src/SidePanel.svelte +0 -480
- package/src/ThemeMenuButton.svelte +0 -132
- package/src/comments/ui/AuthModal.svelte +0 -108
- package/src/comments/ui/CommentWindow.svelte +0 -333
- package/src/comments/ui/CommentsDrawer.svelte +0 -96
- package/src/comments/ui/Composer.svelte +0 -65
- package/src/lib/components/ui/alert/alert-action.svelte +0 -19
- package/src/lib/components/ui/alert/alert-description.svelte +0 -22
- package/src/lib/components/ui/alert/alert-title.svelte +0 -22
- package/src/lib/components/ui/alert/alert.svelte +0 -38
- package/src/lib/components/ui/avatar/avatar-badge.svelte +0 -25
- package/src/lib/components/ui/avatar/avatar-fallback.svelte +0 -20
- package/src/lib/components/ui/avatar/avatar-group-count.svelte +0 -22
- package/src/lib/components/ui/avatar/avatar-group.svelte +0 -22
- package/src/lib/components/ui/avatar/avatar-image.svelte +0 -17
- package/src/lib/components/ui/avatar/avatar.svelte +0 -24
- package/src/lib/components/ui/badge/badge.svelte +0 -44
- package/src/lib/components/ui/button/button.svelte +0 -108
- package/src/lib/components/ui/card/card-action.svelte +0 -21
- package/src/lib/components/ui/card/card-content.svelte +0 -19
- package/src/lib/components/ui/card/card-description.svelte +0 -19
- package/src/lib/components/ui/card/card-footer.svelte +0 -18
- package/src/lib/components/ui/card/card-header.svelte +0 -21
- package/src/lib/components/ui/card/card-title.svelte +0 -14
- package/src/lib/components/ui/card/card.svelte +0 -21
- package/src/lib/components/ui/checkbox/checkbox.svelte +0 -39
- package/src/lib/components/ui/collapsible/collapsible-content.svelte +0 -7
- package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +0 -7
- package/src/lib/components/ui/collapsible/collapsible.svelte +0 -11
- package/src/lib/components/ui/dialog/dialog-close.svelte +0 -11
- package/src/lib/components/ui/dialog/dialog-content.svelte +0 -42
- package/src/lib/components/ui/dialog/dialog-description.svelte +0 -17
- package/src/lib/components/ui/dialog/dialog-footer.svelte +0 -29
- package/src/lib/components/ui/dialog/dialog-header.svelte +0 -19
- package/src/lib/components/ui/dialog/dialog-overlay.svelte +0 -17
- package/src/lib/components/ui/dialog/dialog-portal.svelte +0 -7
- package/src/lib/components/ui/dialog/dialog-title.svelte +0 -17
- package/src/lib/components/ui/dialog/dialog-trigger.svelte +0 -11
- package/src/lib/components/ui/dialog/dialog.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +0 -16
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +0 -40
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +0 -27
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +0 -18
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte +0 -24
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte +0 -20
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +0 -16
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +0 -34
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte +0 -17
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +0 -19
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +0 -17
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +0 -27
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte +0 -7
- package/src/lib/components/ui/input/input.svelte +0 -40
- package/src/lib/components/ui/label/label.svelte +0 -20
- package/src/lib/components/ui/panel/panel-body.svelte +0 -13
- package/src/lib/components/ui/panel/panel-close.svelte +0 -16
- package/src/lib/components/ui/panel/panel-content.svelte +0 -33
- package/src/lib/components/ui/panel/panel-footer.svelte +0 -13
- package/src/lib/components/ui/panel/panel-header.svelte +0 -16
- package/src/lib/components/ui/panel/panel-title.svelte +0 -14
- package/src/lib/components/ui/panel/panel.svelte +0 -15
- package/src/lib/components/ui/popover/popover-close.svelte +0 -7
- package/src/lib/components/ui/popover/popover-content.svelte +0 -27
- package/src/lib/components/ui/popover/popover-description.svelte +0 -19
- package/src/lib/components/ui/popover/popover-header.svelte +0 -19
- package/src/lib/components/ui/popover/popover-portal.svelte +0 -7
- package/src/lib/components/ui/popover/popover-title.svelte +0 -19
- package/src/lib/components/ui/popover/popover-trigger.svelte +0 -17
- package/src/lib/components/ui/popover/popover.svelte +0 -7
- package/src/lib/components/ui/select/select-content.svelte +0 -40
- package/src/lib/components/ui/select/select-group-heading.svelte +0 -19
- package/src/lib/components/ui/select/select-group.svelte +0 -17
- package/src/lib/components/ui/select/select-item.svelte +0 -38
- package/src/lib/components/ui/select/select-label.svelte +0 -18
- package/src/lib/components/ui/select/select-portal.svelte +0 -7
- package/src/lib/components/ui/select/select-scroll-down-button.svelte +0 -20
- package/src/lib/components/ui/select/select-scroll-up-button.svelte +0 -20
- package/src/lib/components/ui/select/select-separator.svelte +0 -17
- package/src/lib/components/ui/select/select-trigger.svelte +0 -27
- package/src/lib/components/ui/select/select.svelte +0 -11
- package/src/lib/components/ui/separator/separator.svelte +0 -23
- package/src/lib/components/ui/sheet/sheet-close.svelte +0 -7
- package/src/lib/components/ui/sheet/sheet-content.svelte +0 -43
- package/src/lib/components/ui/sheet/sheet-description.svelte +0 -17
- package/src/lib/components/ui/sheet/sheet-footer.svelte +0 -18
- package/src/lib/components/ui/sheet/sheet-header.svelte +0 -19
- package/src/lib/components/ui/sheet/sheet-overlay.svelte +0 -17
- package/src/lib/components/ui/sheet/sheet-portal.svelte +0 -7
- package/src/lib/components/ui/sheet/sheet-title.svelte +0 -17
- package/src/lib/components/ui/sheet/sheet-trigger.svelte +0 -7
- package/src/lib/components/ui/sheet/sheet.svelte +0 -7
- package/src/lib/components/ui/textarea/textarea.svelte +0 -21
- package/src/lib/components/ui/toggle/toggle.svelte +0 -45
- package/src/lib/components/ui/toggle-group/toggle-group-item.svelte +0 -35
- package/src/lib/components/ui/toggle-group/toggle-group.svelte +0 -63
- package/src/lib/components/ui/tooltip/tooltip-content.svelte +0 -24
- package/src/lib/components/ui/tooltip/tooltip-trigger.svelte +0 -27
- package/src/lib/components/ui/tooltip/tooltip.svelte +0 -9
- package/src/lib/components/ui/trigger-button/trigger-button.svelte +0 -106
- package/src/svelte-plugin-ui/components/Icon.svelte +0 -181
- package/src/svelte-plugin-ui/components/ModeSwitch.svelte +0 -121
- package/src/svelte-plugin-ui/components/ToolbarShell.svelte +0 -150
- package/src/svelte-plugin-ui/components/Viewfinder.svelte +0 -1001
- package/src/tools/handlers/docs.js +0 -11
- package/src/workshop/features/createCanvas/CreateCanvasForm.svelte +0 -139
- package/src/workshop/features/createFlow/CreateFlowForm.svelte +0 -314
- package/src/workshop/features/createPage/CreatePageForm.svelte +0 -249
- package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +0 -287
- package/src/workshop/features/createStory/CreateStoryForm.svelte +0 -161
- package/src/workshop/ui/WorkshopPanel.svelte +0 -97
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Docs tool module — documentation sidepanel toggle.
|
|
3
|
-
*/
|
|
4
|
-
export const id = 'docs'
|
|
5
|
-
|
|
6
|
-
// No component needed — sidepanel tools use generic TriggerButton
|
|
7
|
-
|
|
8
|
-
export async function handler() {
|
|
9
|
-
const { togglePanel } = await import('../../stores/sidePanelStore.js')
|
|
10
|
-
return () => togglePanel('docs')
|
|
11
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
CreateCanvasForm — workshop form for creating a new canvas.
|
|
3
|
-
Uses shadcn-svelte components for all form elements.
|
|
4
|
-
-->
|
|
5
|
-
|
|
6
|
-
<script lang="ts">
|
|
7
|
-
import { onMount } from 'svelte'
|
|
8
|
-
import { Button } from '../../../lib/components/ui/button/index.js'
|
|
9
|
-
import { Input } from '../../../lib/components/ui/input/index.js'
|
|
10
|
-
import { Label } from '../../../lib/components/ui/label/index.js'
|
|
11
|
-
import { Checkbox } from '../../../lib/components/ui/checkbox/index.js'
|
|
12
|
-
import * as Panel from '../../../lib/components/ui/panel/index.js'
|
|
13
|
-
import * as Alert from '../../../lib/components/ui/alert/index.js'
|
|
14
|
-
|
|
15
|
-
interface Props { onClose?: () => void }
|
|
16
|
-
let { onClose }: Props = $props()
|
|
17
|
-
|
|
18
|
-
let name = $state('')
|
|
19
|
-
let title = $state('')
|
|
20
|
-
let titleTouched = $state(false)
|
|
21
|
-
let description = $state('')
|
|
22
|
-
let folder = $state('')
|
|
23
|
-
let grid = $state(true)
|
|
24
|
-
|
|
25
|
-
let folders: string[] = $state([])
|
|
26
|
-
let loading = $state(true)
|
|
27
|
-
let submitting = $state(false)
|
|
28
|
-
let error: string | null = $state(null)
|
|
29
|
-
let success: string | null = $state(null)
|
|
30
|
-
let createdRoute: string | null = $state(null)
|
|
31
|
-
|
|
32
|
-
const kebabName = $derived(
|
|
33
|
-
name.replace(/[^a-zA-Z0-9\s_-]/g, '').trim().replace(/[\s_]+/g, '-').toLowerCase().replace(/-+/g, '-').replace(/^-|-$/g, '')
|
|
34
|
-
)
|
|
35
|
-
const autoTitle = $derived(
|
|
36
|
-
kebabName ? kebabName.split('-').map((s: string) => s.charAt(0).toUpperCase() + s.slice(1)).join(' ') : ''
|
|
37
|
-
)
|
|
38
|
-
const displayTitle = $derived(titleTouched ? title : autoTitle)
|
|
39
|
-
const routePreview = $derived(kebabName ? `/canvas/${kebabName}` : '')
|
|
40
|
-
const nameError = $derived(
|
|
41
|
-
name.trim() && !kebabName ? 'Name must contain at least one alphanumeric character'
|
|
42
|
-
: name.trim() && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(kebabName) ? 'Name must be kebab-case'
|
|
43
|
-
: null
|
|
44
|
-
)
|
|
45
|
-
const canSubmit = $derived(!!kebabName && !nameError && !submitting)
|
|
46
|
-
|
|
47
|
-
function getApiUrl() {
|
|
48
|
-
const basePath = window.__STORYBOARD_BASE_PATH__ || '/'
|
|
49
|
-
return basePath.replace(/\/$/, '') + '/_storyboard/canvas'
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const CANVAS_SUCCESS_KEY = 'sb-canvas-created'
|
|
53
|
-
|
|
54
|
-
onMount(async () => {
|
|
55
|
-
// Restore success state after Vite's full-reload on file creation
|
|
56
|
-
try {
|
|
57
|
-
const saved = sessionStorage.getItem(CANVAS_SUCCESS_KEY)
|
|
58
|
-
if (saved) {
|
|
59
|
-
const parsed = JSON.parse(saved)
|
|
60
|
-
success = parsed.success
|
|
61
|
-
createdRoute = parsed.route
|
|
62
|
-
sessionStorage.removeItem(CANVAS_SUCCESS_KEY)
|
|
63
|
-
}
|
|
64
|
-
} catch {}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const res = await fetch(getApiUrl() + '/folders')
|
|
68
|
-
if (res.ok) {
|
|
69
|
-
const data = await res.json()
|
|
70
|
-
folders = data.folders || []
|
|
71
|
-
}
|
|
72
|
-
} catch { /* defaults */ } finally { loading = false }
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
function handleTitleInput(e: Event) { title = (e.target as HTMLInputElement).value; titleTouched = true }
|
|
76
|
-
function handleTitleBlur() { if (!title.trim()) titleTouched = false }
|
|
77
|
-
|
|
78
|
-
async function submit() {
|
|
79
|
-
if (!canSubmit) return
|
|
80
|
-
submitting = true; error = null; success = null; createdRoute = null
|
|
81
|
-
try {
|
|
82
|
-
const res = await fetch(getApiUrl() + '/create', {
|
|
83
|
-
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
84
|
-
body: JSON.stringify({ name: kebabName, title: displayTitle, description: description || undefined, folder: folder || undefined, grid }),
|
|
85
|
-
})
|
|
86
|
-
const data = await res.json()
|
|
87
|
-
if (!res.ok) { error = data.error || 'Failed to create canvas'; return }
|
|
88
|
-
success = `Created ${data.path}`
|
|
89
|
-
createdRoute = data.route
|
|
90
|
-
// Persist success state — Vite does a full-reload when new files are created
|
|
91
|
-
try {
|
|
92
|
-
sessionStorage.setItem(CANVAS_SUCCESS_KEY, JSON.stringify({ success, route: createdRoute }))
|
|
93
|
-
} catch {}
|
|
94
|
-
} catch (err: any) { error = err.message || 'Network error' } finally { submitting = false }
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function handleKeydown(e: KeyboardEvent) { if (e.key === 'Enter' && canSubmit) submit() }
|
|
98
|
-
</script>
|
|
99
|
-
|
|
100
|
-
<Panel.Header>
|
|
101
|
-
<Panel.Title>Create canvas</Panel.Title>
|
|
102
|
-
<Panel.Close />
|
|
103
|
-
</Panel.Header>
|
|
104
|
-
|
|
105
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
106
|
-
<div class="p-4 pt-2 space-y-3" onkeydown={handleKeydown}>
|
|
107
|
-
<div class="space-y-1">
|
|
108
|
-
<Label for="sb-canvas-name">Name</Label>
|
|
109
|
-
<Input id="sb-canvas-name" placeholder="e.g. design-overview" autocomplete="off" spellcheck="false" bind:value={name} />
|
|
110
|
-
{#if nameError}<p class="text-sm text-destructive">{nameError}</p>{/if}
|
|
111
|
-
{#if routePreview}<p class="text-xs text-muted-foreground mt-1.5">Route: <code class="px-1 py-0.5 bg-muted rounded font-mono text-foreground text-xs">{routePreview}</code></p>{/if}
|
|
112
|
-
</div>
|
|
113
|
-
|
|
114
|
-
<div class="space-y-1">
|
|
115
|
-
<Label for="sb-canvas-description">Description <span class="text-muted-foreground font-normal">(optional)</span></Label>
|
|
116
|
-
<Input id="sb-canvas-description" placeholder="A brief description of this canvas" bind:value={description} />
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
<div class="space-y-1">
|
|
120
|
-
<Label for="sb-canvas-folder">Folder</Label>
|
|
121
|
-
<select class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" id="sb-canvas-folder" bind:value={folder} disabled={loading}>
|
|
122
|
-
<option value="">None</option>
|
|
123
|
-
{#each folders as f}<option value={f}>{f}</option>{/each}
|
|
124
|
-
</select>
|
|
125
|
-
</div>
|
|
126
|
-
|
|
127
|
-
<div class="flex items-center gap-2">
|
|
128
|
-
<Checkbox id="sb-canvas-grid" bind:checked={grid} />
|
|
129
|
-
<Label for="sb-canvas-grid" class="text-sm font-normal cursor-pointer">Show grid</Label>
|
|
130
|
-
</div>
|
|
131
|
-
|
|
132
|
-
{#if error}<Alert.Root variant="destructive"><Alert.Description>{error}</Alert.Description></Alert.Root>{/if}
|
|
133
|
-
{#if success}<Alert.Root><Alert.Description class="text-success">{success}{#if createdRoute} — <a href={createdRoute} class="underline font-medium">Go to canvas</a>{/if}</Alert.Description></Alert.Root>{/if}
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<Panel.Footer>
|
|
137
|
-
<Button variant="outline" onclick={onClose}>Cancel</Button>
|
|
138
|
-
<Button onclick={submit} disabled={!canSubmit}>{submitting ? 'Creating\u2026' : 'Create'}</Button>
|
|
139
|
-
</Panel.Footer>
|
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
CreateFlowForm — workshop form for creating a new flow data file.
|
|
3
|
-
Uses shadcn-svelte components for all form elements.
|
|
4
|
-
-->
|
|
5
|
-
|
|
6
|
-
<script lang="ts">
|
|
7
|
-
import { onMount } from 'svelte'
|
|
8
|
-
import { Button } from '../../../lib/components/ui/button/index.js'
|
|
9
|
-
import { Input } from '../../../lib/components/ui/input/index.js'
|
|
10
|
-
import { Label } from '../../../lib/components/ui/label/index.js'
|
|
11
|
-
import * as Panel from '../../../lib/components/ui/panel/index.js'
|
|
12
|
-
import * as Alert from '../../../lib/components/ui/alert/index.js'
|
|
13
|
-
|
|
14
|
-
interface Props {
|
|
15
|
-
onClose?: () => void
|
|
16
|
-
}
|
|
17
|
-
let { onClose }: Props = $props()
|
|
18
|
-
|
|
19
|
-
let name = $state('')
|
|
20
|
-
let title = $state('')
|
|
21
|
-
let titleTouched = $state(false)
|
|
22
|
-
let selectedPrototype = $state('')
|
|
23
|
-
let description = $state('')
|
|
24
|
-
let copyFrom = $state('')
|
|
25
|
-
let startingPage = $state('')
|
|
26
|
-
let newPagePath = $state('')
|
|
27
|
-
let newPageTemplate = $state('')
|
|
28
|
-
const CREATE_NEW_PAGE_VALUE = '__create_new_page__'
|
|
29
|
-
|
|
30
|
-
interface PrototypeEntry { name: string; folder?: string; routes?: string[] }
|
|
31
|
-
interface FlowEntry { name: string; title: string; path: string; prototype?: string; folder?: string; route?: string }
|
|
32
|
-
interface PartialEntry {
|
|
33
|
-
id: string
|
|
34
|
-
name: string
|
|
35
|
-
kind: 'template' | 'recipe'
|
|
36
|
-
scope: 'global' | 'prototype'
|
|
37
|
-
prototype?: string
|
|
38
|
-
folder?: string
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let prototypes: PrototypeEntry[] = $state([])
|
|
42
|
-
let flows: FlowEntry[] = $state([])
|
|
43
|
-
let partials: PartialEntry[] = $state([])
|
|
44
|
-
let loading = $state(true)
|
|
45
|
-
let submitting = $state(false)
|
|
46
|
-
let error: string | null = $state(null)
|
|
47
|
-
let success: string | null = $state(null)
|
|
48
|
-
|
|
49
|
-
const kebabName = $derived(
|
|
50
|
-
name.replace(/[^a-zA-Z0-9\s_-]/g, '').trim().replace(/[\s_]+/g, '-').toLowerCase().replace(/-+/g, '-').replace(/^-|-$/g, '')
|
|
51
|
-
)
|
|
52
|
-
const autoTitle = $derived(
|
|
53
|
-
kebabName ? kebabName.split('-').map((s: string) => s.charAt(0).toUpperCase() + s.slice(1)).join(' ') : ''
|
|
54
|
-
)
|
|
55
|
-
const displayTitle = $derived(titleTouched ? title : autoTitle)
|
|
56
|
-
const filePreview = $derived(kebabName ? `${kebabName}.flow.json` : '')
|
|
57
|
-
const nameError = $derived(
|
|
58
|
-
name.trim() && !kebabName ? 'Name must contain at least one alphanumeric character'
|
|
59
|
-
: name.trim() && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(kebabName) ? 'Name must be kebab-case'
|
|
60
|
-
: null
|
|
61
|
-
)
|
|
62
|
-
const selectedProtoEntry = $derived(
|
|
63
|
-
selectedPrototype ? prototypes.find(p => p.name === selectedPrototype) : null
|
|
64
|
-
)
|
|
65
|
-
const copyFromFlows = $derived(
|
|
66
|
-
selectedPrototype
|
|
67
|
-
? flows.filter((f) => {
|
|
68
|
-
if (f.prototype !== selectedPrototype) return false
|
|
69
|
-
const flowFolder = f.folder || ''
|
|
70
|
-
const selectedFolder = selectedProtoEntry?.folder || ''
|
|
71
|
-
return flowFolder === selectedFolder
|
|
72
|
-
})
|
|
73
|
-
: []
|
|
74
|
-
)
|
|
75
|
-
const prototypeRoutes = $derived(selectedProtoEntry?.routes || [])
|
|
76
|
-
const showNewPageFields = $derived(startingPage === CREATE_NEW_PAGE_VALUE)
|
|
77
|
-
const newPagePrefix = $derived(selectedPrototype ? `/${selectedPrototype}/` : '/prototype-name/')
|
|
78
|
-
const templateChoices = $derived(
|
|
79
|
-
selectedPrototype
|
|
80
|
-
? partials.filter((partial) => {
|
|
81
|
-
if (partial.scope === 'global') return true
|
|
82
|
-
return partial.prototype === selectedPrototype && (partial.folder || '') === (selectedProtoEntry?.folder || '')
|
|
83
|
-
})
|
|
84
|
-
: partials.filter((partial) => partial.scope === 'global')
|
|
85
|
-
)
|
|
86
|
-
const globalTemplateChoices = $derived(templateChoices.filter((partial) => partial.scope === 'global'))
|
|
87
|
-
const localTemplateChoices = $derived(
|
|
88
|
-
templateChoices.filter((partial) => partial.scope === 'prototype')
|
|
89
|
-
)
|
|
90
|
-
const localTemplateHeading = $derived(
|
|
91
|
-
selectedPrototype || ''
|
|
92
|
-
)
|
|
93
|
-
const startingPageError = $derived(
|
|
94
|
-
showNewPageFields && !newPagePath.trim()
|
|
95
|
-
? 'Please provide a new page path'
|
|
96
|
-
: null
|
|
97
|
-
)
|
|
98
|
-
const canSubmit = $derived(
|
|
99
|
-
!!kebabName &&
|
|
100
|
-
!!selectedPrototype &&
|
|
101
|
-
!nameError &&
|
|
102
|
-
!startingPageError &&
|
|
103
|
-
!submitting
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
function getApiUrl() {
|
|
107
|
-
const basePath = window.__STORYBOARD_BASE_PATH__ || '/'
|
|
108
|
-
return basePath.replace(/\/$/, '') + '/_storyboard/workshop/flows'
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
onMount(async () => {
|
|
112
|
-
try {
|
|
113
|
-
const res = await fetch(getApiUrl())
|
|
114
|
-
if (res.ok) {
|
|
115
|
-
const data = await res.json()
|
|
116
|
-
prototypes = data.prototypes || []
|
|
117
|
-
flows = data.flows || []
|
|
118
|
-
partials = data.partials || []
|
|
119
|
-
}
|
|
120
|
-
} catch { /* defaults */ } finally { loading = false }
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
$effect(() => {
|
|
124
|
-
if (!selectedPrototype) {
|
|
125
|
-
copyFrom = ''
|
|
126
|
-
startingPage = ''
|
|
127
|
-
newPagePath = ''
|
|
128
|
-
newPageTemplate = ''
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const routes = selectedProtoEntry?.routes || []
|
|
133
|
-
if (!startingPage || (startingPage !== CREATE_NEW_PAGE_VALUE && !routes.includes(startingPage))) {
|
|
134
|
-
startingPage = routes[0] || ''
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (showNewPageFields) {
|
|
138
|
-
if (!newPagePath.startsWith(newPagePrefix)) {
|
|
139
|
-
newPagePath = `${newPagePrefix}new-page`
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const activeSelectionStillValid = copyFrom && copyFromFlows.some((f) => f.path === copyFrom)
|
|
144
|
-
if (activeSelectionStillValid) return
|
|
145
|
-
|
|
146
|
-
const matchStartingPage = startingPage && startingPage !== CREATE_NEW_PAGE_VALUE
|
|
147
|
-
? copyFromFlows.find((f) => f.route === startingPage)
|
|
148
|
-
: null
|
|
149
|
-
copyFrom = matchStartingPage?.path || ''
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
$effect(() => {
|
|
153
|
-
if (!newPageTemplate) return
|
|
154
|
-
const stillAvailable = templateChoices.some((choice) => choice.id === newPageTemplate)
|
|
155
|
-
if (!stillAvailable) {
|
|
156
|
-
newPageTemplate = ''
|
|
157
|
-
}
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
function handleTitleInput(e: Event) { title = (e.target as HTMLInputElement).value; titleTouched = true }
|
|
161
|
-
function handleTitleBlur() { if (!title.trim()) titleTouched = false }
|
|
162
|
-
|
|
163
|
-
async function submit() {
|
|
164
|
-
if (!canSubmit) return
|
|
165
|
-
submitting = true; error = null; success = null
|
|
166
|
-
try {
|
|
167
|
-
const res = await fetch(getApiUrl(), {
|
|
168
|
-
method: 'POST',
|
|
169
|
-
headers: { 'Content-Type': 'application/json' },
|
|
170
|
-
body: JSON.stringify({
|
|
171
|
-
name: kebabName,
|
|
172
|
-
title: displayTitle,
|
|
173
|
-
prototype: selectedPrototype,
|
|
174
|
-
folder: selectedProtoEntry?.folder || undefined,
|
|
175
|
-
description: description.trim() || undefined,
|
|
176
|
-
copyFrom: copyFrom || undefined,
|
|
177
|
-
startingPage: showNewPageFields ? newPagePath.trim() : (startingPage || undefined),
|
|
178
|
-
createPage: showNewPageFields ? {
|
|
179
|
-
path: newPagePath.trim(),
|
|
180
|
-
template: newPageTemplate || undefined,
|
|
181
|
-
} : undefined,
|
|
182
|
-
}),
|
|
183
|
-
})
|
|
184
|
-
const data = await res.json()
|
|
185
|
-
if (!res.ok) { error = data.error || 'Failed to create flow'; return }
|
|
186
|
-
success = `Created ${data.path}`
|
|
187
|
-
} catch (err: any) { error = err.message || 'Network error' } finally { submitting = false }
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function handleKeydown(e: KeyboardEvent) { if (e.key === 'Enter' && canSubmit) submit() }
|
|
191
|
-
</script>
|
|
192
|
-
|
|
193
|
-
<Panel.Header>
|
|
194
|
-
<Panel.Title>Create flow</Panel.Title>
|
|
195
|
-
<Panel.Close />
|
|
196
|
-
</Panel.Header>
|
|
197
|
-
|
|
198
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
199
|
-
<div class="p-4 pt-2 space-y-5" onkeydown={handleKeydown}>
|
|
200
|
-
<div class="space-y-1">
|
|
201
|
-
<Label for="sb-flow-name">Name</Label>
|
|
202
|
-
<Input id="sb-flow-name" placeholder="e.g. empty-state" autocomplete="off" spellcheck="false" bind:value={name} />
|
|
203
|
-
{#if nameError}<p class="text-sm text-destructive">{nameError}</p>{/if}
|
|
204
|
-
{#if filePreview}<p class="text-xs text-muted-foreground">File: <code class="px-1 py-0.5 bg-muted rounded font-mono text-foreground text-xs">{filePreview}</code></p>{/if}
|
|
205
|
-
</div>
|
|
206
|
-
|
|
207
|
-
<div class="space-y-1">
|
|
208
|
-
<Label for="sb-flow-title">Title</Label>
|
|
209
|
-
<Input id="sb-flow-title" placeholder={autoTitle || 'Auto-derived from name'} value={displayTitle} oninput={handleTitleInput} onblur={handleTitleBlur} />
|
|
210
|
-
</div>
|
|
211
|
-
|
|
212
|
-
<div class="space-y-1">
|
|
213
|
-
<Label for="sb-flow-prototype">Prototype</Label>
|
|
214
|
-
<select class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" id="sb-flow-prototype" bind:value={selectedPrototype} disabled={loading}>
|
|
215
|
-
<option value="">Select prototype</option>
|
|
216
|
-
{#each prototypes as p}<option value={p.name}>{p.folder ? `${p.folder} / ${p.name}` : p.name}</option>{/each}
|
|
217
|
-
</select>
|
|
218
|
-
</div>
|
|
219
|
-
|
|
220
|
-
<div class="space-y-1">
|
|
221
|
-
<Label for="sb-flow-copy">Copy from existing flow <span class="text-muted-foreground">(optional)</span></Label>
|
|
222
|
-
<select
|
|
223
|
-
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
224
|
-
id="sb-flow-copy"
|
|
225
|
-
bind:value={copyFrom}
|
|
226
|
-
disabled={loading || !selectedPrototype}
|
|
227
|
-
>
|
|
228
|
-
{#if !selectedPrototype}
|
|
229
|
-
<option value="">Select a prototype first</option>
|
|
230
|
-
{:else}
|
|
231
|
-
<option value="">None</option>
|
|
232
|
-
{#each copyFromFlows as f}<option value={f.path}>{f.title} ({f.name})</option>{/each}
|
|
233
|
-
{/if}
|
|
234
|
-
</select>
|
|
235
|
-
</div>
|
|
236
|
-
|
|
237
|
-
<div class="space-y-1">
|
|
238
|
-
<Label for="sb-flow-starting-page">Starting page <span class="text-muted-foreground">(optional)</span></Label>
|
|
239
|
-
<select
|
|
240
|
-
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
241
|
-
id="sb-flow-starting-page"
|
|
242
|
-
bind:value={startingPage}
|
|
243
|
-
disabled={loading || !selectedPrototype}
|
|
244
|
-
>
|
|
245
|
-
{#if !selectedPrototype}
|
|
246
|
-
<option value="">Select a prototype first</option>
|
|
247
|
-
{:else}
|
|
248
|
-
<option value="">None</option>
|
|
249
|
-
{#each prototypeRoutes as route}
|
|
250
|
-
<option value={route}>{route}</option>
|
|
251
|
-
{/each}
|
|
252
|
-
<option value={CREATE_NEW_PAGE_VALUE}>Create new page</option>
|
|
253
|
-
{/if}
|
|
254
|
-
</select>
|
|
255
|
-
<p class="text-xs text-muted-foreground">Users will be redirected to this page</p>
|
|
256
|
-
</div>
|
|
257
|
-
|
|
258
|
-
{#if showNewPageFields}
|
|
259
|
-
<div class="space-y-1">
|
|
260
|
-
<Label for="sb-flow-new-page-path">New page path</Label>
|
|
261
|
-
<div class="flex items-center gap-2">
|
|
262
|
-
<span class="text-xs text-muted-foreground font-mono">{newPagePrefix}</span>
|
|
263
|
-
<Input
|
|
264
|
-
id="sb-flow-new-page-path"
|
|
265
|
-
placeholder="new-page"
|
|
266
|
-
value={newPagePath.startsWith(newPagePrefix) ? newPagePath.slice(newPagePrefix.length) : ''}
|
|
267
|
-
oninput={(e: Event) => {
|
|
268
|
-
const suffix = (e.target as HTMLInputElement).value.replace(/^\/+/, '')
|
|
269
|
-
newPagePath = `${newPagePrefix}${suffix}`
|
|
270
|
-
}}
|
|
271
|
-
/>
|
|
272
|
-
</div>
|
|
273
|
-
</div>
|
|
274
|
-
<div class="space-y-1">
|
|
275
|
-
<Label for="sb-flow-new-page-template">Template / recipe</Label>
|
|
276
|
-
<select
|
|
277
|
-
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
278
|
-
id="sb-flow-new-page-template"
|
|
279
|
-
bind:value={newPageTemplate}
|
|
280
|
-
disabled={!selectedPrototype}
|
|
281
|
-
>
|
|
282
|
-
<option value="">Blank page</option>
|
|
283
|
-
{#if globalTemplateChoices.length > 0}
|
|
284
|
-
<optgroup label="Global">
|
|
285
|
-
{#each globalTemplateChoices as partial}
|
|
286
|
-
<option value={partial.id}>{partial.name}</option>
|
|
287
|
-
{/each}
|
|
288
|
-
</optgroup>
|
|
289
|
-
{/if}
|
|
290
|
-
{#if localTemplateChoices.length > 0}
|
|
291
|
-
<optgroup label={localTemplateHeading}>
|
|
292
|
-
{#each localTemplateChoices as partial}
|
|
293
|
-
<option value={partial.id}>{partial.name}</option>
|
|
294
|
-
{/each}
|
|
295
|
-
</optgroup>
|
|
296
|
-
{/if}
|
|
297
|
-
</select>
|
|
298
|
-
</div>
|
|
299
|
-
{#if startingPageError}<p class="text-sm text-destructive">{startingPageError}</p>{/if}
|
|
300
|
-
{/if}
|
|
301
|
-
|
|
302
|
-
<div class="space-y-1">
|
|
303
|
-
<Label for="sb-flow-desc">Description</Label>
|
|
304
|
-
<Input id="sb-flow-desc" placeholder="Optional description" bind:value={description} />
|
|
305
|
-
</div>
|
|
306
|
-
|
|
307
|
-
{#if error}<Alert.Root variant="destructive"><Alert.Description>{error}</Alert.Description></Alert.Root>{/if}
|
|
308
|
-
{#if success}<Alert.Root><Alert.Description class="text-success">{success}</Alert.Description></Alert.Root>{/if}
|
|
309
|
-
</div>
|
|
310
|
-
|
|
311
|
-
<Panel.Footer>
|
|
312
|
-
<Button variant="outline" onclick={onClose}>Cancel</Button>
|
|
313
|
-
<Button onclick={submit} disabled={!canSubmit}>{submitting ? 'Creating\u2026' : 'Create'}</Button>
|
|
314
|
-
</Panel.Footer>
|