@atmos.build/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/components/alert-dialog.d.ts +14 -0
- package/dist/components/alert-dialog.js +40 -0
- package/dist/components/at-search.d.ts +35 -0
- package/dist/components/at-search.js +57 -0
- package/dist/components/attachment-thumbnail-stack.d.ts +13 -0
- package/dist/components/attachment-thumbnail-stack.js +23 -0
- package/dist/components/audio-preview.d.ts +33 -0
- package/dist/components/audio-preview.js +176 -0
- package/dist/components/avatar-uploader.d.ts +29 -0
- package/dist/components/avatar-uploader.js +67 -0
- package/dist/components/avatar.d.ts +12 -0
- package/dist/components/avatar.js +38 -0
- package/dist/components/badge.d.ts +9 -0
- package/dist/components/badge.js +25 -0
- package/dist/components/button-group.d.ts +12 -0
- package/dist/components/button-group.js +29 -0
- package/dist/components/button.d.ts +10 -0
- package/dist/components/button.js +42 -0
- package/dist/components/calendar.d.ts +26 -0
- package/dist/components/calendar.js +154 -0
- package/dist/components/channel-list.d.ts +33 -0
- package/dist/components/channel-list.js +40 -0
- package/dist/components/charts/area-chart.d.ts +2 -0
- package/dist/components/charts/area-chart.js +5 -0
- package/dist/components/charts/bar-chart.d.ts +2 -0
- package/dist/components/charts/bar-chart.js +58 -0
- package/dist/components/charts/colors.d.ts +2 -0
- package/dist/components/charts/colors.js +42 -0
- package/dist/components/charts/hover.d.ts +20 -0
- package/dist/components/charts/hover.js +31 -0
- package/dist/components/charts/index.d.ts +10 -0
- package/dist/components/charts/index.js +9 -0
- package/dist/components/charts/layout.d.ts +35 -0
- package/dist/components/charts/layout.js +101 -0
- package/dist/components/charts/legend.d.ts +6 -0
- package/dist/components/charts/legend.js +7 -0
- package/dist/components/charts/line-area-chart.d.ts +4 -0
- package/dist/components/charts/line-area-chart.js +86 -0
- package/dist/components/charts/line-chart.d.ts +2 -0
- package/dist/components/charts/line-chart.js +5 -0
- package/dist/components/charts/pie-chart.d.ts +2 -0
- package/dist/components/charts/pie-chart.js +22 -0
- package/dist/components/charts/radar-chart.d.ts +2 -0
- package/dist/components/charts/radar-chart.js +29 -0
- package/dist/components/charts/radial-chart.d.ts +2 -0
- package/dist/components/charts/radial-chart.js +19 -0
- package/dist/components/charts/scatter-chart.d.ts +2 -0
- package/dist/components/charts/scatter-chart.js +16 -0
- package/dist/components/charts/story-data.d.ts +24 -0
- package/dist/components/charts/story-data.js +48 -0
- package/dist/components/charts/types.d.ts +43 -0
- package/dist/components/charts/types.js +1 -0
- package/dist/components/checkbox.d.ts +4 -0
- package/dist/components/checkbox.js +10 -0
- package/dist/components/chip.d.ts +25 -0
- package/dist/components/chip.js +36 -0
- package/dist/components/code-editor-theme.d.ts +19 -0
- package/dist/components/code-editor-theme.js +100 -0
- package/dist/components/collapsible-section-header.d.ts +82 -0
- package/dist/components/collapsible-section-header.js +82 -0
- package/dist/components/collection-view/collection-view-group-settings.d.ts +73 -0
- package/dist/components/collection-view/collection-view-group-settings.js +55 -0
- package/dist/components/collection-view/collection-view-settings.d.ts +115 -0
- package/dist/components/collection-view/collection-view-settings.js +146 -0
- package/dist/components/collection-view/collection-view.d.ts +87 -0
- package/dist/components/collection-view/collection-view.js +95 -0
- package/dist/components/collection-view/index.d.ts +6 -0
- package/dist/components/collection-view/index.js +6 -0
- package/dist/components/collection-view/use-collection-detail-navigation.d.ts +11 -0
- package/dist/components/collection-view/use-collection-detail-navigation.js +12 -0
- package/dist/components/collection-view/use-collection-escape.d.ts +9 -0
- package/dist/components/collection-view/use-collection-escape.js +20 -0
- package/dist/components/collection-view/use-collection-selection.d.ts +42 -0
- package/dist/components/collection-view/use-collection-selection.js +203 -0
- package/dist/components/color-picker.d.ts +18 -0
- package/dist/components/color-picker.js +77 -0
- package/dist/components/color-swatch-list.d.ts +16 -0
- package/dist/components/color-swatch-list.js +60 -0
- package/dist/components/combobox/combobox.d.ts +4 -0
- package/dist/components/combobox/combobox.js +70 -0
- package/dist/components/combobox/compound.d.ts +68 -0
- package/dist/components/combobox/compound.js +151 -0
- package/dist/components/combobox/context.d.ts +34 -0
- package/dist/components/combobox/context.js +123 -0
- package/dist/components/combobox/create-step.d.ts +12 -0
- package/dist/components/combobox/create-step.js +8 -0
- package/dist/components/combobox/index.d.ts +10 -0
- package/dist/components/combobox/index.js +5 -0
- package/dist/components/combobox/inline-create-form.d.ts +24 -0
- package/dist/components/combobox/inline-create-form.js +43 -0
- package/dist/components/combobox/types.d.ts +57 -0
- package/dist/components/combobox/types.js +10 -0
- package/dist/components/command.d.ts +35 -0
- package/dist/components/command.js +76 -0
- package/dist/components/comment-pin.d.ts +13 -0
- package/dist/components/comment-pin.js +33 -0
- package/dist/components/confidence-meter.d.ts +11 -0
- package/dist/components/confidence-meter.js +24 -0
- package/dist/components/context-menu.d.ts +31 -0
- package/dist/components/context-menu.js +54 -0
- package/dist/components/copy-button.d.ts +12 -0
- package/dist/components/copy-button.js +32 -0
- package/dist/components/date-picker.d.ts +29 -0
- package/dist/components/date-picker.js +86 -0
- package/dist/components/date-tile.d.ts +11 -0
- package/dist/components/date-tile.js +16 -0
- package/dist/components/date-time-picker.d.ts +25 -0
- package/dist/components/date-time-picker.js +153 -0
- package/dist/components/detail-breadcrumb-utils.d.ts +2 -0
- package/dist/components/detail-breadcrumb-utils.js +18 -0
- package/dist/components/detail-nav-bar.d.ts +28 -0
- package/dist/components/detail-nav-bar.js +28 -0
- package/dist/components/detail-top-bar.d.ts +49 -0
- package/dist/components/detail-top-bar.js +41 -0
- package/dist/components/dialog.d.ts +22 -0
- package/dist/components/dialog.js +51 -0
- package/dist/components/dropdown-menu.d.ts +29 -0
- package/dist/components/dropdown-menu.js +52 -0
- package/dist/components/editable-doc-title.d.ts +17 -0
- package/dist/components/editable-doc-title.js +147 -0
- package/dist/components/empty-state.d.ts +12 -0
- package/dist/components/empty-state.js +6 -0
- package/dist/components/filter-condition-editor.d.ts +18 -0
- package/dist/components/filter-condition-editor.js +102 -0
- package/dist/components/form-dialog.d.ts +30 -0
- package/dist/components/form-dialog.js +52 -0
- package/dist/components/formula-editor.d.ts +18 -0
- package/dist/components/formula-editor.js +154 -0
- package/dist/components/hover-card.d.ts +52 -0
- package/dist/components/hover-card.js +51 -0
- package/dist/components/icon-button.d.ts +15 -0
- package/dist/components/icon-button.js +18 -0
- package/dist/components/inline-alert.d.ts +11 -0
- package/dist/components/inline-alert.js +17 -0
- package/dist/components/input.d.ts +3 -0
- package/dist/components/input.js +7 -0
- package/dist/components/kanban-board.d.ts +27 -0
- package/dist/components/kanban-board.js +145 -0
- package/dist/components/kbd.d.ts +3 -0
- package/dist/components/kbd.js +8 -0
- package/dist/components/label.d.ts +4 -0
- package/dist/components/label.js +9 -0
- package/dist/components/markdown-editor/index.d.ts +4 -0
- package/dist/components/markdown-editor/index.js +2 -0
- package/dist/components/markdown-editor/markdown-editor.d.ts +16 -0
- package/dist/components/markdown-editor/markdown-editor.js +53 -0
- package/dist/components/markdown-editor/serialize.d.ts +12 -0
- package/dist/components/markdown-editor/serialize.js +122 -0
- package/dist/components/markdown-editor/vim.d.ts +8 -0
- package/dist/components/markdown-editor/vim.js +394 -0
- package/dist/components/metric-grid.d.ts +41 -0
- package/dist/components/metric-grid.js +39 -0
- package/dist/components/microphone-priority.d.ts +29 -0
- package/dist/components/microphone-priority.js +15 -0
- package/dist/components/middle-truncate.d.ts +6 -0
- package/dist/components/middle-truncate.js +15 -0
- package/dist/components/multi-combobox.d.ts +48 -0
- package/dist/components/multi-combobox.js +221 -0
- package/dist/components/naut-avatar-engine.d.ts +83 -0
- package/dist/components/naut-avatar-engine.js +803 -0
- package/dist/components/naut-avatar.d.ts +31 -0
- package/dist/components/naut-avatar.js +108 -0
- package/dist/components/navigable-list.d.ts +4 -0
- package/dist/components/navigable-list.js +20 -0
- package/dist/components/note-icon-picker.d.ts +20 -0
- package/dist/components/note-icon-picker.js +84 -0
- package/dist/components/note-icon.d.ts +690 -0
- package/dist/components/note-icon.js +353 -0
- package/dist/components/note-row.d.ts +33 -0
- package/dist/components/note-row.js +29 -0
- package/dist/components/overlapping-dots.d.ts +10 -0
- package/dist/components/overlapping-dots.js +13 -0
- package/dist/components/overview-card.d.ts +12 -0
- package/dist/components/overview-card.js +9 -0
- package/dist/components/panel-header.d.ts +8 -0
- package/dist/components/panel-header.js +6 -0
- package/dist/components/panel-section-states.d.ts +9 -0
- package/dist/components/panel-section-states.js +10 -0
- package/dist/components/person-avatar.d.ts +10 -0
- package/dist/components/person-avatar.js +23 -0
- package/dist/components/photo-avatar.d.ts +11 -0
- package/dist/components/photo-avatar.js +24 -0
- package/dist/components/picker-field.d.ts +23 -0
- package/dist/components/picker-field.js +24 -0
- package/dist/components/popover-stack.d.ts +26 -0
- package/dist/components/popover-stack.js +89 -0
- package/dist/components/popover.d.ts +12 -0
- package/dist/components/popover.js +31 -0
- package/dist/components/portal-login-barrier.d.ts +12 -0
- package/dist/components/portal-login-barrier.js +41 -0
- package/dist/components/presence-dot.d.ts +8 -0
- package/dist/components/presence-dot.js +15 -0
- package/dist/components/presence-overlay.d.ts +27 -0
- package/dist/components/presence-overlay.js +34 -0
- package/dist/components/property-list.d.ts +64 -0
- package/dist/components/property-list.js +313 -0
- package/dist/components/property-panel.d.ts +54 -0
- package/dist/components/property-panel.js +87 -0
- package/dist/components/property-selector.d.ts +36 -0
- package/dist/components/property-selector.js +141 -0
- package/dist/components/provenance-chip.d.ts +12 -0
- package/dist/components/provenance-chip.js +17 -0
- package/dist/components/qr-code.d.ts +13 -0
- package/dist/components/qr-code.js +42 -0
- package/dist/components/qr-encode.d.ts +2 -0
- package/dist/components/qr-encode.js +469 -0
- package/dist/components/quantity-stepper.d.ts +25 -0
- package/dist/components/quantity-stepper.js +43 -0
- package/dist/components/radio-group.d.ts +5 -0
- package/dist/components/radio-group.js +13 -0
- package/dist/components/rename-dialog.d.ts +19 -0
- package/dist/components/rename-dialog.js +35 -0
- package/dist/components/row-surface.d.ts +1 -0
- package/dist/components/row-surface.js +5 -0
- package/dist/components/row-trailing.d.ts +30 -0
- package/dist/components/row-trailing.js +59 -0
- package/dist/components/run-status-badge.d.ts +16 -0
- package/dist/components/run-status-badge.js +43 -0
- package/dist/components/scroll-area.d.ts +5 -0
- package/dist/components/scroll-area.js +12 -0
- package/dist/components/select.d.ts +15 -0
- package/dist/components/select.js +39 -0
- package/dist/components/selectable-card.d.ts +33 -0
- package/dist/components/selectable-card.js +66 -0
- package/dist/components/separator.d.ts +3 -0
- package/dist/components/separator.js +8 -0
- package/dist/components/settings-dialog-shell.d.ts +46 -0
- package/dist/components/settings-dialog-shell.js +48 -0
- package/dist/components/shimmer-text.d.ts +8 -0
- package/dist/components/shimmer-text.js +26 -0
- package/dist/components/side-panel-tokens.d.ts +27 -0
- package/dist/components/side-panel-tokens.js +26 -0
- package/dist/components/side-panel.d.ts +94 -0
- package/dist/components/side-panel.js +106 -0
- package/dist/components/skeleton.d.ts +2 -0
- package/dist/components/skeleton.js +6 -0
- package/dist/components/sortable.d.ts +65 -0
- package/dist/components/sortable.js +110 -0
- package/dist/components/spec-strip.d.ts +18 -0
- package/dist/components/spec-strip.js +15 -0
- package/dist/components/speech-playback.d.ts +25 -0
- package/dist/components/speech-playback.js +35 -0
- package/dist/components/sql-editor.d.ts +13 -0
- package/dist/components/sql-editor.js +228 -0
- package/dist/components/stat-tile.d.ts +7 -0
- package/dist/components/stat-tile.js +6 -0
- package/dist/components/status-badge.d.ts +17 -0
- package/dist/components/status-badge.js +8 -0
- package/dist/components/status-tone.d.ts +9 -0
- package/dist/components/status-tone.js +10 -0
- package/dist/components/sticky-header-fade.d.ts +8 -0
- package/dist/components/sticky-header-fade.js +11 -0
- package/dist/components/swatch-button.d.ts +14 -0
- package/dist/components/swatch-button.js +25 -0
- package/dist/components/switch.d.ts +6 -0
- package/dist/components/switch.js +9 -0
- package/dist/components/system-load/index.d.ts +6 -0
- package/dist/components/system-load/index.js +6 -0
- package/dist/components/system-load/load-block.d.ts +20 -0
- package/dist/components/system-load/load-block.js +23 -0
- package/dist/components/system-load/load-grid.d.ts +16 -0
- package/dist/components/system-load/load-grid.js +23 -0
- package/dist/components/system-load/load-meter.d.ts +25 -0
- package/dist/components/system-load/load-meter.js +29 -0
- package/dist/components/system-load/load-tone.d.ts +21 -0
- package/dist/components/system-load/load-tone.js +29 -0
- package/dist/components/system-load/meter-row.d.ts +31 -0
- package/dist/components/system-load/meter-row.js +29 -0
- package/dist/components/system-load/resource-meter.d.ts +19 -0
- package/dist/components/system-load/resource-meter.js +15 -0
- package/dist/components/tab-title-bar.d.ts +12 -0
- package/dist/components/tab-title-bar.js +9 -0
- package/dist/components/table.d.ts +10 -0
- package/dist/components/table.js +29 -0
- package/dist/components/tabs.d.ts +11 -0
- package/dist/components/tabs.js +97 -0
- package/dist/components/template-chip-input.d.ts +36 -0
- package/dist/components/template-chip-input.js +271 -0
- package/dist/components/template-input.d.ts +24 -0
- package/dist/components/template-input.js +57 -0
- package/dist/components/terminal-spinner.d.ts +11 -0
- package/dist/components/terminal-spinner.js +48 -0
- package/dist/components/textarea.d.ts +3 -0
- package/dist/components/textarea.js +7 -0
- package/dist/components/time-column.d.ts +24 -0
- package/dist/components/time-column.js +60 -0
- package/dist/components/timestamped-transcript.d.ts +38 -0
- package/dist/components/timestamped-transcript.js +29 -0
- package/dist/components/timezone-picker.d.ts +22 -0
- package/dist/components/timezone-picker.js +60 -0
- package/dist/components/tooltip.d.ts +11 -0
- package/dist/components/tooltip.js +29 -0
- package/dist/components/transcription-overlay.d.ts +47 -0
- package/dist/components/transcription-overlay.js +30 -0
- package/dist/components/usage-bar.d.ts +17 -0
- package/dist/components/usage-bar.js +26 -0
- package/dist/components/view-query-bar.d.ts +13 -0
- package/dist/components/view-query-bar.js +13 -0
- package/dist/components/view-query-controls.d.ts +159 -0
- package/dist/components/view-query-controls.js +109 -0
- package/dist/components/view-save-menu.d.ts +20 -0
- package/dist/components/view-save-menu.js +13 -0
- package/dist/components/view-sort-editor.d.ts +40 -0
- package/dist/components/view-sort-editor.js +47 -0
- package/dist/components/voice-line.d.ts +37 -0
- package/dist/components/voice-line.js +293 -0
- package/dist/components/weekly-schedule-editor.d.ts +15 -0
- package/dist/components/weekly-schedule-editor.js +28 -0
- package/dist/flow/canvas/canvas-frame.d.ts +160 -0
- package/dist/flow/canvas/canvas-frame.js +521 -0
- package/dist/flow/canvas/collaborator-layer.d.ts +12 -0
- package/dist/flow/canvas/collaborator-layer.js +43 -0
- package/dist/flow/canvas/connector-edge.d.ts +22 -0
- package/dist/flow/canvas/connector-edge.js +61 -0
- package/dist/flow/canvas/editor-context.d.ts +23 -0
- package/dist/flow/canvas/editor-context.js +6 -0
- package/dist/flow/canvas/graph-core.d.ts +60 -0
- package/dist/flow/canvas/graph-core.js +296 -0
- package/dist/flow/canvas/minimap-sticky-overlay.d.ts +4 -0
- package/dist/flow/canvas/minimap-sticky-overlay.js +45 -0
- package/dist/flow/canvas/node-card.d.ts +46 -0
- package/dist/flow/canvas/node-card.js +56 -0
- package/dist/flow/canvas/node-library.d.ts +40 -0
- package/dist/flow/canvas/node-library.js +54 -0
- package/dist/flow/canvas/sticky-notes.d.ts +25 -0
- package/dist/flow/canvas/sticky-notes.js +101 -0
- package/dist/flow/collaborative-graph-presence.d.ts +28 -0
- package/dist/flow/collaborative-graph-presence.js +55 -0
- package/dist/flow/collaborative-graph-sync.d.ts +40 -0
- package/dist/flow/collaborative-graph-sync.js +127 -0
- package/dist/flow/editor/adapter.d.ts +64 -0
- package/dist/flow/editor/adapter.js +1 -0
- package/dist/flow/editor/command-registry.d.ts +10 -0
- package/dist/flow/editor/command-registry.js +35 -0
- package/dist/flow/editor/dag-canvas.d.ts +18 -0
- package/dist/flow/editor/dag-canvas.js +33 -0
- package/dist/flow/editor/flow-editor.d.ts +54 -0
- package/dist/flow/editor/flow-editor.js +199 -0
- package/dist/flow/editor/issues-popover.d.ts +11 -0
- package/dist/flow/editor/issues-popover.js +70 -0
- package/dist/flow/editor/library-rail.d.ts +19 -0
- package/dist/flow/editor/library-rail.js +25 -0
- package/dist/flow/editor/make-controller.d.ts +18 -0
- package/dist/flow/editor/make-controller.js +44 -0
- package/dist/flow/editor/node-chip.d.ts +2 -0
- package/dist/flow/editor/node-chip.js +16 -0
- package/dist/flow/editor/save-publish-bar.d.ts +27 -0
- package/dist/flow/editor/save-publish-bar.js +14 -0
- package/dist/flow/editor/settings-dialog.d.ts +11 -0
- package/dist/flow/editor/settings-dialog.js +11 -0
- package/dist/flow/editor/settings-shell.d.ts +21 -0
- package/dist/flow/editor/settings-shell.js +20 -0
- package/dist/flow/editor/side-rail.d.ts +22 -0
- package/dist/flow/editor/side-rail.js +15 -0
- package/dist/flow/editor/use-dag-editor.d.ts +94 -0
- package/dist/flow/editor/use-dag-editor.js +502 -0
- package/dist/flow/index.d.ts +25 -0
- package/dist/flow/index.js +25 -0
- package/dist/flow/presence-motion.d.ts +10 -0
- package/dist/flow/presence-motion.js +88 -0
- package/dist/flow/styles.css +1 -0
- package/dist/flow/use-collaborative-graph.d.ts +61 -0
- package/dist/flow/use-collaborative-graph.js +396 -0
- package/dist/flow/use-debounced-value.d.ts +1 -0
- package/dist/flow/use-debounced-value.js +10 -0
- package/dist/hooks/use-detail-nav.d.ts +11 -0
- package/dist/hooks/use-detail-nav.js +49 -0
- package/dist/hooks/use-flush-on-hide.d.ts +1 -0
- package/dist/hooks/use-flush-on-hide.js +21 -0
- package/dist/hooks/use-media-query.d.ts +1 -0
- package/dist/hooks/use-media-query.js +20 -0
- package/dist/hooks/use-virtualizer.d.ts +1 -0
- package/dist/hooks/use-virtualizer.js +1 -0
- package/dist/index.d.ts +139 -0
- package/dist/index.js +139 -0
- package/dist/lib/brand-style.d.ts +6 -0
- package/dist/lib/brand-style.js +16 -0
- package/dist/lib/cn.d.ts +2 -0
- package/dist/lib/cn.js +5 -0
- package/dist/lib/composited-glint.d.ts +7 -0
- package/dist/lib/composited-glint.js +98 -0
- package/dist/lib/date-time-format.d.ts +2 -0
- package/dist/lib/date-time-format.js +21 -0
- package/dist/lib/disclosure-state.d.ts +11 -0
- package/dist/lib/disclosure-state.js +22 -0
- package/dist/lib/label-swatches.d.ts +10 -0
- package/dist/lib/label-swatches.js +24 -0
- package/dist/lib/local-ui-state.d.ts +10 -0
- package/dist/lib/local-ui-state.js +95 -0
- package/dist/lib/parse-loose-datetime.d.ts +1 -0
- package/dist/lib/parse-loose-datetime.js +180 -0
- package/dist/lib/parse-loose-time.d.ts +6 -0
- package/dist/lib/parse-loose-time.js +53 -0
- package/dist/lib/parse-loose.d.ts +1 -0
- package/dist/lib/parse-loose.js +170 -0
- package/dist/lib/react-19-jsx.d.ts +8 -0
- package/dist/lib/react-19-jsx.js +1 -0
- package/dist/lib/view-chrome.d.ts +5 -0
- package/dist/lib/view-chrome.js +5 -0
- package/dist/lib/view-query/config.d.ts +26 -0
- package/dist/lib/view-query/config.js +162 -0
- package/dist/lib/view-query/evaluate.d.ts +11 -0
- package/dist/lib/view-query/evaluate.js +196 -0
- package/dist/lib/view-query/group-order.d.ts +25 -0
- package/dist/lib/view-query/group-order.js +49 -0
- package/dist/lib/view-query/index.d.ts +6 -0
- package/dist/lib/view-query/index.js +6 -0
- package/dist/lib/view-query/model.d.ts +34 -0
- package/dist/lib/view-query/model.js +88 -0
- package/dist/lib/view-query/sort.d.ts +7 -0
- package/dist/lib/view-query/sort.js +30 -0
- package/dist/lib/view-query/types.d.ts +70 -0
- package/dist/lib/view-query/types.js +12 -0
- package/dist/lib/weekly-schedule.d.ts +8 -0
- package/dist/lib/weekly-schedule.js +10 -0
- package/dist/mcp-app/index.d.ts +4 -0
- package/dist/mcp-app/index.js +3 -0
- package/dist/mcp-app/shadcn.css +629 -0
- package/dist/mcp-app/styles.css +72 -0
- package/dist/mcp-app/theme.d.ts +2 -0
- package/dist/mcp-app/theme.js +62 -0
- package/dist/mcp-app/use-atmos-mcp-app.d.ts +109 -0
- package/dist/mcp-app/use-atmos-mcp-app.js +30 -0
- package/dist/mcp-app/vite.d.ts +7 -0
- package/dist/mcp-app/vite.js +30 -0
- package/dist/tokens/index.d.ts +7 -0
- package/dist/tokens/index.js +7 -0
- package/dist/tokens/semantic.css +110 -0
- package/dist/tokens/tokens.css +195 -0
- package/package.json +98 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../lib/cn.js';
|
|
5
|
+
const TONE_TEXT = {
|
|
6
|
+
neutral: 'text-foreground',
|
|
7
|
+
success: 'text-success-9',
|
|
8
|
+
warning: 'text-warning-9',
|
|
9
|
+
danger: 'text-danger-9',
|
|
10
|
+
};
|
|
11
|
+
export function MetricSectionHeading({ title, hint, action, className, ...props }) {
|
|
12
|
+
return (_jsxs("div", { "data-slot": "metric-section-heading", className: cn('mb-2.5 flex flex-wrap items-start justify-between gap-2', className), ...props, children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "text-[13px] font-medium", children: title }), hint ? (_jsx("p", { className: "text-muted-foreground mt-0.5 text-[11.5px] leading-snug", children: hint })) : null] }), action] }));
|
|
13
|
+
}
|
|
14
|
+
export function MetricGrid({ className, ...props }) {
|
|
15
|
+
return (_jsx("div", { "data-slot": "metric-grid", className: cn('bg-background grid gap-px overflow-hidden rounded-xl', className), ...props }));
|
|
16
|
+
}
|
|
17
|
+
const PANEL_PADDING = { none: '', sm: 'p-3', md: 'p-4' };
|
|
18
|
+
export function MetricPanel({ title, action, padding = 'md', className, children, ...props }) {
|
|
19
|
+
return (_jsxs("div", { "data-slot": "metric-panel", className: cn('bg-muted min-w-0', PANEL_PADDING[padding], className), ...props, children: [title || action ? (_jsxs("div", { className: cn('mb-3 flex items-center justify-between gap-2', padding === 'none' && 'px-3 pt-3'), children: [title ? _jsx("p", { className: "text-xs font-medium", children: title }) : _jsx("span", {}), action] })) : null, children] }));
|
|
20
|
+
}
|
|
21
|
+
export function MetricTile({ label, value, suffix, hint, tone = 'neutral', className, ...props }) {
|
|
22
|
+
return (_jsxs("div", { "data-slot": "metric-tile", "data-tone": tone, className: cn('bg-muted min-w-0 p-3', className), ...props, children: [label ? _jsx("p", { className: "text-muted-foreground truncate text-xs", children: label }) : null, _jsxs("p", { className: cn('text-2xl font-semibold tracking-tight tabular-nums', label ? 'mt-2' : '', TONE_TEXT[tone]), children: [value, suffix ? (_jsx("span", { className: "text-muted-foreground ml-1 text-xs font-normal", children: suffix })) : null] }), hint ? _jsx("p", { className: "text-muted-foreground mt-1 text-[11px] leading-snug", children: hint }) : null] }));
|
|
23
|
+
}
|
|
24
|
+
const TONE_BAR = {
|
|
25
|
+
neutral: 'bg-foreground/35',
|
|
26
|
+
success: 'bg-success-9/60',
|
|
27
|
+
warning: 'bg-warning-9/60',
|
|
28
|
+
danger: 'bg-danger-9/55',
|
|
29
|
+
};
|
|
30
|
+
export function MetricBreakdown({ title, items, emptyLabel, showBars = false, className, ...props }) {
|
|
31
|
+
return (_jsxs("div", { "data-slot": "metric-breakdown", className: cn('min-w-0', className), ...props, children: [title ? _jsx("h3", { className: "mb-1 text-xs font-medium", children: title }) : null, items.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-xs", children: emptyLabel })) : (_jsx("ul", { className: cn(showBars && 'grid gap-2'), children: items.map((item) => (_jsx("li", { children: _jsx(MetricBreakdownRow, { item: item, showBar: showBars }) }, item.key))) }))] }));
|
|
32
|
+
}
|
|
33
|
+
function MetricBreakdownRow({ item, showBar }) {
|
|
34
|
+
const tone = item.tone ?? 'neutral';
|
|
35
|
+
const row = (_jsxs(_Fragment, { children: [_jsxs("span", { className: "flex items-center justify-between gap-3 text-xs", children: [_jsx("span", { className: cn('min-w-0 truncate', tone === 'neutral' ? 'text-muted-foreground' : TONE_TEXT[tone]), title: item.title, children: item.label }), _jsx("span", { className: "shrink-0 font-mono tabular-nums", children: item.value })] }), showBar ? (_jsx("span", { className: "bg-background mt-1.5 block h-1 overflow-hidden rounded-full", children: _jsx("span", { className: cn('block h-full rounded-full', TONE_BAR[tone]), style: { width: `${Math.round(Math.max(0, Math.min(1, item.fraction ?? 0)) * 100)}%` } }) })) : null] }));
|
|
36
|
+
if (!item.onSelect)
|
|
37
|
+
return _jsx("div", { className: "py-0.5", children: row });
|
|
38
|
+
return (_jsx("button", { type: "button", onClick: item.onSelect, className: "hover:bg-background/60 focus-visible:ring-ring -mx-1.5 block w-[calc(100%+0.75rem)] rounded-sm px-1.5 py-0.5 text-left focus-visible:ring-2 focus-visible:outline-none", children: row }));
|
|
39
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface MicrophonePriorityItem {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
detail?: React.ReactNode;
|
|
6
|
+
level?: number;
|
|
7
|
+
selected?: boolean;
|
|
8
|
+
unavailable?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface MicrophonePriorityLabels {
|
|
11
|
+
list: string;
|
|
12
|
+
unavailable: string;
|
|
13
|
+
selected: string;
|
|
14
|
+
reorder: (microphoneName: string) => string;
|
|
15
|
+
test: (microphoneName: string) => string;
|
|
16
|
+
stopTest: (microphoneName: string) => string;
|
|
17
|
+
level: (microphoneName: string, percentage: number) => string;
|
|
18
|
+
}
|
|
19
|
+
export interface MicrophonePriorityProps extends Omit<React.ComponentProps<'div'>, 'children'> {
|
|
20
|
+
microphones: readonly MicrophonePriorityItem[];
|
|
21
|
+
labels: MicrophonePriorityLabels;
|
|
22
|
+
testingId?: string | null;
|
|
23
|
+
description?: React.ReactNode;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
onReorder: (microphoneIds: string[]) => void;
|
|
26
|
+
onTest?: (microphoneId: string) => void;
|
|
27
|
+
onStopTest?: (microphoneId: string) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare function MicrophonePriority({ microphones, labels, testingId, description, disabled, onReorder, onTest, onStopTest, className, ...props }: MicrophonePriorityProps): React.JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { AlertCircle, Check, Mic, Square } from 'lucide-react';
|
|
5
|
+
import { cn } from '../lib/cn.js';
|
|
6
|
+
import { Button } from './button.js';
|
|
7
|
+
import { DragHandle, SortableList } from './sortable.js';
|
|
8
|
+
export function MicrophonePriority({ microphones, labels, testingId, description, disabled = false, onReorder, onTest, onStopTest, className, ...props }) {
|
|
9
|
+
return (_jsxs("div", { "data-slot": "microphone-priority", className: cn('space-y-2', className), ...props, children: [description ? _jsx("div", { className: "text-muted-foreground text-sm", children: description }) : null, _jsx("div", { role: "list", "aria-label": labels.list, children: _jsx(SortableList, { items: [...microphones], keyOf: (microphone) => microphone.id, handle: true, disabled: disabled, onReorder: (_microphoneId, detail) => onReorder(detail.nextIds), className: "space-y-1.5", renderItem: (microphone, { dragHandleProps, isDragging, overlay }) => {
|
|
10
|
+
const testing = testingId === microphone.id;
|
|
11
|
+
const level = Math.max(0, Math.min(1, microphone.level ?? 0));
|
|
12
|
+
const percentage = Math.round(level * 100);
|
|
13
|
+
return (_jsxs("div", { role: "listitem", "data-microphone-id": microphone.id, "data-testing": testing || undefined, "data-unavailable": microphone.unavailable || undefined, className: cn('border-border bg-card group rounded-xl border p-2 transition-[border-color,box-shadow,opacity] motion-reduce:transition-none', testing && 'border-primary/40 ring-primary/10 ring-2', microphone.unavailable && 'opacity-60', isDragging && 'opacity-40', overlay && 'ring-ring shadow-lg ring-2'), children: [_jsxs("div", { className: "flex min-h-9 items-center gap-2", children: [_jsx(DragHandle, { dragHandleProps: dragHandleProps, "aria-label": labels.reorder(microphone.name), disabled: disabled || microphone.unavailable, className: "size-8 shrink-0 opacity-100" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "truncate text-sm font-medium", children: microphone.name }), microphone.selected ? (_jsx("span", { className: "text-primary inline-flex items-center gap-1 text-xs", "aria-label": labels.selected, children: _jsx(Check, { className: "size-3.5", strokeWidth: 1.5, "aria-hidden": true }) })) : null, microphone.unavailable ? (_jsxs("span", { className: "text-warning inline-flex items-center gap-1 text-xs", children: [_jsx(AlertCircle, { className: "size-3.5", strokeWidth: 1.5, "aria-hidden": true }), labels.unavailable] })) : null] }), microphone.detail ? (_jsx("div", { className: "text-muted-foreground truncate text-xs", children: microphone.detail })) : null] }), testing ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onStopTest?.(microphone.id), disabled: !onStopTest, "aria-label": labels.stopTest(microphone.name), children: [_jsx(Square, { className: "size-3", strokeWidth: 1.5, "aria-hidden": true }), labels.stopTest(microphone.name)] })) : (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onTest?.(microphone.id), disabled: disabled || microphone.unavailable || !onTest, "aria-label": labels.test(microphone.name), children: [_jsx(Mic, { className: "size-3.5", strokeWidth: 1.5, "aria-hidden": true }), labels.test(microphone.name)] }))] }), testing ? (_jsx("div", { role: "meter", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": percentage, "aria-label": labels.level(microphone.name, percentage), className: "bg-muted mt-2 h-1.5 overflow-hidden rounded-full", children: _jsx("div", { className: "bg-primary h-full origin-left rounded-full transition-transform motion-reduce:transition-none", style: { transform: `scaleX(${level})` } }) })) : null] }));
|
|
14
|
+
} }) })] }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../lib/cn.js';
|
|
4
|
+
const FALLBACK_TAIL = 12;
|
|
5
|
+
const MAX_TAIL = 22;
|
|
6
|
+
function trailingSegmentLength(text) {
|
|
7
|
+
const separator = Math.max(text.lastIndexOf('/'), text.lastIndexOf('\\'));
|
|
8
|
+
const segment = separator === -1 ? FALLBACK_TAIL : text.length - separator;
|
|
9
|
+
return Math.min(segment, MAX_TAIL);
|
|
10
|
+
}
|
|
11
|
+
export function MiddleTruncate({ text, tail, className }) {
|
|
12
|
+
const kept = Math.min(text.length, Math.max(0, tail ?? trailingSegmentLength(text)));
|
|
13
|
+
const split = text.length - kept;
|
|
14
|
+
return (_jsxs("span", { title: text, className: cn('flex min-w-0 items-baseline', className), children: [_jsx("span", { className: "min-w-0 truncate", children: text.slice(0, split) }), _jsx("span", { className: "shrink-0 whitespace-pre", children: text.slice(split) })] }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ComboboxLabels } from './combobox/types.js';
|
|
3
|
+
export interface MultiComboboxItem {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
icon?: ReactNode;
|
|
7
|
+
shortcut?: string;
|
|
8
|
+
group?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface MultiComboboxProps {
|
|
11
|
+
open: boolean;
|
|
12
|
+
onOpenChange: (open: boolean) => void;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
items: MultiComboboxItem[];
|
|
16
|
+
values: string[];
|
|
17
|
+
onChange: (next: string[]) => void;
|
|
18
|
+
searchPlaceholder: string;
|
|
19
|
+
triggerKey?: string;
|
|
20
|
+
allowCreate?: boolean;
|
|
21
|
+
onCreate?: (label: string) => void;
|
|
22
|
+
renderCreateStep?: (context: {
|
|
23
|
+
query: string;
|
|
24
|
+
onCreated: (item: {
|
|
25
|
+
id: string;
|
|
26
|
+
}) => void;
|
|
27
|
+
onCancel: () => void;
|
|
28
|
+
}) => ReactNode;
|
|
29
|
+
CreateForm?: (props: {
|
|
30
|
+
initialValue: string;
|
|
31
|
+
onCreated: (item: {
|
|
32
|
+
id: string;
|
|
33
|
+
}) => void;
|
|
34
|
+
onCancel: () => void;
|
|
35
|
+
}) => ReactNode;
|
|
36
|
+
createLabel?: string;
|
|
37
|
+
contentClassName?: string;
|
|
38
|
+
onSearchChange?: (query: string) => void;
|
|
39
|
+
searching?: boolean;
|
|
40
|
+
searchingLabel?: string;
|
|
41
|
+
emptyText?: string;
|
|
42
|
+
labels?: Partial<ComboboxLabels>;
|
|
43
|
+
excludeSelected?: boolean;
|
|
44
|
+
showSelectionIndicator?: boolean;
|
|
45
|
+
triggerAsChild?: boolean;
|
|
46
|
+
'aria-label'?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function MultiCombobox({ open, onOpenChange, children, disabled, items, values, onChange, searchPlaceholder, triggerKey, allowCreate, onCreate, CreateForm, renderCreateStep, createLabel, contentClassName, onSearchChange, searching, searchingLabel, emptyText, labels: labelsProp, excludeSelected, showSelectionIndicator, triggerAsChild, 'aria-label': ariaLabel, }: MultiComboboxProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Fragment, useCallback, useEffect, useId, useMemo, useRef, useState, } from 'react';
|
|
4
|
+
import { Check, Plus } from 'lucide-react';
|
|
5
|
+
import { Slot } from 'radix-ui';
|
|
6
|
+
import { ComboboxCreateStep } from './combobox/create-step.js';
|
|
7
|
+
import { DEFAULT_COMBOBOX_LABELS } from './combobox/types.js';
|
|
8
|
+
import { EmptyState } from './empty-state.js';
|
|
9
|
+
import { Kbd } from './kbd.js';
|
|
10
|
+
import { StackedPopover, StackedPopoverContent, StackedPopoverTrigger, } from './popover-stack.js';
|
|
11
|
+
import { cn } from '../lib/cn.js';
|
|
12
|
+
const CREATE_ROW = '__create__';
|
|
13
|
+
export function MultiCombobox({ open, onOpenChange, children, disabled = false, items, values, onChange, searchPlaceholder, triggerKey, allowCreate = false, onCreate, CreateForm, renderCreateStep, createLabel, contentClassName, onSearchChange, searching = false, searchingLabel, emptyText, labels: labelsProp, excludeSelected = false, showSelectionIndicator = true, triggerAsChild = false, 'aria-label': ariaLabel, }) {
|
|
14
|
+
const labels = { ...DEFAULT_COMBOBOX_LABELS, ...labelsProp };
|
|
15
|
+
const [query, setQuery] = useState('');
|
|
16
|
+
const [activeOverride, setActiveOverride] = useState(null);
|
|
17
|
+
const [mode, setMode] = useState('list');
|
|
18
|
+
const [pinnedSelected, setPinnedSelected] = useState(new Set());
|
|
19
|
+
const prevOpenRef = useRef(false);
|
|
20
|
+
const inputRef = useRef(null);
|
|
21
|
+
const triggerRef = useRef(null);
|
|
22
|
+
const wheelCleanupRef = useRef(null);
|
|
23
|
+
const listId = useId();
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (open && !prevOpenRef.current)
|
|
26
|
+
setPinnedSelected(new Set(values));
|
|
27
|
+
prevOpenRef.current = open;
|
|
28
|
+
}, [open, values]);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (open && mode === 'list')
|
|
31
|
+
inputRef.current?.focus();
|
|
32
|
+
}, [open, mode]);
|
|
33
|
+
const listRefCallback = useCallback((node) => {
|
|
34
|
+
wheelCleanupRef.current?.();
|
|
35
|
+
wheelCleanupRef.current = null;
|
|
36
|
+
if (!node)
|
|
37
|
+
return;
|
|
38
|
+
const stopPropagation = (event) => event.stopPropagation();
|
|
39
|
+
node.addEventListener('wheel', stopPropagation, { passive: true });
|
|
40
|
+
wheelCleanupRef.current = () => node.removeEventListener('wheel', stopPropagation);
|
|
41
|
+
}, []);
|
|
42
|
+
useEffect(() => () => {
|
|
43
|
+
wheelCleanupRef.current?.();
|
|
44
|
+
}, []);
|
|
45
|
+
const selectedSet = useMemo(() => new Set(values), [values]);
|
|
46
|
+
const updateQuery = useCallback((next) => {
|
|
47
|
+
setQuery(next);
|
|
48
|
+
onSearchChange?.(next);
|
|
49
|
+
}, [onSearchChange]);
|
|
50
|
+
const availableItems = useMemo(() => (excludeSelected ? items.filter((item) => !selectedSet.has(item.id)) : items), [excludeSelected, items, selectedSet]);
|
|
51
|
+
const filtered = useMemo(() => {
|
|
52
|
+
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
53
|
+
if (!normalizedQuery)
|
|
54
|
+
return availableItems;
|
|
55
|
+
return availableItems.filter((item) => item.label.toLocaleLowerCase().includes(normalizedQuery));
|
|
56
|
+
}, [availableItems, query]);
|
|
57
|
+
const selectedRows = useMemo(() => filtered.filter((item) => pinnedSelected.has(item.id)), [filtered, pinnedSelected]);
|
|
58
|
+
const remainingRows = useMemo(() => filtered.filter((item) => !pinnedSelected.has(item.id)), [filtered, pinnedSelected]);
|
|
59
|
+
const remainingGroupCount = useMemo(() => new Set(remainingRows.map((item) => item.group).filter(Boolean)).size, [remainingRows]);
|
|
60
|
+
const trimmedQuery = query.trim();
|
|
61
|
+
const hasExactMatch = useMemo(() => {
|
|
62
|
+
if (!trimmedQuery)
|
|
63
|
+
return false;
|
|
64
|
+
const normalizedQuery = trimmedQuery.toLocaleLowerCase();
|
|
65
|
+
return availableItems.some((item) => item.label.toLocaleLowerCase() === normalizedQuery);
|
|
66
|
+
}, [availableItems, trimmedQuery]);
|
|
67
|
+
const hasCreateStep = Boolean(renderCreateStep) || Boolean(CreateForm);
|
|
68
|
+
const canCreate = allowCreate && (Boolean(onCreate) || hasCreateStep);
|
|
69
|
+
const showCreate = canCreate && trimmedQuery.length > 0 && !hasExactMatch;
|
|
70
|
+
const rowIds = useMemo(() => {
|
|
71
|
+
const ids = [...selectedRows, ...remainingRows].map((item) => item.id);
|
|
72
|
+
if (showCreate)
|
|
73
|
+
ids.push(CREATE_ROW);
|
|
74
|
+
return ids;
|
|
75
|
+
}, [remainingRows, selectedRows, showCreate]);
|
|
76
|
+
const activeId = activeOverride && rowIds.includes(activeOverride) ? activeOverride : (rowIds[0] ?? null);
|
|
77
|
+
const handleOpenChange = useCallback((next) => {
|
|
78
|
+
if (next && disabled)
|
|
79
|
+
return;
|
|
80
|
+
if (next && !open) {
|
|
81
|
+
updateQuery('');
|
|
82
|
+
setActiveOverride(null);
|
|
83
|
+
setMode('list');
|
|
84
|
+
}
|
|
85
|
+
onOpenChange(next);
|
|
86
|
+
}, [disabled, onOpenChange, open, updateQuery]);
|
|
87
|
+
const toggle = useCallback((id) => {
|
|
88
|
+
const next = new Set(selectedSet);
|
|
89
|
+
if (next.has(id))
|
|
90
|
+
next.delete(id);
|
|
91
|
+
else
|
|
92
|
+
next.add(id);
|
|
93
|
+
onChange(Array.from(next));
|
|
94
|
+
}, [onChange, selectedSet]);
|
|
95
|
+
const handleCreate = useCallback(() => {
|
|
96
|
+
if (!trimmedQuery)
|
|
97
|
+
return;
|
|
98
|
+
if (renderCreateStep || CreateForm) {
|
|
99
|
+
setMode('create');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!onCreate)
|
|
103
|
+
return;
|
|
104
|
+
onCreate(trimmedQuery);
|
|
105
|
+
updateQuery('');
|
|
106
|
+
setActiveOverride(null);
|
|
107
|
+
}, [CreateForm, onCreate, renderCreateStep, trimmedQuery, updateQuery]);
|
|
108
|
+
const handleCreated = useCallback((item) => {
|
|
109
|
+
const next = new Set(values);
|
|
110
|
+
next.add(item.id);
|
|
111
|
+
onChange(Array.from(next));
|
|
112
|
+
updateQuery('');
|
|
113
|
+
setActiveOverride(null);
|
|
114
|
+
setMode('list');
|
|
115
|
+
}, [onChange, updateQuery, values]);
|
|
116
|
+
const handleKeyDown = useCallback((event) => {
|
|
117
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
118
|
+
if (rowIds.length === 0)
|
|
119
|
+
return;
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
const currentIndex = activeId ? rowIds.indexOf(activeId) : -1;
|
|
122
|
+
const delta = event.key === 'ArrowDown' ? 1 : -1;
|
|
123
|
+
const nextIndex = (currentIndex + delta + rowIds.length) % rowIds.length;
|
|
124
|
+
setActiveOverride(rowIds[nextIndex] ?? null);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if ((event.key === ' ' || event.key === 'Spacebar') && query.length === 0) {
|
|
128
|
+
if (!activeId || activeId === CREATE_ROW)
|
|
129
|
+
return;
|
|
130
|
+
event.preventDefault();
|
|
131
|
+
toggle(activeId);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (event.key === 'Enter') {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
if (activeId === CREATE_ROW || (showCreate && filtered.length === 0)) {
|
|
137
|
+
handleCreate();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (activeId)
|
|
141
|
+
toggle(activeId);
|
|
142
|
+
if (!event.shiftKey)
|
|
143
|
+
handleOpenChange(false);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (event.key === 'Escape') {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
handleOpenChange(false);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (event.key.length === 1 &&
|
|
152
|
+
!event.metaKey &&
|
|
153
|
+
!event.ctrlKey &&
|
|
154
|
+
!event.altKey &&
|
|
155
|
+
query.length === 0) {
|
|
156
|
+
const shortcut = event.key.toLocaleLowerCase();
|
|
157
|
+
const item = availableItems.find((candidate) => candidate.shortcut?.toLocaleLowerCase() === shortcut);
|
|
158
|
+
if (!item)
|
|
159
|
+
return;
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
toggle(item.id);
|
|
162
|
+
}
|
|
163
|
+
}, [
|
|
164
|
+
activeId,
|
|
165
|
+
availableItems,
|
|
166
|
+
filtered.length,
|
|
167
|
+
handleCreate,
|
|
168
|
+
handleOpenChange,
|
|
169
|
+
query.length,
|
|
170
|
+
rowIds,
|
|
171
|
+
showCreate,
|
|
172
|
+
toggle,
|
|
173
|
+
]);
|
|
174
|
+
const activeDomId = activeId ? `${listId}-row-${activeId}` : undefined;
|
|
175
|
+
const inCreateMode = mode === 'create' && hasCreateStep;
|
|
176
|
+
const createStep = renderCreateStep ? (renderCreateStep({
|
|
177
|
+
query: trimmedQuery,
|
|
178
|
+
onCreated: handleCreated,
|
|
179
|
+
onCancel: () => setMode('list'),
|
|
180
|
+
})) : CreateForm ? (_jsx(CreateForm, { initialValue: trimmedQuery, onCreated: handleCreated, onCancel: () => setMode('list') })) : null;
|
|
181
|
+
const renderRow = (item) => {
|
|
182
|
+
const active = activeId === item.id;
|
|
183
|
+
const selected = selectedSet.has(item.id);
|
|
184
|
+
return (_jsxs("li", { id: `${listId}-row-${item.id}`, role: "option", "aria-selected": selected, "data-active": active || undefined, onPointerMove: () => setActiveOverride(item.id), onPointerDown: (event) => {
|
|
185
|
+
if (event.button !== 0 || !event.isPrimary)
|
|
186
|
+
return;
|
|
187
|
+
event.preventDefault();
|
|
188
|
+
toggle(item.id);
|
|
189
|
+
}, className: cn('text-foreground mx-1 flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-[13px]', active && 'bg-muted'), children: [showSelectionIndicator ? (_jsx("span", { "data-slot": "multi-combobox-selection-indicator", className: cn('flex size-3.5 shrink-0 items-center justify-center rounded-sm border', selected
|
|
190
|
+
? 'bg-primary border-primary text-primary-foreground'
|
|
191
|
+
: 'border-border/70 bg-transparent'), "aria-hidden": true, children: selected ? _jsx(Check, { className: "size-2.5", strokeWidth: 2.5 }) : null })) : null, item.icon ? (_jsx("span", { className: "inline-flex shrink-0 items-center justify-center", children: item.icon })) : null, _jsx("span", { className: "min-w-0 flex-1 truncate", children: item.label }), item.shortcut ? _jsx(Kbd, { className: "shrink-0 text-[10.5px]", children: item.shortcut }) : null] }, item.id));
|
|
192
|
+
};
|
|
193
|
+
return (_jsxs(StackedPopover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(StackedPopoverTrigger, { asChild: true, children: triggerAsChild ? (_jsx(Slot.Root, { ref: triggerRef, "aria-disabled": disabled || undefined, "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": listId, onClickCapture: (event) => {
|
|
194
|
+
if (disabled)
|
|
195
|
+
event.preventDefault();
|
|
196
|
+
}, children: children })) : (_jsx("div", { ref: triggerRef, className: "inline-flex w-full", onClickCapture: (event) => {
|
|
197
|
+
if (disabled)
|
|
198
|
+
event.preventDefault();
|
|
199
|
+
}, children: _jsx(Slot.Root, { "aria-disabled": disabled || undefined, "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": listId, children: children }) })) }), _jsx(StackedPopoverContent, { className: cn('relative isolate w-64 gap-0 overflow-hidden p-0', contentClassName), align: "start", "aria-label": ariaLabel, onCloseAutoFocus: (event) => {
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
const trigger = triggerRef.current;
|
|
202
|
+
const focusable = trigger?.matches('button, [tabindex]:not([tabindex="-1"])')
|
|
203
|
+
? trigger
|
|
204
|
+
: trigger?.querySelector('button, [tabindex]:not([tabindex="-1"])');
|
|
205
|
+
focusable?.focus();
|
|
206
|
+
}, onOpenAutoFocus: (event) => {
|
|
207
|
+
event.preventDefault();
|
|
208
|
+
if (mode === 'list')
|
|
209
|
+
inputRef.current?.focus();
|
|
210
|
+
}, children: inCreateMode ? (_jsx("div", { className: "animate-in fade-in-0 slide-in-from-top-1 duration-150 motion-reduce:animate-none", children: _jsx(ComboboxCreateStep, { label: createLabel ?? searchPlaceholder, labels: labels, children: createStep }) })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "border-border/60 flex items-center gap-2 border-b px-2.5 pt-2.5 pb-1.5", children: [_jsx("input", { ref: inputRef, type: "text", role: "combobox", "aria-label": ariaLabel ?? searchPlaceholder, "aria-autocomplete": "list", "aria-controls": listId, "aria-expanded": open, "aria-activedescendant": activeDomId, value: query, placeholder: searchPlaceholder, onChange: (event) => updateQuery(event.target.value), onKeyDown: handleKeyDown, className: "placeholder:text-muted-foreground/70 min-w-0 flex-1 bg-transparent text-[13px] outline-none" }), searching ? (_jsx("span", { className: "text-muted-foreground text-[11px]", role: "status", children: searchingLabel ?? searchPlaceholder })) : null, triggerKey ? _jsx(Kbd, { className: "shrink-0 text-[10.5px]", children: triggerKey }) : null] }), _jsxs("ul", { ref: listRefCallback, id: listId, role: "listbox", "aria-multiselectable": true, "aria-label": ariaLabel, className: "max-h-72 overflow-y-auto py-1", children: [filtered.length === 0 && !showCreate && !searching ? (_jsx("li", { children: _jsx(EmptyState, { title: emptyText ?? labelsProp?.noMatches ?? searchPlaceholder, className: "py-6" }) })) : (_jsxs(_Fragment, { children: [selectedRows.map(renderRow), selectedRows.length > 0 && remainingRows.length > 0 ? (_jsx("li", { role: "presentation", "aria-hidden": true, className: "border-border/60 mx-2 my-1 border-t" })) : null, remainingRows.map((item, index) => {
|
|
211
|
+
const showGroup = remainingGroupCount > 1 &&
|
|
212
|
+
item.group &&
|
|
213
|
+
(index === 0 || remainingRows[index - 1]?.group !== item.group);
|
|
214
|
+
return (_jsxs(Fragment, { children: [showGroup ? (_jsx("li", { role: "presentation", "aria-hidden": true, className: "text-muted-foreground/70 mx-1 mt-1.5 mb-0.5 px-2 text-[10.5px]", children: item.group })) : null, renderRow(item)] }, item.id));
|
|
215
|
+
})] })), showCreate ? (_jsxs("li", { id: `${listId}-row-${CREATE_ROW}`, role: "option", "aria-selected": false, "data-active": activeId === CREATE_ROW || undefined, onPointerMove: () => setActiveOverride(CREATE_ROW), onPointerDown: (event) => {
|
|
216
|
+
if (event.button !== 0 || !event.isPrimary)
|
|
217
|
+
return;
|
|
218
|
+
event.preventDefault();
|
|
219
|
+
handleCreate();
|
|
220
|
+
}, className: cn('border-border/60 mx-1 mt-1 flex cursor-pointer items-center gap-2 rounded-md border-t px-2 py-2 text-[13px]', activeId === CREATE_ROW && 'bg-muted'), children: [_jsx(Plus, { className: "text-muted-foreground size-3.5", strokeWidth: 1.5, "aria-hidden": true }), _jsxs("span", { className: "text-foreground min-w-0 truncate", children: [createLabel ? `${createLabel}: ` : null, _jsx("span", { className: "text-foreground/90", children: trimmedQuery })] })] })) : null] })] })) })] }));
|
|
221
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export declare const NAUT_SHAPES: readonly ["circle", "squircle", "triangle", "diamond", "hexagon"];
|
|
2
|
+
export type NautShape = (typeof NAUT_SHAPES)[number];
|
|
3
|
+
export declare const NAUT_COLORS: {
|
|
4
|
+
readonly ink: "#111216";
|
|
5
|
+
readonly slate: "#4b5163";
|
|
6
|
+
readonly coral: "#ef6f4f";
|
|
7
|
+
readonly sun: "#f0b429";
|
|
8
|
+
readonly mint: "#2fb585";
|
|
9
|
+
readonly sky: "#3d9ff0";
|
|
10
|
+
readonly lavender: "#8b7cf2";
|
|
11
|
+
readonly rose: "#ec5f98";
|
|
12
|
+
readonly ocean: "#3162e8";
|
|
13
|
+
readonly forest: "#2f6b4f";
|
|
14
|
+
readonly plum: "#6b3a8e";
|
|
15
|
+
readonly clay: "#b5654b";
|
|
16
|
+
};
|
|
17
|
+
export type NautColor = keyof typeof NAUT_COLORS;
|
|
18
|
+
export declare const NAUT_COLOR_KEYS: NautColor[];
|
|
19
|
+
export declare const isNautShape: (v: unknown) => v is NautShape;
|
|
20
|
+
export declare const isNautColor: (v: unknown) => v is NautColor;
|
|
21
|
+
export declare const NAUT_EXPRESSIONS: readonly ["neutral", "happy", "angry", "surprised", "thinking", "sad", "sleepy", "excited", "error", "confused", "wink", "focused", "laughing", "scared", "smug", "talking", "loading"];
|
|
22
|
+
export type NautExpression = (typeof NAUT_EXPRESSIONS)[number];
|
|
23
|
+
export declare const NAUT_GESTURES: readonly ["nod", "shake", "blink", "wink", "bounce", "jump", "spin", "lookAround", "shiver", "celebrate", "nope", "pop"];
|
|
24
|
+
export type NautGesture = (typeof NAUT_GESTURES)[number];
|
|
25
|
+
export declare const NAUT_VIEWBOX = "-126 -126 252 252";
|
|
26
|
+
export interface NautAvatarOptions {
|
|
27
|
+
shape?: NautShape;
|
|
28
|
+
color?: NautColor;
|
|
29
|
+
expression?: NautExpression;
|
|
30
|
+
/** Deterministic idle randomness so lists don't all blink in sync. */
|
|
31
|
+
seed?: number;
|
|
32
|
+
idle?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface NautAvatarElements {
|
|
35
|
+
root: SVGGElement;
|
|
36
|
+
body: SVGPathElement;
|
|
37
|
+
eyes: SVGGElement;
|
|
38
|
+
eyeL: SVGPathElement;
|
|
39
|
+
eyeR: SVGPathElement;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Framework-agnostic renderer: owns the animation state and writes attributes onto the
|
|
43
|
+
* SVG elements it is given. Call `update(dt)` once per frame.
|
|
44
|
+
*/
|
|
45
|
+
export declare class NautAvatarEngine {
|
|
46
|
+
shape: NautShape;
|
|
47
|
+
color: NautColor;
|
|
48
|
+
expression: NautExpression;
|
|
49
|
+
idle: boolean;
|
|
50
|
+
/** Pointer/gaze target in [-1, 1]; null = no external gaze. */
|
|
51
|
+
gazeTarget: {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
} | null;
|
|
55
|
+
private readonly rand;
|
|
56
|
+
private time;
|
|
57
|
+
private emotionTime;
|
|
58
|
+
private gestures;
|
|
59
|
+
private nodes;
|
|
60
|
+
private sphere;
|
|
61
|
+
private eyeYOff;
|
|
62
|
+
private readonly face;
|
|
63
|
+
private targetFace;
|
|
64
|
+
private readonly idleState;
|
|
65
|
+
private el;
|
|
66
|
+
constructor(opts?: NautAvatarOptions);
|
|
67
|
+
attach(el: NautAvatarElements): void;
|
|
68
|
+
setShape(shape: NautShape): void;
|
|
69
|
+
setColor(color: NautColor): void;
|
|
70
|
+
setExpression(key: NautExpression, instant?: boolean): void;
|
|
71
|
+
play(key: NautGesture): void;
|
|
72
|
+
/** Snap every tween to its target (used for static renders / reduced motion). */
|
|
73
|
+
settle(): void;
|
|
74
|
+
update(dt: number): void;
|
|
75
|
+
private updateIdle;
|
|
76
|
+
private render;
|
|
77
|
+
}
|
|
78
|
+
/** Stable pseudo-random pick so the same id always gets the same appearance. */
|
|
79
|
+
export declare function hashSeed(input: string): number;
|
|
80
|
+
export declare function nautAppearanceForSeed(seed: string): {
|
|
81
|
+
shape: NautShape;
|
|
82
|
+
color: NautColor;
|
|
83
|
+
};
|