@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
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon — renders icons from multiple sources using namespaced names.
|
|
3
|
+
*
|
|
4
|
+
* primer/ → Primer Octicons (fill-based)
|
|
5
|
+
* feather/ → Feather Icons (stroke-based)
|
|
6
|
+
* iconoir/ → Iconoir (stroke-based, manually registered)
|
|
7
|
+
* (no prefix) → Custom (folder, prototype, canvas, component, etc.)
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* <Icon name="primer/repo" />
|
|
11
|
+
* <Icon name="feather/flag" size={16} />
|
|
12
|
+
* <Icon name="iconoir/key-command" size={16} strokeWeight={2} />
|
|
13
|
+
* <Icon name="prototype" size={14} />
|
|
14
|
+
* <Icon name="feather/tablet" rotate={90} />
|
|
15
|
+
* <Icon name="primer/lock" offsetX={1} offsetY={-1} />
|
|
16
|
+
* <Icon name="feather/arrow-right" flipX />
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/* ─── Custom SVG paths (fill-based, no namespace prefix) ─── */
|
|
20
|
+
|
|
21
|
+
const customIcons = {
|
|
22
|
+
'home': {
|
|
23
|
+
viewBox: '0 0 16 16',
|
|
24
|
+
path: 'M6.906.664a1.749 1.749 0 0 1 2.187 0l5.25 4.2c.415.332.657.835.657 1.367v7.019A1.75 1.75 0 0 1 13.25 15h-3.5a.75.75 0 0 1-.75-.75V9H7v5.25a.75.75 0 0 1-.75.75h-3.5A1.75 1.75 0 0 1 1 13.25V6.23c0-.531.242-1.034.657-1.366l5.25-4.2Zm1.25 1.171a.25.25 0 0 0-.312 0l-5.25 4.2a.25.25 0 0 0-.094.196v7.019c0 .138.112.25.25.25H5.5V8.25a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 .75.75v5.25h2.75a.25.25 0 0 0 .25-.25V6.23a.25.25 0 0 0-.094-.195Z',
|
|
25
|
+
},
|
|
26
|
+
'folder': {
|
|
27
|
+
viewBox: '0 0 24 24',
|
|
28
|
+
path: 'M4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h5.175q.4 0 .763.15t.637.425L12 6h8q.825 0 1.413.588T22 8v10q0 .825-.587 1.413T20 20z',
|
|
29
|
+
},
|
|
30
|
+
'folder-open': {
|
|
31
|
+
viewBox: '0 0 24 24',
|
|
32
|
+
path: 'M4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h5.175q.4 0 .763.15t.637.425L12 6h9q.425 0 .713.288T22 7t-.288.713T21 8H7.85q-1.55 0-2.7.975T4 11.45V18l1.975-6.575q.2-.65.738-1.037T7.9 10h12.9q1.025 0 1.613.813t.312 1.762l-1.8 6q-.2.65-.737 1.038T19 20z',
|
|
33
|
+
},
|
|
34
|
+
// CollageFrame icon (from PrototypeEmbed widget title bar)
|
|
35
|
+
'prototype': {
|
|
36
|
+
viewBox: '0 0 24 24',
|
|
37
|
+
strokePaths: [
|
|
38
|
+
'M19.4 20H4.6C4.26863 20 4 19.7314 4 19.4V4.6C4 4.26863 4.26863 4 4.6 4H19.4C19.7314 4 20 4.26863 20 4.6V19.4C20 19.7314 19.7314 20 19.4 20Z',
|
|
39
|
+
'M11 12V4',
|
|
40
|
+
'M4 12H20',
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
// Smiley face icon (from assets/icons/canvas.svg)
|
|
44
|
+
'canvas': {
|
|
45
|
+
viewBox: '0 0 28 23',
|
|
46
|
+
strokeRect: { x: 1, y: 1, width: 26, height: 21, rx: 7 },
|
|
47
|
+
fillPaths: [
|
|
48
|
+
'M17.8421 12.9776V12.9788L17.8409 12.9812C18.2386 12.451 18.9901 12.3434 19.5204 12.7409C20.0506 13.1385 20.1582 13.8901 19.7606 14.4204L18.8008 13.7008C19.7416 14.4064 19.7606 14.4209 19.7606 14.4215L19.7583 14.4239C19.7573 14.4252 19.756 14.427 19.7548 14.4286C19.7524 14.4317 19.7499 14.436 19.7466 14.4403C19.7399 14.449 19.7311 14.4601 19.7208 14.4731C19.7001 14.4992 19.6715 14.5332 19.6364 14.5751C19.566 14.6589 19.4665 14.7734 19.3387 14.9067C19.0842 15.1723 18.712 15.5216 18.2312 15.8713C17.2736 16.5677 15.831 17.3011 14.0003 17.3011C12.1695 17.3011 10.727 16.5677 9.76938 15.8713C9.28854 15.5216 8.91634 15.1723 8.66184 14.9067C8.53409 14.7734 8.43453 14.6589 8.36415 14.5751C8.32905 14.5332 8.30044 14.4992 8.27977 14.4731C8.26946 14.4601 8.26066 14.449 8.25398 14.4403C8.25066 14.436 8.24819 14.4317 8.24578 14.4286C8.24457 14.427 8.24325 14.4252 8.24226 14.4239L8.23992 14.4215C8.24001 14.4209 8.25896 14.4064 9.19979 13.7008L8.23992 14.4204C7.8424 13.8901 7.94999 13.1385 8.48018 12.7409C9.01029 12.3435 9.76077 12.4513 10.1585 12.9812L10.1597 12.98L10.1585 12.9776H10.1573C10.1583 12.9789 10.1602 12.9801 10.162 12.9823C10.1691 12.9914 10.182 13.0091 10.2018 13.0327C10.2416 13.08 10.3064 13.1534 10.394 13.2449C10.5708 13.4293 10.8366 13.6804 11.1805 13.9305C11.873 14.4341 12.8308 14.9009 14.0003 14.9009C15.1698 14.9009 16.1276 14.4341 16.8201 13.9305C17.164 13.6804 17.4298 13.4293 17.6065 13.2449C17.6942 13.1534 17.759 13.08 17.7987 13.0327C17.8186 13.0091 17.8314 12.9914 17.8386 12.9823L17.8421 12.9776Z',
|
|
49
|
+
'M10.4111 6.5C11.0739 6.5 11.6112 7.03731 11.6112 7.70012C11.6112 8.36293 11.0739 8.90025 10.4111 8.90025H10.3993C9.73653 8.90025 9.19922 8.36293 9.19922 7.70012C9.19922 7.03731 9.73653 6.5 10.3993 6.5H10.4111Z',
|
|
50
|
+
'M17.6103 6.5C18.2731 6.5 18.8104 7.03731 18.8104 7.70012C18.8104 8.36293 18.2731 8.90025 17.6103 8.90025H17.5986C16.9358 8.90025 16.3984 8.36293 16.3984 7.70012C16.3984 7.03731 16.9358 6.5 17.5986 6.5H17.6103Z',
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
'flow': {
|
|
54
|
+
viewBox: '0 0 24 24',
|
|
55
|
+
strokeWidth: '2.5',
|
|
56
|
+
strokePaths: [
|
|
57
|
+
'M13 19L22 12L13 5L13 19Z',
|
|
58
|
+
'M2 19L11 12L2 5L2 19Z',
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
'sticky-note': {
|
|
62
|
+
viewBox: '0 0 14 14',
|
|
63
|
+
fillRule: 'evenodd',
|
|
64
|
+
path: 'M3.709.471C4.763.353 5.867.25 7 .25s2.237.104 3.29.22h.003a3.694 3.694 0 0 1 3.247 3.256v.004c.113 1.049.21 2.145.21 3.27q-.001.595-.032 1.176l-.008.067c-.556 3.437-3.804 5.226-6.192 5.498h-.006l-.048.006a.6.6 0 0 1-.126 0q-.168.003-.338.003c-1.133 0-2.236-.103-3.29-.221h-.003A3.695 3.695 0 0 1 .46 10.272v-.004C.346 9.221.25 8.126.25 7s.097-2.222.21-3.27v-.003A3.694 3.694 0 0 1 3.707.472zm8.784 7.047h-2.37c-.854 0-1.514.656-1.628 1.442c-.22 1.52-.706 2.546-1.413 3.54H7c-1.061 0-2.108-.097-3.15-.213a2.445 2.445 0 0 1-2.148-2.153C1.592 9.1 1.5 8.057 1.5 7s.091-2.1.202-3.134A2.444 2.444 0 0 1 3.85 1.714C4.89 1.597 5.938 1.5 7 1.5s2.107.098 3.151.213a2.444 2.444 0 0 1 2.147 2.152C12.408 4.9 12.5 5.944 12.5 7q0 .259-.007.518',
|
|
65
|
+
},
|
|
66
|
+
'agents': {
|
|
67
|
+
viewBox: '0 0 32 32',
|
|
68
|
+
path: 'M27.2 16c0-6.19-5.01-11.2-11.2-11.2S4.8 9.81 4.8 16S9.81 27.2 16 27.2S27.2 22.19 27.2 16m-5.6 2.1a1.4 1.4 0 0 1 0 2.8h-4.2a1.4 1.4 0 0 1 0-2.8zm-11.2-6.8a1.397 1.397 0 0 1 1.84.361l.08.119l2.1 3.5l.087.171a1.4 1.4 0 0 1 0 1.1l-.088.171l-2.1 3.5a1.4 1.4 0 0 1-2.4-1.44l1.67-2.78l-1.67-2.78l-.067-.127a1.394 1.394 0 0 1 .547-1.79zM30 16c0 7.73-6.27 14-14 14S2 23.73 2 16S8.27 2 16 2s14 6.27 14 14',
|
|
69
|
+
},
|
|
70
|
+
'codex': {
|
|
71
|
+
viewBox: '0 0 24 24',
|
|
72
|
+
fillRule: 'evenodd',
|
|
73
|
+
path: 'M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z',
|
|
74
|
+
},
|
|
75
|
+
'claude': {
|
|
76
|
+
viewBox: '0 0 24 24',
|
|
77
|
+
path: 'm4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z',
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ─── Iconoir icons (stroke-based unless fill: true) ─── */
|
|
82
|
+
|
|
83
|
+
const iconoirIcons = {
|
|
84
|
+
'square-dashed': {
|
|
85
|
+
viewBox: '0 0 24 24',
|
|
86
|
+
strokeWidth: '1.5',
|
|
87
|
+
content: '<path d="M7 4H4V7" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 11V13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 4H13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 20H13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M20 11V13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M17 4H20V7" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M7 20H4V17" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M17 20H20V17" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
88
|
+
},
|
|
89
|
+
'key-command': {
|
|
90
|
+
viewBox: '0 0 24 24',
|
|
91
|
+
strokeWidth: '1.5',
|
|
92
|
+
content: '<path d="M9 6V18" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M15 6V18" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M9 6C9 4.34315 7.65685 3 6 3C4.34315 3 3 4.34315 3 6C3 7.65685 4.34315 9 6 9H18C19.6569 9 21 7.65685 21 6C21 4.34315 19.6569 3 18 3C16.3431 3 15 4.34315 15 6" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M9 18C9 19.6569 7.65685 21 6 21C4.34315 21 3 19.6569 3 18C3 16.3431 4.34315 15 6 15H18C19.6569 15 21 16.3431 21 18C21 19.6569 19.6569 21 18 21C16.3431 21 15 19.6569 15 18" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
93
|
+
},
|
|
94
|
+
'plus-circle': {
|
|
95
|
+
viewBox: '0 0 24 24',
|
|
96
|
+
strokeWidth: '1.5',
|
|
97
|
+
content: '<path d="M8 12H12M16 12H12M12 12V8M12 12V16" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
98
|
+
},
|
|
99
|
+
'plus-circle-solid': {
|
|
100
|
+
viewBox: '0 0 24 24',
|
|
101
|
+
fill: true,
|
|
102
|
+
content: '<path fill-rule="evenodd" clip-rule="evenodd" d="M12 1.25C6.06294 1.25 1.25 6.06294 1.25 12C1.25 17.9371 6.06294 22.75 12 22.75C17.9371 22.75 22.75 17.9371 22.75 12C22.75 6.06294 17.9371 1.25 12 1.25ZM12.75 8C12.75 7.58579 12.4142 7.25 12 7.25C11.5858 7.25 11.25 7.58579 11.25 8V11.25H8C7.58579 11.25 7.25 11.5858 7.25 12C7.25 12.4142 7.58579 12.75 8 12.75H11.25V16C11.25 16.4142 11.5858 16.75 12 16.75C12.4142 16.75 12.75 16.4142 12.75 16V12.75H16C16.4142 12.75 16.75 12.4142 16.75 12C16.75 11.5858 16.4142 11.25 16 11.25H12.75V8Z" fill="currentColor"/>',
|
|
103
|
+
},
|
|
104
|
+
'grid-plus': {
|
|
105
|
+
viewBox: '0 0 24 24',
|
|
106
|
+
strokeWidth: '1.5',
|
|
107
|
+
content: '<path d="M13.9922 17H16.9922M19.9922 17H16.9922M16.9922 17V14M16.9922 17V20" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 9.4V4.6C4 4.26863 4.26863 4 4.6 4H9.4C9.73137 4 10 4.26863 10 4.6V9.4C10 9.73137 9.73137 10 9.4 10H4.6C4.26863 10 4 9.73137 4 9.4Z" stroke="currentColor" stroke-width="1.5"/><path d="M4 19.4V14.6C4 14.2686 4.26863 14 4.6 14H9.4C9.73137 14 10 14.2686 10 14.6V19.4C10 19.7314 9.73137 20 9.4 20H4.6C4.26863 20 4 19.7314 4 19.4Z" stroke="currentColor" stroke-width="1.5"/><path d="M14 9.4V4.6C14 4.26863 14.2686 4 14.6 4H19.4C19.7314 4 20 4.26863 20 4.6V9.4C20 9.73137 19.7314 10 19.4 10H14.6C14.2686 10 14 9.73137 14 9.4Z" stroke="currentColor" stroke-width="1.5"/>',
|
|
108
|
+
},
|
|
109
|
+
'view-grid': {
|
|
110
|
+
viewBox: '0 0 24 24',
|
|
111
|
+
strokeWidth: '1.5',
|
|
112
|
+
content: '<path d="M14 20.4V14.6C14 14.2686 14.2686 14 14.6 14H20.4C20.7314 14 21 14.2686 21 14.6V20.4C21 20.7314 20.7314 21 20.4 21H14.6C14.2686 21 14 20.7314 14 20.4Z" stroke="currentColor" stroke-width="1.5"/><path d="M3 20.4V14.6C3 14.2686 3.26863 14 3.6 14H9.4C9.73137 14 10 14.2686 10 14.6V20.4C10 20.7314 9.73137 21 9.4 21H3.6C3.26863 21 3 20.7314 3 20.4Z" stroke="currentColor" stroke-width="1.5"/><path d="M14 9.4V3.6C14 3.26863 14.2686 3 14.6 3H20.4C20.7314 3 21 3.26863 21 3.6V9.4C21 9.73137 20.7314 10 20.4 10H14.6C14.2686 10 14 9.73137 14 9.4Z" stroke="currentColor" stroke-width="1.5"/><path d="M3 9.4V3.6C3 3.26863 3.26863 3 3.6 3H9.4C9.73137 3 10 3.26863 10 3.6V9.4C10 9.73137 9.73137 10 9.4 10H3.6C3.26863 10 3 9.73137 3 9.4Z" stroke="currentColor" stroke-width="1.5"/>',
|
|
113
|
+
},
|
|
114
|
+
'select-point-3d': {
|
|
115
|
+
viewBox: '0 0 24 24',
|
|
116
|
+
strokeWidth: '1.5',
|
|
117
|
+
content: '<path d="M12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12C11 12.5523 11.4477 13 12 13Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M21 7.35304L21 16.647C21 16.8649 20.8819 17.0656 20.6914 17.1715L12.2914 21.8381C12.1102 21.9388 11.8898 21.9388 11.7086 21.8381L3.30861 17.1715C3.11814 17.0656 3 16.8649 3 16.647L2.99998 7.35304C2.99998 7.13514 3.11812 6.93437 3.3086 6.82855L11.7086 2.16188C11.8898 2.06121 12.1102 2.06121 12.2914 2.16188L20.6914 6.82855C20.8818 6.93437 21 7.13514 21 7.35304Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
118
|
+
},
|
|
119
|
+
'square-3d-three-points': {
|
|
120
|
+
viewBox: '0 0 24 24',
|
|
121
|
+
strokeWidth: '1.5',
|
|
122
|
+
content: '<path d="M3 21V3.6C3 3.26863 3.26863 3 3.6 3H21" stroke="currentColor"/><path d="M17 21H20.4C20.7314 21 21 20.7314 21 20.4V17" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M21 7V9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M21 12V14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M7 21H9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 21H14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4C3.55228 4 4 3.55228 4 3C4 2.44772 3.55228 2 3 2C2.44772 2 2 2.44772 2 3C2 3.55228 2.44772 4 3 4Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 22C3.55228 22 4 21.5523 4 21C4 20.4477 3.55228 20 3 20C2.44772 20 2 20.4477 2 21C2 21.5523 2.44772 22 3 22Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M21 4C21.5523 4 22 3.55228 22 3C22 2.44772 21.5523 2 21 2C20.4477 2 20 2.44772 20 3C20 3.55228 20.4477 4 21 4Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
123
|
+
},
|
|
124
|
+
'white-flag': {
|
|
125
|
+
viewBox: '0 0 24 24',
|
|
126
|
+
strokeWidth: '1.5',
|
|
127
|
+
content: '<path d="M5 15L5.95039 4.54568C5.97849 4.23663 6.23761 4 6.54793 4H20.343C20.6958 4 20.9725 4.30295 20.9405 4.65432L20.0496 14.4543C20.0215 14.7634 19.7624 15 19.4521 15H5ZM5 15L4.4 21" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
128
|
+
},
|
|
129
|
+
'light-bulb': {
|
|
130
|
+
viewBox: '0 0 24 24',
|
|
131
|
+
strokeWidth: '1.5',
|
|
132
|
+
content: '<path d="M9 18H15" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 21H14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M9.00082 15C9.00098 13 8.50098 12.5 7.50082 11.5C6.50067 10.5 6.02422 9.48689 6.00082 8C5.95284 4.95029 8.00067 3 12.0008 3C16.001 3 18.0488 4.95029 18.0008 8C17.9774 9.48689 17.5007 10.5 16.5008 11.5C15.501 12.5 15.001 13 15.0008 15" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
133
|
+
},
|
|
134
|
+
'light-bulb-off': {
|
|
135
|
+
viewBox: '0 0 24 24',
|
|
136
|
+
strokeWidth: '1.5',
|
|
137
|
+
content: '<path d="M9 18H15" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 21H14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M16.4999 11.5C17.4997 10.5 17.9765 9.48689 17.9999 8C18.0479 4.95029 16 3 11.9999 3C10.8324 3 9.83119 3.16613 8.99988 3.47724" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M8.99985 15C9 13 8.5 12.5 7.49985 11.5C6.4997 10.5 6.02324 9.48689 5.99985 8C5.99142 7.46458 6.0476 6.96304 6.1676 6.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 3L21 21" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
138
|
+
},
|
|
139
|
+
'keyframes': {
|
|
140
|
+
viewBox: '0 0 24 24',
|
|
141
|
+
strokeWidth: '1.5',
|
|
142
|
+
content: '<path d="M13.8476 13.317L9.50515 18.2798C8.70833 19.1905 7.29167 19.1905 6.49485 18.2798L2.15238 13.317C1.49259 12.563 1.49259 11.437 2.15238 10.683L6.49485 5.72018C7.29167 4.80952 8.70833 4.80952 9.50515 5.72017L13.8476 10.683C14.5074 11.437 14.5074 12.563 13.8476 13.317Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 19L17.8844 13.3016C18.5263 12.5526 18.5263 11.4474 17.8844 10.6984L13 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M17 19L21.8844 13.3016C22.5263 12.5526 22.5263 11.4474 21.8844 10.6984L17 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
143
|
+
},
|
|
144
|
+
'keyframes-couple-solid': {
|
|
145
|
+
viewBox: '0 0 24 24',
|
|
146
|
+
fill: true,
|
|
147
|
+
content: '<path fill-rule="evenodd" clip-rule="evenodd" d="M14.0658 5.18029L12.5606 6.87362L11.4395 5.87707L12.9447 4.18374C14.0386 2.95308 15.9614 2.95308 17.0554 4.18373L22.3794 10.1733C23.3056 11.2152 23.3057 12.7855 22.3795 13.8273L17.0554 19.8169C15.9614 21.0476 14.0386 21.0477 12.9447 19.8169L11.4395 18.1236L12.5606 17.1271L14.0658 18.8204C14.563 19.3798 15.437 19.3798 15.9342 18.8204L21.2583 12.8308C21.6793 12.3572 21.6793 11.6435 21.2584 11.17L15.9343 5.18029C15.437 4.6209 14.563 4.6209 14.0658 5.18029" fill="currentColor"/><path d="M6.94474 4.18374C8.03866 2.95307 9.96152 2.95308 11.0555 4.18374L16.3795 10.1733C17.3057 11.2152 17.3058 12.7855 16.3796 13.8273L11.0555 19.8169C9.96155 21.0476 8.03866 21.0477 6.94474 19.8169L1.62067 13.8273C0.694507 12.7855 0.694485 11.2152 1.62064 10.1734L6.94474 4.18374Z" fill="currentColor"/>',
|
|
148
|
+
},
|
|
149
|
+
'keyframe': {
|
|
150
|
+
viewBox: '0 0 24 24',
|
|
151
|
+
strokeWidth: '1.5',
|
|
152
|
+
content: '<path d="M20.777 13.3453L13.4799 21.3721C12.6864 22.245 11.3136 22.245 10.5201 21.3721L3.22304 13.3453C2.52955 12.5825 2.52955 11.4175 3.22304 10.6547L10.5201 2.62787C11.3136 1.755 12.6864 1.755 13.4799 2.62787L20.777 10.6547C21.4705 11.4175 21.4705 12.5825 20.777 13.3453Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
153
|
+
},
|
|
154
|
+
'wrench': {
|
|
155
|
+
viewBox: '0 0 24 24',
|
|
156
|
+
strokeWidth: '1.5',
|
|
157
|
+
content: '<path d="M10.0503 10.6066L2.97923 17.6777C2.19818 18.4587 2.19818 19.725 2.97923 20.5061V20.5061C3.76027 21.2871 5.0266 21.2871 5.80765 20.5061L12.8787 13.435" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><path d="M10.0502 10.6066C9.20638 8.45358 9.37134 5.6286 11.1109 3.88909C12.8504 2.14957 16.0606 1.76777 17.8284 2.82843L14.7877 5.8691L14.5051 8.98014L17.6161 8.69753L20.6568 5.65685C21.7175 7.42462 21.3357 10.6349 19.5961 12.3744C17.8566 14.1139 15.0316 14.2789 12.8786 13.435" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* ─── React Component ─── */
|
|
162
|
+
|
|
163
|
+
import octicons from '@primer/octicons'
|
|
164
|
+
import feather from 'feather-icons'
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @param {object} props
|
|
168
|
+
* @param {string} props.name - Namespaced icon name: primer/, feather/, iconoir/, or plain custom name
|
|
169
|
+
* @param {number} [props.size=16]
|
|
170
|
+
* @param {string} [props.label] - Accessible label (sets aria-label instead of aria-hidden)
|
|
171
|
+
* @param {string} [props.color]
|
|
172
|
+
* @param {number} [props.offsetX=0]
|
|
173
|
+
* @param {number} [props.offsetY=0]
|
|
174
|
+
* @param {number} [props.rotate=0]
|
|
175
|
+
* @param {boolean} [props.flipX=false]
|
|
176
|
+
* @param {boolean} [props.flipY=false]
|
|
177
|
+
* @param {number} [props.strokeWeight] - Override stroke width
|
|
178
|
+
* @param {number} [props.scale=1]
|
|
179
|
+
* @param {string} [props.className]
|
|
180
|
+
*/
|
|
181
|
+
export default function Icon({
|
|
182
|
+
name, size = 16, label, color,
|
|
183
|
+
offsetX = 0, offsetY = 0, rotate = 0,
|
|
184
|
+
flipX = false, flipY = false,
|
|
185
|
+
strokeWeight, scale = 1, className,
|
|
186
|
+
}) {
|
|
187
|
+
const source = name.includes('/') ? name.split('/')[0] : null
|
|
188
|
+
const iconName = name.includes('/') ? name.slice(name.indexOf('/') + 1) : name
|
|
189
|
+
|
|
190
|
+
const ariaProps = label ? { 'aria-label': label, role: 'img' } : { 'aria-hidden': true }
|
|
191
|
+
|
|
192
|
+
// Build wrapper style with all transform props
|
|
193
|
+
const scaleX = (flipX ? -1 : 1) * scale
|
|
194
|
+
const scaleY = (flipY ? -1 : 1) * scale
|
|
195
|
+
const hasTransform = offsetX || offsetY || rotate || flipX || flipY || scale !== 1
|
|
196
|
+
const wrapperStyle = {
|
|
197
|
+
...(color ? { color } : {}),
|
|
198
|
+
display: 'inline-flex',
|
|
199
|
+
...(hasTransform ? {
|
|
200
|
+
translate: (offsetX || offsetY) ? `${offsetX}px ${offsetY}px` : undefined,
|
|
201
|
+
rotate: rotate ? `${rotate}deg` : undefined,
|
|
202
|
+
scale: (flipX || flipY || scale !== 1) ? `${scaleX} ${scaleY}` : undefined,
|
|
203
|
+
} : {}),
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let svgContent = null
|
|
207
|
+
|
|
208
|
+
// Custom icons (no source prefix)
|
|
209
|
+
const custom = !source ? customIcons[iconName] : null
|
|
210
|
+
if (custom) {
|
|
211
|
+
if (custom.path) {
|
|
212
|
+
svgContent = (
|
|
213
|
+
<svg width={size} height={size} viewBox={custom.viewBox} fill="currentColor" {...ariaProps}>
|
|
214
|
+
<path d={custom.path} fillRule={custom.fillRule} clipRule={custom.fillRule} />
|
|
215
|
+
</svg>
|
|
216
|
+
)
|
|
217
|
+
} else if (custom.strokePaths) {
|
|
218
|
+
svgContent = (
|
|
219
|
+
<svg width={size} height={size} viewBox={custom.viewBox} fill="none" stroke="currentColor" strokeWidth={strokeWeight ?? custom.strokeWidth ?? '1.5'} strokeLinecap="round" strokeLinejoin="round" {...ariaProps}>
|
|
220
|
+
{custom.strokePaths.map((d, i) => <path key={i} d={d} />)}
|
|
221
|
+
</svg>
|
|
222
|
+
)
|
|
223
|
+
} else if (custom.strokeRect || custom.fillPaths) {
|
|
224
|
+
svgContent = (
|
|
225
|
+
<svg width={size} height={size} viewBox={custom.viewBox} fill="none" stroke="currentColor" strokeWidth={strokeWeight ?? '2'} {...ariaProps}>
|
|
226
|
+
{custom.strokeRect && <rect {...custom.strokeRect} />}
|
|
227
|
+
{custom.fillPaths?.map((d, i) => <path key={i} d={d} fill="currentColor" stroke="none" />)}
|
|
228
|
+
</svg>
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Primer Octicons
|
|
234
|
+
if (!svgContent && source === 'primer') {
|
|
235
|
+
const octicon = octicons[iconName]
|
|
236
|
+
if (octicon) {
|
|
237
|
+
const html = octicon.toSVG({
|
|
238
|
+
width: size, height: size,
|
|
239
|
+
fill: 'currentColor',
|
|
240
|
+
...(label ? { 'aria-label': label } : { 'aria-hidden': 'true' }),
|
|
241
|
+
})
|
|
242
|
+
svgContent = <span dangerouslySetInnerHTML={{ __html: html }} />
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Feather Icons
|
|
247
|
+
if (!svgContent && source === 'feather') {
|
|
248
|
+
const icon = feather.icons[iconName]
|
|
249
|
+
if (icon) {
|
|
250
|
+
const html = icon.toSvg({
|
|
251
|
+
width: size, height: size,
|
|
252
|
+
'stroke-width': strokeWeight ?? 2,
|
|
253
|
+
...(label ? { 'aria-label': label } : { 'aria-hidden': 'true' }),
|
|
254
|
+
})
|
|
255
|
+
svgContent = <span dangerouslySetInnerHTML={{ __html: html }} />
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Iconoir icons
|
|
260
|
+
if (!svgContent && source === 'iconoir') {
|
|
261
|
+
const iconoir = iconoirIcons[iconName]
|
|
262
|
+
if (iconoir) {
|
|
263
|
+
const sw = strokeWeight ?? iconoir.strokeWidth
|
|
264
|
+
svgContent = (
|
|
265
|
+
<svg
|
|
266
|
+
width={size} height={size} viewBox={iconoir.viewBox}
|
|
267
|
+
fill={iconoir.fill ? 'currentColor' : 'none'}
|
|
268
|
+
strokeWidth={iconoir.fill ? undefined : sw}
|
|
269
|
+
{...ariaProps}
|
|
270
|
+
dangerouslySetInnerHTML={{ __html: iconoir.content }}
|
|
271
|
+
/>
|
|
272
|
+
)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (!svgContent) return null
|
|
277
|
+
|
|
278
|
+
return <span className={className} style={wrapperStyle}>{svgContent}</span>
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export { Icon }
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
.sb-mode-switch {
|
|
2
|
+
position: fixed;
|
|
3
|
+
bottom: 20px;
|
|
4
|
+
left: 50%;
|
|
5
|
+
transform: translateX(-50%);
|
|
6
|
+
z-index: 9999;
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
gap: 0;
|
|
10
|
+
background: var(--bgColor-muted, #161b22);
|
|
11
|
+
border: 1px solid var(--borderColor-default, #30363d);
|
|
12
|
+
border-radius: 999px;
|
|
13
|
+
padding: 4px;
|
|
14
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
15
|
+
font-family: "Hubot Sans", -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
html.storyboard-mode-present .sb-mode-switch,
|
|
19
|
+
html.storyboard-mode-plan .sb-mode-switch,
|
|
20
|
+
html.storyboard-mode-inspect .sb-mode-switch {
|
|
21
|
+
background: color-mix(in srgb, var(--sb--mode-color) 40%, black);
|
|
22
|
+
transition: background 0.2s ease;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.sb-mode-btn {
|
|
26
|
+
appearance: none;
|
|
27
|
+
border: none;
|
|
28
|
+
background: transparent;
|
|
29
|
+
color: var(--fgColor-muted, #848d97);
|
|
30
|
+
font-size: 13px;
|
|
31
|
+
font-weight: 500;
|
|
32
|
+
padding: 6px 14px;
|
|
33
|
+
border-radius: 999px;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
line-height: 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.sb-mode-btn:hover {
|
|
41
|
+
color: var(--fgColor-default, #e6edf3);
|
|
42
|
+
background: var(--bgColor-neutral-muted, rgba(110, 118, 129, 0.1));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.sb-mode-btn-active {
|
|
46
|
+
background: var(--bgColor-accent-muted, rgba(56, 139, 253, 0.15));
|
|
47
|
+
color: var(--fgColor-accent, #58a6ff);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.sb-mode-btn-active:hover {
|
|
51
|
+
background: var(--bgColor-accent-muted, rgba(56, 139, 253, 0.2));
|
|
52
|
+
color: var(--fgColor-accent, #58a6ff);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Mode-aware button colors */
|
|
56
|
+
html.storyboard-mode-prototype .sb-mode-btn,
|
|
57
|
+
html.storyboard-mode-present .sb-mode-btn,
|
|
58
|
+
html.storyboard-mode-plan .sb-mode-btn,
|
|
59
|
+
html.storyboard-mode-inspect .sb-mode-btn {
|
|
60
|
+
color: rgba(255, 255, 255, 0.7);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
html.storyboard-mode-prototype .sb-mode-btn:hover,
|
|
64
|
+
html.storyboard-mode-present .sb-mode-btn:hover,
|
|
65
|
+
html.storyboard-mode-plan .sb-mode-btn:hover,
|
|
66
|
+
html.storyboard-mode-inspect .sb-mode-btn:hover {
|
|
67
|
+
color: #fff;
|
|
68
|
+
background: rgba(255, 255, 255, 0.1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
html.storyboard-mode-prototype .sb-mode-btn-active,
|
|
72
|
+
html.storyboard-mode-present .sb-mode-btn-active,
|
|
73
|
+
html.storyboard-mode-plan .sb-mode-btn-active,
|
|
74
|
+
html.storyboard-mode-inspect .sb-mode-btn-active {
|
|
75
|
+
background: rgba(255, 255, 255, 0.85);
|
|
76
|
+
color: color-mix(in srgb, var(--sb--mode-color) 70%, black);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
html.storyboard-mode-prototype .sb-mode-btn-active:hover,
|
|
80
|
+
html.storyboard-mode-present .sb-mode-btn-active:hover,
|
|
81
|
+
html.storyboard-mode-plan .sb-mode-btn-active:hover,
|
|
82
|
+
html.storyboard-mode-inspect .sb-mode-btn-active:hover {
|
|
83
|
+
background: rgba(255, 255, 255, 0.85);
|
|
84
|
+
color: color-mix(in srgb, var(--sb--mode-color) 70%, black);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Hide when chrome is toggled off via ⌘ + . */
|
|
88
|
+
html.storyboard-chrome-hidden .sb-mode-switch {
|
|
89
|
+
display: none;
|
|
90
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModeSwitch — segmented toggle for switching between design modes.
|
|
3
|
+
*
|
|
4
|
+
* Renders as a fixed pill at the bottom-center of the viewport.
|
|
5
|
+
* Only visible when two or more modes are registered.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useSyncExternalStore } from 'react'
|
|
9
|
+
import './ModeSwitch.css'
|
|
10
|
+
import { modeState, switchMode } from '../stores/modeStore.js'
|
|
11
|
+
|
|
12
|
+
function subscribeModeState(callback) {
|
|
13
|
+
return modeState.subscribe(callback)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getSnapshotModeState() {
|
|
17
|
+
let current
|
|
18
|
+
const unsub = modeState.subscribe((v) => { current = v })
|
|
19
|
+
unsub()
|
|
20
|
+
return current
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function ModeSwitch() {
|
|
24
|
+
const state = useSyncExternalStore(subscribeModeState, getSnapshotModeState)
|
|
25
|
+
|
|
26
|
+
if (!state?.switcherVisible || !state?.modes || state.modes.length < 2) {
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className="sb-mode-switch" role="tablist" aria-label="Design mode">
|
|
32
|
+
{state.modes.map((m) => (
|
|
33
|
+
<button
|
|
34
|
+
key={m.name}
|
|
35
|
+
role="tab"
|
|
36
|
+
aria-selected={state.mode === m.name}
|
|
37
|
+
className={`sb-mode-btn${state.mode === m.name ? ' sb-mode-btn-active' : ''}`}
|
|
38
|
+
onClick={() => switchMode(m.name)}
|
|
39
|
+
>
|
|
40
|
+
{m.label}
|
|
41
|
+
</button>
|
|
42
|
+
))}
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default ModeSwitch
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
.sb-toolbar-shell {
|
|
2
|
+
position: fixed;
|
|
3
|
+
right: 20px;
|
|
4
|
+
bottom: 80px;
|
|
5
|
+
z-index: 9998;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
gap: 8px;
|
|
9
|
+
align-items: flex-end;
|
|
10
|
+
font-family: "Mona Sans", -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.sb-toolbar {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: 2px;
|
|
17
|
+
background: var(--bgColor-muted, #161b22);
|
|
18
|
+
border: 1px solid var(--borderColor-default, #30363d);
|
|
19
|
+
border-radius: 12px;
|
|
20
|
+
padding: 4px;
|
|
21
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sb-tool-btn {
|
|
25
|
+
appearance: none;
|
|
26
|
+
border: none;
|
|
27
|
+
background: transparent;
|
|
28
|
+
color: var(--fgColor-muted, #848d97);
|
|
29
|
+
font-size: 12px;
|
|
30
|
+
font-weight: 500;
|
|
31
|
+
padding: 6px 10px;
|
|
32
|
+
border-radius: 8px;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
35
|
+
white-space: nowrap;
|
|
36
|
+
text-align: left;
|
|
37
|
+
line-height: 1;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
gap: 6px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.sb-tool-btn:hover:not(:disabled) {
|
|
44
|
+
color: var(--fgColor-default, #e6edf3);
|
|
45
|
+
background: var(--bgColor-neutral-muted, rgba(110, 118, 129, 0.1));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sb-tool-btn:disabled {
|
|
49
|
+
opacity: 0.4;
|
|
50
|
+
cursor: default;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.sb-tool-btn-active {
|
|
54
|
+
color: var(--fgColor-default, #e6edf3);
|
|
55
|
+
background: var(--bgColor-neutral-muted, rgba(110, 118, 129, 0.15));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.sb-tool-btn-busy {
|
|
59
|
+
opacity: 0.6;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.sb-tool-badge {
|
|
63
|
+
font-size: 10px;
|
|
64
|
+
font-weight: 600;
|
|
65
|
+
background: var(--bgColor-accent-muted, rgba(56, 139, 253, 0.15));
|
|
66
|
+
color: var(--fgColor-accent, #58a6ff);
|
|
67
|
+
padding: 1px 5px;
|
|
68
|
+
border-radius: 10px;
|
|
69
|
+
line-height: 1.2;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.sb-toolbar-label {
|
|
73
|
+
font-size: 10px;
|
|
74
|
+
font-weight: 600;
|
|
75
|
+
text-transform: uppercase;
|
|
76
|
+
letter-spacing: 0.05em;
|
|
77
|
+
color: var(--fgColor-muted, #848d97);
|
|
78
|
+
padding: 4px 10px 2px;
|
|
79
|
+
opacity: 0.6;
|
|
80
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ToolbarShell — right-side toolbar container with two stacked groups:
|
|
3
|
+
* 1. Mode-specific tools (group: 'tools')
|
|
4
|
+
* 2. Developer tools (group: 'dev')
|
|
5
|
+
*
|
|
6
|
+
* Reads from the tool store, which sources from the declarative tool
|
|
7
|
+
* registry (modes.config.json) + runtime state (setToolState/setToolAction).
|
|
8
|
+
*
|
|
9
|
+
* Fixed to the right side of the viewport, above the ModeSwitch.
|
|
10
|
+
* Only renders when the current mode has visible tools.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import React, { useSyncExternalStore } from 'react'
|
|
14
|
+
import './ToolbarShell.css'
|
|
15
|
+
import { toolState } from '../stores/toolStore.js'
|
|
16
|
+
|
|
17
|
+
function subscribeToolState(callback) {
|
|
18
|
+
return toolState.subscribe(callback)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getSnapshotToolState() {
|
|
22
|
+
let current
|
|
23
|
+
const unsub = toolState.subscribe((v) => { current = v })
|
|
24
|
+
unsub()
|
|
25
|
+
return current
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function handleClick(tool) {
|
|
29
|
+
if (tool.action && tool.state.enabled && !tool.state.busy) {
|
|
30
|
+
tool.action()
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function ToolButton({ tool }) {
|
|
35
|
+
return (
|
|
36
|
+
<button
|
|
37
|
+
className={
|
|
38
|
+
'sb-tool-btn' +
|
|
39
|
+
(tool.state.active ? ' sb-tool-btn-active' : '') +
|
|
40
|
+
(tool.state.busy ? ' sb-tool-btn-busy' : '')
|
|
41
|
+
}
|
|
42
|
+
onClick={() => handleClick(tool)}
|
|
43
|
+
disabled={!tool.state.enabled || tool.state.busy || !tool.action}
|
|
44
|
+
title={tool.label}
|
|
45
|
+
>
|
|
46
|
+
{tool.label}
|
|
47
|
+
{tool.state.badge != null && (
|
|
48
|
+
<span className="sb-tool-badge">{tool.state.badge}</span>
|
|
49
|
+
)}
|
|
50
|
+
</button>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function ToolbarShell() {
|
|
55
|
+
const state = useSyncExternalStore(subscribeToolState, getSnapshotToolState)
|
|
56
|
+
|
|
57
|
+
if (!state || (state.tools.length === 0 && state.devTools.length === 0)) {
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div className="sb-toolbar-shell">
|
|
63
|
+
{state.tools.length > 0 && (
|
|
64
|
+
<div className="sb-toolbar" role="toolbar" aria-label="Mode tools">
|
|
65
|
+
<span className="sb-toolbar-label">Tools</span>
|
|
66
|
+
{state.tools.map((tool) => (
|
|
67
|
+
<ToolButton key={tool.id} tool={tool} />
|
|
68
|
+
))}
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
|
|
72
|
+
{state.devTools.length > 0 && (
|
|
73
|
+
<div className="sb-toolbar" role="toolbar" aria-label="Developer tools">
|
|
74
|
+
<span className="sb-toolbar-label">Dev</span>
|
|
75
|
+
{state.devTools.map((tool) => (
|
|
76
|
+
<ToolButton key={tool.id} tool={tool} />
|
|
77
|
+
))}
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default ToolbarShell
|