@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,24 +1,24 @@
|
|
|
1
|
-
import Root from "./panel.
|
|
2
|
-
import Content from "./panel-content.
|
|
3
|
-
import Header from "./panel-header.
|
|
4
|
-
import Title from "./panel-title.
|
|
5
|
-
import Body from "./panel-body.
|
|
6
|
-
import Footer from "./panel-footer.
|
|
7
|
-
import Close from "./panel-close.
|
|
1
|
+
import Root from "./panel.jsx";
|
|
2
|
+
import Content from "./panel-content.jsx";
|
|
3
|
+
import Header from "./panel-header.jsx";
|
|
4
|
+
import Title from "./panel-title.jsx";
|
|
5
|
+
import Body from "./panel-body.jsx";
|
|
6
|
+
import Footer from "./panel-footer.jsx";
|
|
7
|
+
import Close from "./panel-close.jsx";
|
|
8
8
|
|
|
9
9
|
export {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
Root,
|
|
11
|
+
Content,
|
|
12
|
+
Header,
|
|
13
|
+
Title,
|
|
14
|
+
Body,
|
|
15
|
+
Footer,
|
|
16
|
+
Close,
|
|
17
|
+
Root as Panel,
|
|
18
|
+
Content as PanelContent,
|
|
19
|
+
Header as PanelHeader,
|
|
20
|
+
Title as PanelTitle,
|
|
21
|
+
Body as PanelBody,
|
|
22
|
+
Footer as PanelFooter,
|
|
23
|
+
Close as PanelClose,
|
|
24
24
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const PanelBody = forwardRef(function PanelBody({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="panel-body" className={cn("flex-1 overflow-auto px-4 py-2", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default PanelBody;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
3
|
+
import { Button } from "../../../components/ui/button/index.js";
|
|
4
|
+
import { X } from "lucide-react";
|
|
5
|
+
|
|
6
|
+
const PanelClose = forwardRef(function PanelClose({ className, ...props }, ref) {
|
|
7
|
+
return (
|
|
8
|
+
<DialogPrimitive.Close asChild data-slot="panel-close">
|
|
9
|
+
<Button ref={ref} variant="ghost" size="icon-sm" className={className} {...props}>
|
|
10
|
+
<X />
|
|
11
|
+
<span className="sr-only">Close</span>
|
|
12
|
+
</Button>
|
|
13
|
+
</DialogPrimitive.Close>
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
export default PanelClose;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
3
|
+
import { cn } from "../../../utils/index.js";
|
|
4
|
+
|
|
5
|
+
const PanelContent = forwardRef(function PanelContent({ className, children, ...props }, ref) {
|
|
6
|
+
return (
|
|
7
|
+
<DialogPrimitive.Portal>
|
|
8
|
+
<DialogPrimitive.Content
|
|
9
|
+
ref={ref}
|
|
10
|
+
data-slot="panel-content"
|
|
11
|
+
onInteractOutside={(e) => e.preventDefault()}
|
|
12
|
+
onFocusOutside={(e) => e.preventDefault()}
|
|
13
|
+
className={cn(
|
|
14
|
+
"font-sans fixed z-[10000] bottom-28 right-6 w-[400px] max-h-[90vh] flex flex-col",
|
|
15
|
+
"bg-popover text-popover-foreground border-3 border-slate-400",
|
|
16
|
+
"rounded-xl shadow-xl overflow-x-hidden overflow-y-auto",
|
|
17
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-bottom-4",
|
|
18
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-bottom-4",
|
|
19
|
+
"duration-150",
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...props}
|
|
23
|
+
>
|
|
24
|
+
{children}
|
|
25
|
+
</DialogPrimitive.Content>
|
|
26
|
+
</DialogPrimitive.Portal>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
export default PanelContent;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const PanelFooter = forwardRef(function PanelFooter({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="panel-footer" className={cn("flex items-center justify-end gap-2 px-4 pt-2 pb-4", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default PanelFooter;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const PanelHeader = forwardRef(function PanelHeader({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="panel-header" className={cn("flex items-center justify-between gap-2 px-4 pt-4 pb-2", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default PanelHeader;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
3
|
+
import { cn } from "../../../utils/index.js";
|
|
4
|
+
|
|
5
|
+
const PanelTitle = forwardRef(function PanelTitle({ className, children, ...props }, ref) {
|
|
6
|
+
return (
|
|
7
|
+
<DialogPrimitive.Title ref={ref} data-slot="panel-title" className={cn("text-sm font-semibold", className)} {...props}>
|
|
8
|
+
{children}
|
|
9
|
+
</DialogPrimitive.Title>
|
|
10
|
+
);
|
|
11
|
+
});
|
|
12
|
+
export default PanelTitle;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import Root from "./popover.
|
|
2
|
-
import Close from "./popover-close.
|
|
3
|
-
import Content from "./popover-content.
|
|
4
|
-
import Description from "./popover-description.
|
|
5
|
-
import Header from "./popover-header.
|
|
6
|
-
import Title from "./popover-title.
|
|
7
|
-
import Trigger from "./popover-trigger.
|
|
8
|
-
import Portal from "./popover-portal.
|
|
1
|
+
import Root from "./popover.jsx";
|
|
2
|
+
import Close from "./popover-close.jsx";
|
|
3
|
+
import Content from "./popover-content.jsx";
|
|
4
|
+
import Description from "./popover-description.jsx";
|
|
5
|
+
import Header from "./popover-header.jsx";
|
|
6
|
+
import Title from "./popover-title.jsx";
|
|
7
|
+
import Trigger from "./popover-trigger.jsx";
|
|
8
|
+
import Portal from "./popover-portal.jsx";
|
|
9
9
|
|
|
10
10
|
export {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
11
|
+
Root,
|
|
12
|
+
Content,
|
|
13
|
+
Description,
|
|
14
|
+
Header,
|
|
15
|
+
Title,
|
|
16
|
+
Trigger,
|
|
17
|
+
Close,
|
|
18
|
+
Portal,
|
|
19
|
+
//
|
|
20
|
+
Root as Popover,
|
|
21
|
+
Content as PopoverContent,
|
|
22
|
+
Description as PopoverDescription,
|
|
23
|
+
Header as PopoverHeader,
|
|
24
|
+
Title as PopoverTitle,
|
|
25
|
+
Trigger as PopoverTrigger,
|
|
26
|
+
Close as PopoverClose,
|
|
27
|
+
Portal as PopoverPortal,
|
|
28
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
3
|
+
|
|
4
|
+
const PopoverClose = forwardRef(function PopoverClose(props, ref) {
|
|
5
|
+
return <PopoverPrimitive.Close ref={ref} data-slot="popover-close" {...props} />;
|
|
6
|
+
});
|
|
7
|
+
export default PopoverClose;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
3
|
+
import { cn } from "../../../utils/index.js";
|
|
4
|
+
|
|
5
|
+
const PopoverContent = forwardRef(function PopoverContent({ className, sideOffset = 4, align = "center", ...props }, ref) {
|
|
6
|
+
return (
|
|
7
|
+
<PopoverPrimitive.Portal>
|
|
8
|
+
<PopoverPrimitive.Content
|
|
9
|
+
ref={ref}
|
|
10
|
+
data-slot="popover-content"
|
|
11
|
+
sideOffset={sideOffset}
|
|
12
|
+
align={align}
|
|
13
|
+
className={cn(
|
|
14
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm shadow-md ring-1 duration-100 z-50 w-72 origin-(--transform-origin) outline-hidden",
|
|
15
|
+
className
|
|
16
|
+
)}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
</PopoverPrimitive.Portal>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
export default PopoverContent;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const PopoverDescription = forwardRef(function PopoverDescription({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="popover-description" className={cn("text-muted-foreground", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default PopoverDescription;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const PopoverHeader = forwardRef(function PopoverHeader({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="popover-header" className={cn("flex flex-col gap-0.5 text-sm", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default PopoverHeader;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const PopoverTitle = forwardRef(function PopoverTitle({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="popover-title" className={cn("font-medium", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default PopoverTitle;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
3
|
+
import { cn } from "../../../utils/index.js";
|
|
4
|
+
|
|
5
|
+
const PopoverTrigger = forwardRef(function PopoverTrigger({ className, ...props }, ref) {
|
|
6
|
+
return <PopoverPrimitive.Trigger ref={ref} data-slot="popover-trigger" className={cn("", className)} {...props} />;
|
|
7
|
+
});
|
|
8
|
+
export default PopoverTrigger;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearchableList — a filterable list with an auto-focused search input.
|
|
3
|
+
*
|
|
4
|
+
* Designed to work inside dropdown menus and popovers. Prevents printable-key
|
|
5
|
+
* events from bubbling so host menus (e.g. Radix typeahead) don't hijack input.
|
|
6
|
+
* Navigation keys (arrows, escape, tab) still bubble for menu keyboard nav.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <SearchableList
|
|
10
|
+
* items={items}
|
|
11
|
+
* filterFn={(item, query) => item.name.toLowerCase().includes(query)}
|
|
12
|
+
* renderItem={(item) => <MenuItem key={item.id}>{item.name}</MenuItem>}
|
|
13
|
+
* placeholder="Filter…"
|
|
14
|
+
* />
|
|
15
|
+
*/
|
|
16
|
+
import { useState, useRef, useEffect, useMemo, useCallback, forwardRef } from 'react'
|
|
17
|
+
import { Input } from './input/index.js'
|
|
18
|
+
import { cn } from '../../utils/index.js'
|
|
19
|
+
|
|
20
|
+
/** Keys that should always bubble to the parent menu for navigation. */
|
|
21
|
+
const PASSTHROUGH_KEYS = new Set([
|
|
22
|
+
'Escape', 'Tab', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight',
|
|
23
|
+
'Home', 'End', 'Enter', 'PageUp', 'PageDown',
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {Object} props
|
|
28
|
+
* @param {Array} props.items - Items to display and filter
|
|
29
|
+
* @param {(item: any, query: string) => boolean} props.filterFn - Filter predicate (query is pre-lowercased)
|
|
30
|
+
* @param {(item: any, index: number) => React.ReactNode} props.renderItem - Render each item
|
|
31
|
+
* @param {string} [props.placeholder='Search…'] - Input placeholder
|
|
32
|
+
* @param {string} [props.emptyMessage='No results'] - Shown when filter yields no results
|
|
33
|
+
* @param {string} [props.loadingMessage='Loading…'] - Shown while loading
|
|
34
|
+
* @param {boolean} [props.loading=false] - Whether items are still loading
|
|
35
|
+
* @param {React.ReactNode} [props.header] - Slot rendered between input and results (always visible)
|
|
36
|
+
* @param {boolean} [props.autoFocus=true] - Focus the input on mount
|
|
37
|
+
* @param {string} [props.className] - Wrapper className
|
|
38
|
+
* @param {string} [props.listClassName] - Scrollable results area className
|
|
39
|
+
* @param {React.RefObject} [props.inputRef] - External ref for the input element
|
|
40
|
+
*/
|
|
41
|
+
const SearchableList = forwardRef(function SearchableList(
|
|
42
|
+
{
|
|
43
|
+
items = [],
|
|
44
|
+
filterFn,
|
|
45
|
+
renderItem,
|
|
46
|
+
placeholder = 'Search…',
|
|
47
|
+
emptyMessage = 'No results',
|
|
48
|
+
loadingMessage = 'Loading…',
|
|
49
|
+
loading = false,
|
|
50
|
+
header,
|
|
51
|
+
autoFocus = true,
|
|
52
|
+
className,
|
|
53
|
+
listClassName,
|
|
54
|
+
inputRef: externalInputRef,
|
|
55
|
+
},
|
|
56
|
+
ref,
|
|
57
|
+
) {
|
|
58
|
+
const [query, setQuery] = useState('')
|
|
59
|
+
const internalInputRef = useRef(null)
|
|
60
|
+
const inputRef = externalInputRef || internalInputRef
|
|
61
|
+
const listRef = useRef(null)
|
|
62
|
+
|
|
63
|
+
// Auto-focus the input on mount — double rAF lets the host menu
|
|
64
|
+
// finish its own focus management before we steal focus.
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!autoFocus) return
|
|
67
|
+
const outer = requestAnimationFrame(() => {
|
|
68
|
+
requestAnimationFrame(() => {
|
|
69
|
+
inputRef.current?.focus()
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
return () => cancelAnimationFrame(outer)
|
|
73
|
+
}, [autoFocus])
|
|
74
|
+
|
|
75
|
+
const filteredItems = useMemo(() => {
|
|
76
|
+
const q = query.trim().toLowerCase()
|
|
77
|
+
if (!q || !filterFn) return items
|
|
78
|
+
return items.filter((item) => filterFn(item, q))
|
|
79
|
+
}, [items, query, filterFn])
|
|
80
|
+
|
|
81
|
+
// Handle keyboard navigation between input and list.
|
|
82
|
+
// Printable keys are suppressed so Radix typeahead doesn't intercept them.
|
|
83
|
+
const handleKeyDown = useCallback((e) => {
|
|
84
|
+
// ArrowDown from input → focus first menu item in results
|
|
85
|
+
if (e.key === 'ArrowDown') {
|
|
86
|
+
const firstItem = listRef.current?.querySelector('[role="menuitem"]')
|
|
87
|
+
if (firstItem) {
|
|
88
|
+
e.preventDefault()
|
|
89
|
+
e.stopPropagation()
|
|
90
|
+
firstItem.focus()
|
|
91
|
+
}
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
// Tab from input → focus first menu item (keeps user in the dropdown)
|
|
95
|
+
if (e.key === 'Tab' && !e.shiftKey) {
|
|
96
|
+
const firstItem = listRef.current?.querySelector('[role="menuitem"]')
|
|
97
|
+
if (firstItem) {
|
|
98
|
+
e.preventDefault()
|
|
99
|
+
e.stopPropagation()
|
|
100
|
+
firstItem.focus()
|
|
101
|
+
}
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
if (!PASSTHROUGH_KEYS.has(e.key)) {
|
|
105
|
+
e.stopPropagation()
|
|
106
|
+
}
|
|
107
|
+
}, [])
|
|
108
|
+
|
|
109
|
+
// Shift+Tab from any list item → return focus to the input
|
|
110
|
+
const handleListKeyDown = useCallback((e) => {
|
|
111
|
+
if (e.key === 'Tab' && e.shiftKey) {
|
|
112
|
+
e.preventDefault()
|
|
113
|
+
e.stopPropagation()
|
|
114
|
+
inputRef.current?.focus()
|
|
115
|
+
}
|
|
116
|
+
}, [])
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div ref={ref} className={cn('flex flex-col', className)}>
|
|
120
|
+
{/* Search input — pinned at top */}
|
|
121
|
+
<div
|
|
122
|
+
className="px-2 pt-1 pb-1.5"
|
|
123
|
+
onKeyDown={handleKeyDown}
|
|
124
|
+
onPointerDown={(e) => e.stopPropagation()}
|
|
125
|
+
>
|
|
126
|
+
<Input
|
|
127
|
+
ref={inputRef}
|
|
128
|
+
type="text"
|
|
129
|
+
value={query}
|
|
130
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
131
|
+
placeholder={placeholder}
|
|
132
|
+
autoComplete="off"
|
|
133
|
+
spellCheck={false}
|
|
134
|
+
className="h-9 text-xs rounded"
|
|
135
|
+
aria-label={placeholder}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
{/* Optional header slot (e.g. "Create new…" button) — always visible */}
|
|
140
|
+
{header}
|
|
141
|
+
|
|
142
|
+
{/* Scrollable results area */}
|
|
143
|
+
<div ref={listRef} className={cn('overflow-y-auto', listClassName)} onKeyDown={handleListKeyDown}>
|
|
144
|
+
{loading ? (
|
|
145
|
+
<p className="px-2 py-3 text-xs text-muted-foreground text-center">{loadingMessage}</p>
|
|
146
|
+
) : filteredItems.length > 0 ? (
|
|
147
|
+
filteredItems.map(renderItem)
|
|
148
|
+
) : query.trim() ? (
|
|
149
|
+
<p className="px-2 py-3 text-xs text-muted-foreground text-center">{emptyMessage}</p>
|
|
150
|
+
) : items.length === 0 ? (
|
|
151
|
+
<p className="px-2 py-3 text-xs text-muted-foreground text-center">No items</p>
|
|
152
|
+
) : null}
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
export { SearchableList }
|
|
159
|
+
export default SearchableList
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import Root from "./select.
|
|
2
|
-
import Group from "./select-group.
|
|
3
|
-
import Label from "./select-label.
|
|
4
|
-
import Item from "./select-item.
|
|
5
|
-
import Content from "./select-content.
|
|
6
|
-
import Trigger from "./select-trigger.
|
|
7
|
-
import Separator from "./select-separator.
|
|
8
|
-
import ScrollDownButton from "./select-scroll-down-button.
|
|
9
|
-
import ScrollUpButton from "./select-scroll-up-button.
|
|
10
|
-
import GroupHeading from "./select-group-heading.
|
|
11
|
-
import Portal from "./select-portal.
|
|
1
|
+
import Root from "./select.jsx";
|
|
2
|
+
import Group from "./select-group.jsx";
|
|
3
|
+
import Label from "./select-label.jsx";
|
|
4
|
+
import Item from "./select-item.jsx";
|
|
5
|
+
import Content from "./select-content.jsx";
|
|
6
|
+
import Trigger from "./select-trigger.jsx";
|
|
7
|
+
import Separator from "./select-separator.jsx";
|
|
8
|
+
import ScrollDownButton from "./select-scroll-down-button.jsx";
|
|
9
|
+
import ScrollUpButton from "./select-scroll-up-button.jsx";
|
|
10
|
+
import GroupHeading from "./select-group-heading.jsx";
|
|
11
|
+
import Portal from "./select-portal.jsx";
|
|
12
12
|
|
|
13
13
|
export {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
14
|
+
Root,
|
|
15
|
+
Group,
|
|
16
|
+
Label,
|
|
17
|
+
Item,
|
|
18
|
+
Content,
|
|
19
|
+
Trigger,
|
|
20
|
+
Separator,
|
|
21
|
+
ScrollDownButton,
|
|
22
|
+
ScrollUpButton,
|
|
23
|
+
GroupHeading,
|
|
24
|
+
Portal,
|
|
25
|
+
//
|
|
26
|
+
Root as Select,
|
|
27
|
+
Group as SelectGroup,
|
|
28
|
+
Label as SelectLabel,
|
|
29
|
+
Item as SelectItem,
|
|
30
|
+
Content as SelectContent,
|
|
31
|
+
Trigger as SelectTrigger,
|
|
32
|
+
Separator as SelectSeparator,
|
|
33
|
+
ScrollDownButton as SelectScrollDownButton,
|
|
34
|
+
ScrollUpButton as SelectScrollUpButton,
|
|
35
|
+
GroupHeading as SelectGroupHeading,
|
|
36
|
+
Portal as SelectPortal,
|
|
37
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
|
+
import SelectScrollUpButton from "./select-scroll-up-button.jsx";
|
|
4
|
+
import SelectScrollDownButton from "./select-scroll-down-button.jsx";
|
|
5
|
+
import { cn } from "../../../utils/index.js";
|
|
6
|
+
|
|
7
|
+
const SelectContent = forwardRef(function SelectContent({ className, children, sideOffset = 4, position = "popper", ...props }, ref) {
|
|
8
|
+
return (
|
|
9
|
+
<SelectPrimitive.Portal>
|
|
10
|
+
<SelectPrimitive.Content
|
|
11
|
+
ref={ref}
|
|
12
|
+
data-slot="select-content"
|
|
13
|
+
sideOffset={sideOffset}
|
|
14
|
+
position={position}
|
|
15
|
+
className={cn(
|
|
16
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-lg shadow-md ring-1 duration-100 relative isolate z-50 overflow-x-hidden overflow-y-auto",
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
<SelectScrollUpButton />
|
|
22
|
+
<SelectPrimitive.Viewport className="w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1">
|
|
23
|
+
{children}
|
|
24
|
+
</SelectPrimitive.Viewport>
|
|
25
|
+
<SelectScrollDownButton />
|
|
26
|
+
</SelectPrimitive.Content>
|
|
27
|
+
</SelectPrimitive.Portal>
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
export default SelectContent;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
|
+
import { cn } from "../../../utils/index.js";
|
|
4
|
+
|
|
5
|
+
const SelectGroupHeading = forwardRef(function SelectGroupHeading({ className, children, ...props }, ref) {
|
|
6
|
+
return (
|
|
7
|
+
<SelectPrimitive.Label
|
|
8
|
+
ref={ref}
|
|
9
|
+
data-slot="select-group-heading"
|
|
10
|
+
className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
|
|
11
|
+
{...props}
|
|
12
|
+
>
|
|
13
|
+
{children}
|
|
14
|
+
</SelectPrimitive.Label>
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
export default SelectGroupHeading;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
|
+
import { cn } from "../../../utils/index.js";
|
|
4
|
+
|
|
5
|
+
const SelectGroup = forwardRef(function SelectGroup({ className, ...props }, ref) {
|
|
6
|
+
return (
|
|
7
|
+
<SelectPrimitive.Group
|
|
8
|
+
ref={ref}
|
|
9
|
+
data-slot="select-group"
|
|
10
|
+
className={cn("scroll-my-1 p-1", className)}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
export default SelectGroup;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
|
+
import { Check } from "lucide-react";
|
|
4
|
+
import { cn } from "../../../utils/index.js";
|
|
5
|
+
|
|
6
|
+
const SelectItem = forwardRef(function SelectItem({ className, children, ...props }, ref) {
|
|
7
|
+
return (
|
|
8
|
+
<SelectPrimitive.Item
|
|
9
|
+
ref={ref}
|
|
10
|
+
data-slot="select-item"
|
|
11
|
+
className={cn(
|
|
12
|
+
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 focus:bg-accent data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground focus:text-accent-foreground relative flex w-full cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<span className="absolute end-2 flex size-3.5 items-center justify-center">
|
|
18
|
+
<SelectPrimitive.ItemIndicator>
|
|
19
|
+
<Check className="cn-select-item-indicator-icon" />
|
|
20
|
+
</SelectPrimitive.ItemIndicator>
|
|
21
|
+
</span>
|
|
22
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
23
|
+
</SelectPrimitive.Item>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
export default SelectItem;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../utils/index.js";
|
|
3
|
+
|
|
4
|
+
const SelectLabel = forwardRef(function SelectLabel({ className, children, ...props }, ref) {
|
|
5
|
+
return (
|
|
6
|
+
<div ref={ref} data-slot="select-label" className={cn("text-muted-foreground px-1.5 py-1 text-xs", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
export default SelectLabel;
|