@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,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { Button } from './button.js';
|
|
5
|
+
import { Dialog, DialogContent, DialogDescription, DialogTitle } from './dialog.js';
|
|
6
|
+
import { Kbd } from './kbd.js';
|
|
7
|
+
import { Label } from './label.js';
|
|
8
|
+
import { Switch } from './switch.js';
|
|
9
|
+
import { cn } from '../lib/cn.js';
|
|
10
|
+
export function FormDialog({ open, onOpenChange, title, description, onSubmit, submitLabel, labels, submitting = false, canSubmit = true, hideSubmit = false, footerLeft, children, contentClassName, 'data-testid': testId, }) {
|
|
11
|
+
const submitRef = useRef(() => undefined);
|
|
12
|
+
const contentRef = useRef(null);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
submitRef.current = () => {
|
|
15
|
+
if (submitting || !canSubmit)
|
|
16
|
+
return;
|
|
17
|
+
onSubmit();
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!open)
|
|
22
|
+
return;
|
|
23
|
+
const onKeyDown = (e) => {
|
|
24
|
+
if (e.isComposing)
|
|
25
|
+
return;
|
|
26
|
+
if (e.key !== 'Enter' || (!e.metaKey && !e.ctrlKey) || e.shiftKey || e.altKey)
|
|
27
|
+
return;
|
|
28
|
+
const openDialogs = document.querySelectorAll('[data-atmos-form-dialog][data-state="open"]');
|
|
29
|
+
if (openDialogs.item(openDialogs.length - 1) !== contentRef.current)
|
|
30
|
+
return;
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
e.stopImmediatePropagation();
|
|
33
|
+
submitRef.current();
|
|
34
|
+
};
|
|
35
|
+
document.addEventListener('keydown', onKeyDown, true);
|
|
36
|
+
return () => document.removeEventListener('keydown', onKeyDown, true);
|
|
37
|
+
}, [open]);
|
|
38
|
+
const onBodyKeyDown = (e) => {
|
|
39
|
+
if (e.key !== 'Enter' || e.shiftKey || e.metaKey || e.ctrlKey || e.altKey)
|
|
40
|
+
return;
|
|
41
|
+
const target = e.target;
|
|
42
|
+
if (target.tagName === 'INPUT') {
|
|
43
|
+
e.preventDefault();
|
|
44
|
+
submitRef.current();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const submitDisabled = submitting || !canSubmit;
|
|
48
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { ref: contentRef, "data-atmos-form-dialog": true, "data-testid": testId, closeLabel: labels.close, className: cn('gap-0 overflow-visible p-0', contentClassName ?? 'sm:max-w-[520px]'), children: [_jsxs("div", { className: "px-5 pt-4 pb-3", children: [_jsx(DialogTitle, { className: "font-heading text-[15px] leading-none font-medium", children: title }), description ? (_jsx(DialogDescription, { className: "text-muted-foreground mt-1 text-[12px]", children: description })) : (_jsx(DialogDescription, { className: "sr-only", children: title }))] }), _jsx("div", { className: "bg-border/60 h-px" }), _jsx("div", { className: "max-h-[60vh] overflow-y-auto px-5 py-4", role: "presentation", onKeyDown: onBodyKeyDown, children: children }), _jsx("div", { className: "bg-border/60 h-px" }), _jsxs("div", { className: "bg-muted/25 flex items-center gap-3 px-5 py-3", children: [footerLeft ? _jsx("div", { className: "flex items-center gap-2", children: footerLeft }) : null, _jsx("div", { className: "ml-auto flex items-center gap-2", children: hideSubmit ? (_jsx(Button, { size: "sm", onClick: () => onOpenChange(false), children: labels.close })) : (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => onOpenChange(false), children: labels.cancel }), _jsxs(Button, { size: "sm", onClick: () => submitRef.current(), disabled: submitDisabled, className: "gap-2", "data-testid": "form-dialog-submit", children: [submitting ? labels.saving : submitLabel, _jsx(Kbd, { className: "bg-primary-foreground/15 text-primary-foreground/90", children: "\u2318\u21B5" })] })] })) })] })] }) }));
|
|
49
|
+
}
|
|
50
|
+
export function FormDialogCreateMoreToggle({ checked, onCheckedChange, label, id = 'form-create-more', }) {
|
|
51
|
+
return (_jsxs(_Fragment, { children: [_jsx(Switch, { id: id, size: "sm", checked: checked, onCheckedChange: onCheckedChange }), _jsx(Label, { htmlFor: id, className: "text-muted-foreground/90 cursor-pointer text-[11.5px]", children: label })] }));
|
|
52
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface FormulaEditorField {
|
|
2
|
+
slug: string;
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FormulaEditorProps {
|
|
7
|
+
value: string;
|
|
8
|
+
onChange: (value: string) => void;
|
|
9
|
+
fields: FormulaEditorField[];
|
|
10
|
+
ariaLabel: string;
|
|
11
|
+
placeholder: string;
|
|
12
|
+
fieldDetail: string;
|
|
13
|
+
operatorDetail: string;
|
|
14
|
+
functionDetail: string;
|
|
15
|
+
className?: string;
|
|
16
|
+
'data-testid'?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function FormulaEditor({ value, onChange, fields, ariaLabel, placeholder, fieldDetail, operatorDetail, functionDetail, className, 'data-testid': testId, }: FormulaEditorProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { autocompletion, moveCompletionSelection } from '@codemirror/autocomplete';
|
|
5
|
+
import { HighlightStyle, StreamLanguage, syntaxHighlighting } from '@codemirror/language';
|
|
6
|
+
import { Prec } from '@codemirror/state';
|
|
7
|
+
import { EditorView, keymap } from '@codemirror/view';
|
|
8
|
+
import CodeMirror from '@uiw/react-codemirror';
|
|
9
|
+
import { tags } from '@lezer/highlight';
|
|
10
|
+
import { cn } from '../lib/cn.js';
|
|
11
|
+
const functions = [
|
|
12
|
+
['sum', 'sum(a, b)'],
|
|
13
|
+
['avg', 'avg(a, b)'],
|
|
14
|
+
['mean', 'mean(a, b)'],
|
|
15
|
+
['min', 'min(a, b)'],
|
|
16
|
+
['max', 'max(a, b)'],
|
|
17
|
+
['count', 'count(a, b)'],
|
|
18
|
+
['abs', 'abs(a)'],
|
|
19
|
+
['round', 'round(a, digits)'],
|
|
20
|
+
];
|
|
21
|
+
const language = StreamLanguage.define({
|
|
22
|
+
token(stream) {
|
|
23
|
+
if (stream.match(/[0-9]+(?:\.[0-9]+)?/))
|
|
24
|
+
return 'number';
|
|
25
|
+
if (stream.match(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/))
|
|
26
|
+
return 'string';
|
|
27
|
+
if (stream.match(/(?:sum|avg|mean|min|max|count|abs|round)\b/i))
|
|
28
|
+
return 'keyword';
|
|
29
|
+
if (stream.match(/[A-Za-z_][A-Za-z0-9_]*/))
|
|
30
|
+
return 'variableName';
|
|
31
|
+
if (stream.match(/[+\-*/(),]/))
|
|
32
|
+
return 'operator';
|
|
33
|
+
stream.next();
|
|
34
|
+
return null;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
const highlighting = HighlightStyle.define([
|
|
38
|
+
{
|
|
39
|
+
tag: [tags.keyword, tags.function(tags.variableName)],
|
|
40
|
+
color: 'var(--cm-function)',
|
|
41
|
+
fontWeight: '600',
|
|
42
|
+
},
|
|
43
|
+
{ tag: tags.number, color: 'var(--cm-number)' },
|
|
44
|
+
{ tag: [tags.string, tags.special(tags.string)], color: 'var(--cm-string)' },
|
|
45
|
+
{ tag: [tags.variableName, tags.name], color: 'var(--cm-name)', fontWeight: '600' },
|
|
46
|
+
{
|
|
47
|
+
tag: [tags.operator, tags.punctuation, tags.separator, tags.paren],
|
|
48
|
+
color: 'var(--cm-operator)',
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
const theme = EditorView.theme({
|
|
52
|
+
'&': {
|
|
53
|
+
color: 'var(--popover-foreground)',
|
|
54
|
+
backgroundColor: 'transparent',
|
|
55
|
+
fontSize: '12.5px',
|
|
56
|
+
minHeight: '84px',
|
|
57
|
+
},
|
|
58
|
+
'&.cm-focused': { outline: 'none' },
|
|
59
|
+
'.cm-scroller': { fontFamily: 'var(--font-mono, ui-monospace, monospace)', lineHeight: '1.55' },
|
|
60
|
+
'.cm-content': { caretColor: 'var(--foreground)', minHeight: '84px', padding: '8px 10px' },
|
|
61
|
+
'.cm-placeholder': { color: 'var(--muted-foreground)' },
|
|
62
|
+
'.cm-cursor, .cm-dropCursor': { borderLeftColor: 'var(--foreground)' },
|
|
63
|
+
'.cm-selectionBackground, &.cm-focused .cm-selectionBackground, .cm-content ::selection': {
|
|
64
|
+
backgroundColor: 'color-mix(in oklch, var(--primary) 22%, transparent)',
|
|
65
|
+
},
|
|
66
|
+
'.cm-activeLine': { backgroundColor: 'color-mix(in oklch, var(--muted) 42%, transparent)' },
|
|
67
|
+
'.cm-tooltip.cm-tooltip-autocomplete': {
|
|
68
|
+
border: '1px solid var(--border)',
|
|
69
|
+
borderRadius: 'var(--radius-lg)',
|
|
70
|
+
backgroundColor: 'var(--popover)',
|
|
71
|
+
color: 'var(--popover-foreground)',
|
|
72
|
+
boxShadow: '0 12px 32px -12px rgb(0 0 0 / 0.28)',
|
|
73
|
+
padding: '4px',
|
|
74
|
+
overflow: 'hidden',
|
|
75
|
+
},
|
|
76
|
+
'.cm-tooltip.cm-tooltip-autocomplete > ul': {
|
|
77
|
+
fontFamily: 'inherit',
|
|
78
|
+
fontSize: '12.5px',
|
|
79
|
+
maxHeight: '15rem',
|
|
80
|
+
},
|
|
81
|
+
'.cm-tooltip.cm-tooltip-autocomplete > ul > li': {
|
|
82
|
+
display: 'flex',
|
|
83
|
+
alignItems: 'center',
|
|
84
|
+
gap: '7px',
|
|
85
|
+
padding: '4px 8px',
|
|
86
|
+
borderRadius: 'var(--radius-sm)',
|
|
87
|
+
color: 'var(--popover-foreground)',
|
|
88
|
+
},
|
|
89
|
+
'.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]': {
|
|
90
|
+
backgroundColor: 'var(--accent)',
|
|
91
|
+
color: 'var(--accent-foreground)',
|
|
92
|
+
},
|
|
93
|
+
'.cm-completionMatchedText': { textDecoration: 'none', fontWeight: '600', color: 'inherit' },
|
|
94
|
+
'.cm-completionDetail': {
|
|
95
|
+
marginLeft: 'auto',
|
|
96
|
+
fontStyle: 'normal',
|
|
97
|
+
fontFamily: 'var(--font-mono)',
|
|
98
|
+
fontSize: '10.5px',
|
|
99
|
+
color: 'var(--muted-foreground)',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
const completionKeys = Prec.high(keymap.of([
|
|
103
|
+
{ key: 'Ctrl-n', run: moveCompletionSelection(true) },
|
|
104
|
+
{ key: 'Ctrl-p', run: moveCompletionSelection(false) },
|
|
105
|
+
]));
|
|
106
|
+
export function FormulaEditor({ value, onChange, fields, ariaLabel, placeholder, fieldDetail, operatorDetail, functionDetail, className, 'data-testid': testId, }) {
|
|
107
|
+
const extensions = useMemo(() => {
|
|
108
|
+
const options = [
|
|
109
|
+
...functions.map(([label, info]) => ({
|
|
110
|
+
label,
|
|
111
|
+
apply: `${label}()`,
|
|
112
|
+
info,
|
|
113
|
+
type: 'function',
|
|
114
|
+
detail: functionDetail,
|
|
115
|
+
})),
|
|
116
|
+
...fields.map((field) => ({
|
|
117
|
+
label: field.slug,
|
|
118
|
+
type: 'property',
|
|
119
|
+
detail: field.name || fieldDetail,
|
|
120
|
+
info: field.type,
|
|
121
|
+
})),
|
|
122
|
+
...['+', '-', '*', '/', '(', ')'].map((label) => ({
|
|
123
|
+
label,
|
|
124
|
+
type: 'operator',
|
|
125
|
+
detail: operatorDetail,
|
|
126
|
+
})),
|
|
127
|
+
];
|
|
128
|
+
return [
|
|
129
|
+
language,
|
|
130
|
+
syntaxHighlighting(highlighting),
|
|
131
|
+
completionKeys,
|
|
132
|
+
EditorView.lineWrapping,
|
|
133
|
+
EditorView.contentAttributes.of({ 'aria-label': ariaLabel }),
|
|
134
|
+
autocompletion({
|
|
135
|
+
icons: true,
|
|
136
|
+
override: [
|
|
137
|
+
(context) => {
|
|
138
|
+
const word = context.matchBefore(/[A-Za-z0-9_+\-*/()]*/);
|
|
139
|
+
if (!word || (word.from === word.to && !context.explicit))
|
|
140
|
+
return null;
|
|
141
|
+
return { from: word.from, options, validFor: /^[A-Za-z0-9_+\-*/()]*$/ };
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
}),
|
|
145
|
+
theme,
|
|
146
|
+
];
|
|
147
|
+
}, [ariaLabel, fieldDetail, fields, functionDetail, operatorDetail]);
|
|
148
|
+
return (_jsx("div", { "data-slot": "formula-editor", "data-testid": testId, className: cn('border-input bg-background focus-within:border-ring focus-within:ring-ring/50 overflow-hidden rounded-lg border focus-within:ring-3', className), children: _jsx(CodeMirror, { value: value, onChange: onChange, extensions: extensions, placeholder: placeholder, theme: "none", basicSetup: {
|
|
149
|
+
lineNumbers: false,
|
|
150
|
+
foldGutter: false,
|
|
151
|
+
autocompletion: false,
|
|
152
|
+
highlightActiveLineGutter: false,
|
|
153
|
+
}, "aria-label": ariaLabel }) }));
|
|
154
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { HoverCard as HoverCardPrimitive } from 'radix-ui';
|
|
3
|
+
declare function HoverCard({ openDelay, closeDelay, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
/**
|
|
5
|
+
* Always a `group/hover-card`, so anything inside the trigger can react to the card
|
|
6
|
+
* being open — a sidebar row staying lit while its card shows, for instance.
|
|
7
|
+
*/
|
|
8
|
+
declare function HoverCardTrigger({ className, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>): React.JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Defaults to the right of its trigger and flips to whichever side has room, so the
|
|
11
|
+
* same card works against a left rail, a right inspector, or a viewport edge.
|
|
12
|
+
*
|
|
13
|
+
* Sized to its longest row rather than to a column width: a card of short values reads
|
|
14
|
+
* as a small label beside the thing it describes instead of a mostly-empty panel. The
|
|
15
|
+
* floor only keeps a one-word card from being narrower than the eye reads as a card,
|
|
16
|
+
* and the ceiling is where a long value starts wrapping instead of pushing on.
|
|
17
|
+
*/
|
|
18
|
+
declare function HoverCardContent({ className, side, align, sideOffset, collisionPadding, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Content>): React.JSX.Element;
|
|
19
|
+
export interface HoverCardHeaderProps extends React.ComponentProps<'div'> {
|
|
20
|
+
icon?: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* A second line under the title — who owns the thing and how it stands. The icon
|
|
23
|
+
* grows to an avatar and centres across both lines, so one mark identifies the pair
|
|
24
|
+
* rather than each line carrying its own.
|
|
25
|
+
*/
|
|
26
|
+
subtitle?: React.ReactNode;
|
|
27
|
+
/** Trailing slot for a single affordance — the pin toggle in the reference design. */
|
|
28
|
+
action?: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
declare function HoverCardHeader({ className, icon, subtitle, action, children, ...props }: HoverCardHeaderProps): React.JSX.Element;
|
|
31
|
+
export interface HoverCardMetaProps extends React.ComponentProps<'div'> {
|
|
32
|
+
icon?: React.ReactNode;
|
|
33
|
+
/** Metadata the design system sets in Geist Mono — paths, ids, versions. */
|
|
34
|
+
mono?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Let a long value wrap onto further lines instead of truncating. A file path is
|
|
37
|
+
* only useful whole, so the card grows rather than hiding where the work happens.
|
|
38
|
+
*/
|
|
39
|
+
wrap?: boolean;
|
|
40
|
+
}
|
|
41
|
+
declare function HoverCardMeta({ className, icon, mono, wrap, children, ...props }: HoverCardMetaProps): React.JSX.Element;
|
|
42
|
+
/**
|
|
43
|
+
* Padded slot for content that is not a row — a meter, a chart, a short paragraph —
|
|
44
|
+
* so it lines up with the rows above it without every consumer re-deriving the inset.
|
|
45
|
+
*/
|
|
46
|
+
declare function HoverCardBlock({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
47
|
+
declare function HoverCardSeparator({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
48
|
+
export interface HoverCardActionProps extends React.ComponentProps<'button'> {
|
|
49
|
+
icon?: React.ReactNode;
|
|
50
|
+
}
|
|
51
|
+
declare function HoverCardAction({ className, icon, children, ...props }: HoverCardActionProps): React.JSX.Element;
|
|
52
|
+
export { HoverCard, HoverCardAction, HoverCardBlock, HoverCardContent, HoverCardHeader, HoverCardMeta, HoverCardSeparator, HoverCardTrigger, };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { HoverCard as HoverCardPrimitive } from 'radix-ui';
|
|
5
|
+
import { cn } from '../lib/cn.js';
|
|
6
|
+
function HoverCard({ openDelay = 320, closeDelay = 120, ...props }) {
|
|
7
|
+
return (_jsx(HoverCardPrimitive.Root, { "data-slot": "hover-card", openDelay: openDelay, closeDelay: closeDelay, ...props }));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Always a `group/hover-card`, so anything inside the trigger can react to the card
|
|
11
|
+
* being open — a sidebar row staying lit while its card shows, for instance.
|
|
12
|
+
*/
|
|
13
|
+
function HoverCardTrigger({ className, ...props }) {
|
|
14
|
+
return (_jsx(HoverCardPrimitive.Trigger, { "data-slot": "hover-card-trigger", className: cn('group/hover-card', className), ...props }));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Defaults to the right of its trigger and flips to whichever side has room, so the
|
|
18
|
+
* same card works against a left rail, a right inspector, or a viewport edge.
|
|
19
|
+
*
|
|
20
|
+
* Sized to its longest row rather than to a column width: a card of short values reads
|
|
21
|
+
* as a small label beside the thing it describes instead of a mostly-empty panel. The
|
|
22
|
+
* floor only keeps a one-word card from being narrower than the eye reads as a card,
|
|
23
|
+
* and the ceiling is where a long value starts wrapping instead of pushing on.
|
|
24
|
+
*/
|
|
25
|
+
function HoverCardContent({ className, side = 'right', align = 'start', sideOffset = 4, collisionPadding = 8, ...props }) {
|
|
26
|
+
return (_jsx(HoverCardPrimitive.Portal, { children: _jsx(HoverCardPrimitive.Content, { "data-slot": "hover-card-content", side: side, align: align, sideOffset: sideOffset, collisionPadding: collisionPadding, className: cn('bg-popover text-popover-foreground ring-foreground/10 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 z-50 flex w-max max-w-[26rem] min-w-36 origin-(--radix-hover-card-content-transform-origin) flex-col gap-px rounded-lg p-1 shadow-md ring-1 outline-hidden duration-100', className), ...props }) }));
|
|
27
|
+
}
|
|
28
|
+
const rowClassName = 'flex min-h-7 w-full items-center gap-2 rounded-md px-1.5 py-1 text-left text-[12.5px] [&_svg]:size-3.5 [&_svg]:shrink-0';
|
|
29
|
+
function HoverCardIcon({ className, children }) {
|
|
30
|
+
return (_jsx("span", { "data-slot": "hover-card-icon", className: cn('text-muted-foreground/80 inline-flex size-3.5 shrink-0 items-center justify-center', className), "aria-hidden": true, children: children }));
|
|
31
|
+
}
|
|
32
|
+
function HoverCardHeader({ className, icon, subtitle, action, children, ...props }) {
|
|
33
|
+
return (_jsxs("div", { "data-slot": "hover-card-header", className: cn(rowClassName, subtitle && 'gap-2.5', className), ...props, children: [icon ? (_jsx(HoverCardIcon, { className: subtitle ? 'size-7' : undefined, children: icon })) : null, _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-foreground block truncate font-medium", children: children }), subtitle ? (_jsx("span", { className: "text-muted-foreground block truncate text-[11.5px]", children: subtitle })) : null] }), action ? _jsx("span", { className: "ml-auto shrink-0", children: action }) : null] }));
|
|
34
|
+
}
|
|
35
|
+
function HoverCardMeta({ className, icon, mono, wrap, children, ...props }) {
|
|
36
|
+
return (_jsxs("div", { "data-slot": "hover-card-meta", className: cn(rowClassName, 'text-muted-foreground', wrap && 'items-start', className), ...props, children: [icon ? _jsx(HoverCardIcon, { className: wrap ? 'mt-0.5' : undefined, children: icon }) : null, _jsx("span", { className: cn('min-w-0 flex-1', wrap ? 'break-all whitespace-normal' : 'truncate', mono && 'font-mono text-[11.5px]'), children: children })] }));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Padded slot for content that is not a row — a meter, a chart, a short paragraph —
|
|
40
|
+
* so it lines up with the rows above it without every consumer re-deriving the inset.
|
|
41
|
+
*/
|
|
42
|
+
function HoverCardBlock({ className, ...props }) {
|
|
43
|
+
return _jsx("div", { "data-slot": "hover-card-block", className: cn('px-1.5 py-1.5', className), ...props });
|
|
44
|
+
}
|
|
45
|
+
function HoverCardSeparator({ className, ...props }) {
|
|
46
|
+
return (_jsx("div", { "data-slot": "hover-card-separator", role: "separator", className: cn('bg-border/60 my-1 h-px w-full shrink-0', className), ...props }));
|
|
47
|
+
}
|
|
48
|
+
function HoverCardAction({ className, icon, children, ...props }) {
|
|
49
|
+
return (_jsxs("button", { "data-slot": "hover-card-action", type: "button", className: cn(rowClassName, 'text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/50 cursor-pointer outline-hidden transition-colors focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50', className), ...props, children: [icon ? _jsx(HoverCardIcon, { children: icon }) : null, _jsx("span", { className: "min-w-0 flex-1 truncate", children: children })] }));
|
|
50
|
+
}
|
|
51
|
+
export { HoverCard, HoverCardAction, HoverCardBlock, HoverCardContent, HoverCardHeader, HoverCardMeta, HoverCardSeparator, HoverCardTrigger, };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
type IconButtonSize = 'xs' | 'sm' | 'md' | 'card';
|
|
3
|
+
type IconButtonTone = 'muted' | 'danger';
|
|
4
|
+
export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
5
|
+
size?: IconButtonSize;
|
|
6
|
+
tone?: IconButtonTone;
|
|
7
|
+
reveal?: boolean;
|
|
8
|
+
tooltip?: ReactNode;
|
|
9
|
+
tooltipSide?: 'top' | 'right' | 'bottom' | 'left';
|
|
10
|
+
/** Takes the tooltip over from hover — a press closes an uncontrolled one. */
|
|
11
|
+
tooltipOpen?: boolean;
|
|
12
|
+
onTooltipOpenChange?: (open: boolean) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const IconButton: import("react").ForwardRefExoticComponent<IconButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import { Button } from './button.js';
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from './tooltip.js';
|
|
6
|
+
import { cn } from '../lib/cn.js';
|
|
7
|
+
const sizeMap = { xs: 'icon-xs', sm: 'icon-sm', md: 'icon', card: 'icon-xs' };
|
|
8
|
+
const toneClass = {
|
|
9
|
+
muted: 'hover:bg-muted/50 hover:text-foreground',
|
|
10
|
+
danger: 'hover:bg-destructive/10 hover:text-destructive',
|
|
11
|
+
};
|
|
12
|
+
export const IconButton = forwardRef(function IconButton({ size = 'sm', tone = 'muted', reveal = false, tooltip, tooltipSide = 'top', tooltipOpen, onTooltipOpenChange, className, type = 'button', ...props }, ref) {
|
|
13
|
+
const button = (_jsx(Button, { ref: ref, type: type, variant: "ghost", size: sizeMap[size], className: cn('text-muted-foreground/70', toneClass[tone], size === 'card' && 'size-6 rounded-md hover:bg-muted/70', reveal &&
|
|
14
|
+
'opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100', className), ...props }));
|
|
15
|
+
if (tooltip == null)
|
|
16
|
+
return button;
|
|
17
|
+
return (_jsxs(Tooltip, { open: tooltipOpen, onOpenChange: onTooltipOpenChange, children: [_jsx(TooltipTrigger, { asChild: true, children: button }), _jsx(TooltipContent, { variant: "compact", side: tooltipSide, children: tooltip })] }));
|
|
18
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export type InlineAlertTone = 'error' | 'warning' | 'info';
|
|
3
|
+
export interface InlineAlertProps {
|
|
4
|
+
tone?: InlineAlertTone;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
onDismiss?: () => void;
|
|
7
|
+
dismissLabel?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function InlineAlert({ tone, children, onDismiss, dismissLabel, className, }: InlineAlertProps): import("react").JSX.Element;
|
|
11
|
+
export declare function InlineNotice({ tone, children, className, }: Pick<InlineAlertProps, 'tone' | 'children' | 'className'>): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AlertTriangle, Info, X } from 'lucide-react';
|
|
4
|
+
import { cn } from '../lib/cn.js';
|
|
5
|
+
import { Button } from './button.js';
|
|
6
|
+
const toneClass = {
|
|
7
|
+
error: 'border-destructive/30 bg-destructive/10 text-destructive',
|
|
8
|
+
warning: 'border-warning/30 bg-warning/15 text-warning',
|
|
9
|
+
info: 'border-info/30 bg-info/15 text-info',
|
|
10
|
+
};
|
|
11
|
+
export function InlineAlert({ tone = 'error', children, onDismiss, dismissLabel, className, }) {
|
|
12
|
+
const Icon = tone === 'info' ? Info : AlertTriangle;
|
|
13
|
+
return (_jsxs("div", { role: "alert", "data-slot": "inline-alert", "data-tone": tone, className: cn('flex items-start gap-2 rounded-md border px-3 py-2 text-xs', toneClass[tone], className), children: [_jsx(Icon, { className: "mt-0.5 size-3.5 shrink-0", strokeWidth: 1.5, "aria-hidden": true }), _jsx("span", { className: "flex-1 leading-relaxed", children: children }), onDismiss ? (_jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", onClick: onDismiss, "aria-label": dismissLabel, className: "-mr-1 size-4 rounded text-current opacity-80 hover:bg-transparent hover:opacity-100", children: _jsx(X, { className: "size-3", strokeWidth: 1.5 }) })) : null] }));
|
|
14
|
+
}
|
|
15
|
+
export function InlineNotice({ tone = 'info', children, className, }) {
|
|
16
|
+
return (_jsx(InlineAlert, { tone: tone, className: className, children: children }));
|
|
17
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from '../lib/cn.js';
|
|
4
|
+
function Input({ className, type, ...props }) {
|
|
5
|
+
return (_jsx("input", { type: type, "data-slot": "input", className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props }));
|
|
6
|
+
}
|
|
7
|
+
export { Input };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import '../lib/react-19-jsx.js';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import { type DragHandleProps } from './sortable.js';
|
|
4
|
+
export interface KanbanColumn {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
}
|
|
8
|
+
export interface KanbanCardRenderArgs {
|
|
9
|
+
isDragging: boolean;
|
|
10
|
+
dragHandleProps: DragHandleProps;
|
|
11
|
+
}
|
|
12
|
+
export interface KanbanColumnRenderArgs {
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
isOver: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface KanbanBoardProps<T> {
|
|
17
|
+
columns: KanbanColumn[];
|
|
18
|
+
items: T[];
|
|
19
|
+
keyOf: (item: T) => string;
|
|
20
|
+
columnOf: (item: T) => string;
|
|
21
|
+
onMove: (itemId: string, toColumnId: string, toIndex: number) => void;
|
|
22
|
+
renderColumn: (column: KanbanColumn, args: KanbanColumnRenderArgs) => ReactNode;
|
|
23
|
+
renderCard: (item: T, args: KanbanCardRenderArgs) => ReactNode;
|
|
24
|
+
collisionStrategy?: 'kanban';
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function KanbanBoard<T>({ columns, items, keyOf, columnOf, onMove, renderColumn, renderCard, className, }: KanbanBoardProps<T>): import("react").JSX.Element;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import '../lib/react-19-jsx.js';
|
|
4
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
5
|
+
import { DndContext, KeyboardSensor, PointerSensor, closestCenter, pointerWithin, rectIntersection, useDroppable, useSensor, useSensors, } from '@dnd-kit/core';
|
|
6
|
+
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable';
|
|
7
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
8
|
+
import { DragPreview } from './sortable.js';
|
|
9
|
+
const CARD_PREFIX = 'kcard::';
|
|
10
|
+
const COLUMN_PREFIX = 'kcol::';
|
|
11
|
+
function makeCardId(columnId, itemId) {
|
|
12
|
+
return `${CARD_PREFIX}${columnId}::${itemId}`;
|
|
13
|
+
}
|
|
14
|
+
function parseCardId(raw) {
|
|
15
|
+
if (!raw.startsWith(CARD_PREFIX))
|
|
16
|
+
return null;
|
|
17
|
+
const rest = raw.slice(CARD_PREFIX.length);
|
|
18
|
+
const separator = rest.lastIndexOf('::');
|
|
19
|
+
if (separator < 0)
|
|
20
|
+
return null;
|
|
21
|
+
return {
|
|
22
|
+
columnId: rest.slice(0, separator),
|
|
23
|
+
itemId: rest.slice(separator + 2),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function makeColumnId(columnId) {
|
|
27
|
+
return `${COLUMN_PREFIX}${columnId}`;
|
|
28
|
+
}
|
|
29
|
+
function parseColumnId(raw) {
|
|
30
|
+
return raw.startsWith(COLUMN_PREFIX) ? raw.slice(COLUMN_PREFIX.length) : null;
|
|
31
|
+
}
|
|
32
|
+
export function KanbanBoard({ columns, items, keyOf, columnOf, onMove, renderColumn, renderCard, className, }) {
|
|
33
|
+
const [activeCardId, setActiveCardId] = useState(null);
|
|
34
|
+
const [overColumnId, setOverColumnId] = useState(null);
|
|
35
|
+
const itemsByColumn = useMemo(() => {
|
|
36
|
+
const map = new Map();
|
|
37
|
+
for (const column of columns)
|
|
38
|
+
map.set(column.id, []);
|
|
39
|
+
for (const item of items) {
|
|
40
|
+
const columnId = columnOf(item);
|
|
41
|
+
const list = map.get(columnId);
|
|
42
|
+
if (list)
|
|
43
|
+
list.push(item);
|
|
44
|
+
else
|
|
45
|
+
map.set(columnId, [item]);
|
|
46
|
+
}
|
|
47
|
+
return map;
|
|
48
|
+
}, [columns, items, columnOf]);
|
|
49
|
+
const itemsById = useMemo(() => {
|
|
50
|
+
const map = new Map();
|
|
51
|
+
for (const item of items)
|
|
52
|
+
map.set(keyOf(item), item);
|
|
53
|
+
return map;
|
|
54
|
+
}, [items, keyOf]);
|
|
55
|
+
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
56
|
+
const collisionDetection = useCallback((args) => {
|
|
57
|
+
const pointerHits = pointerWithin(args);
|
|
58
|
+
if (pointerHits.length > 0) {
|
|
59
|
+
const column = pointerHits.find((hit) => String(hit.id).startsWith(COLUMN_PREFIX));
|
|
60
|
+
return column ? [column] : pointerHits;
|
|
61
|
+
}
|
|
62
|
+
const intersections = rectIntersection(args);
|
|
63
|
+
if (intersections.length > 0)
|
|
64
|
+
return intersections;
|
|
65
|
+
return closestCenter(args);
|
|
66
|
+
}, []);
|
|
67
|
+
function handleStart(event) {
|
|
68
|
+
setActiveCardId(String(event.active.id));
|
|
69
|
+
}
|
|
70
|
+
function handleOver(event) {
|
|
71
|
+
const { over } = event;
|
|
72
|
+
if (!over) {
|
|
73
|
+
setOverColumnId(null);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const overId = String(over.id);
|
|
77
|
+
const columnId = parseColumnId(overId);
|
|
78
|
+
if (columnId) {
|
|
79
|
+
setOverColumnId(columnId);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const card = parseCardId(overId);
|
|
83
|
+
setOverColumnId(card ? card.columnId : null);
|
|
84
|
+
}
|
|
85
|
+
function handleEnd(event) {
|
|
86
|
+
setActiveCardId(null);
|
|
87
|
+
setOverColumnId(null);
|
|
88
|
+
const { active, over } = event;
|
|
89
|
+
if (!over)
|
|
90
|
+
return;
|
|
91
|
+
const activeId = String(active.id);
|
|
92
|
+
const overId = String(over.id);
|
|
93
|
+
const parsed = parseCardId(activeId);
|
|
94
|
+
if (!parsed)
|
|
95
|
+
return;
|
|
96
|
+
let targetColumnId = parseColumnId(overId);
|
|
97
|
+
let overItemId = null;
|
|
98
|
+
if (!targetColumnId) {
|
|
99
|
+
const overCard = parseCardId(overId);
|
|
100
|
+
if (overCard) {
|
|
101
|
+
targetColumnId = overCard.columnId;
|
|
102
|
+
overItemId = overCard.itemId;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!targetColumnId)
|
|
106
|
+
return;
|
|
107
|
+
const targetList = (itemsByColumn.get(targetColumnId) ?? []).filter((item) => keyOf(item) !== parsed.itemId);
|
|
108
|
+
let toIndex;
|
|
109
|
+
if (overItemId && overItemId !== parsed.itemId) {
|
|
110
|
+
const overIndex = targetList.findIndex((item) => keyOf(item) === overItemId);
|
|
111
|
+
toIndex = overIndex < 0 ? targetList.length : overIndex;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
toIndex = targetList.length;
|
|
115
|
+
}
|
|
116
|
+
if (targetColumnId === parsed.columnId && activeId === overId)
|
|
117
|
+
return;
|
|
118
|
+
onMove(parsed.itemId, targetColumnId, toIndex);
|
|
119
|
+
}
|
|
120
|
+
const activeItemId = activeCardId ? (parseCardId(activeCardId)?.itemId ?? null) : null;
|
|
121
|
+
const activeItem = activeItemId ? (itemsById.get(activeItemId) ?? null) : null;
|
|
122
|
+
return (_jsx("div", { "data-slot": "kanban-board", className: className ?? 'min-h-0 flex-1 overflow-x-auto overflow-y-hidden', children: _jsxs(DndContext, { sensors: sensors, collisionDetection: collisionDetection, onDragStart: handleStart, onDragOver: handleOver, onDragEnd: handleEnd, onDragCancel: () => {
|
|
123
|
+
setActiveCardId(null);
|
|
124
|
+
setOverColumnId(null);
|
|
125
|
+
}, children: [_jsx("div", { className: "flex h-full min-w-max gap-3", children: columns.map((column) => {
|
|
126
|
+
const columnItems = itemsByColumn.get(column.id) ?? [];
|
|
127
|
+
return (_jsx(KanbanColumnDroppable, { column: column, isOver: overColumnId === column.id, renderColumn: renderColumn, children: _jsx(SortableContext, { items: columnItems.map((item) => makeCardId(column.id, keyOf(item))), strategy: verticalListSortingStrategy, children: columnItems.map((item) => (_jsx(KanbanCard, { id: makeCardId(column.id, keyOf(item)), item: item, renderCard: renderCard }, keyOf(item)))) }) }, column.id));
|
|
128
|
+
}) }), _jsx(DragPreview, { children: activeItem ? renderCard(activeItem, { isDragging: true, dragHandleProps: {} }) : null })] }) }));
|
|
129
|
+
}
|
|
130
|
+
function KanbanColumnDroppable({ column, isOver: isOverColumn, renderColumn, children, }) {
|
|
131
|
+
const { setNodeRef, isOver } = useDroppable({ id: makeColumnId(column.id) });
|
|
132
|
+
return (_jsx("div", { ref: setNodeRef, className: "flex h-full flex-col", children: renderColumn(column, { children, isOver: isOver || isOverColumn }) }));
|
|
133
|
+
}
|
|
134
|
+
function KanbanCard({ id, item, renderCard, }) {
|
|
135
|
+
const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({
|
|
136
|
+
id,
|
|
137
|
+
});
|
|
138
|
+
const style = {
|
|
139
|
+
transform: CSS.Transform.toString(transform),
|
|
140
|
+
transition,
|
|
141
|
+
opacity: isDragging ? 0.4 : 1,
|
|
142
|
+
};
|
|
143
|
+
const dragHandleProps = { ...attributes, ...listeners };
|
|
144
|
+
return (_jsx("div", { ref: setNodeRef, style: style, ...attributes, ...listeners, "aria-roledescription": "draggable card", children: renderCard(item, { isDragging, dragHandleProps }) }));
|
|
145
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '../lib/cn.js';
|
|
3
|
+
export function Kbd({ className, ...props }) {
|
|
4
|
+
return (_jsx("kbd", { "data-slot": "kbd", className: cn('pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*="size-"])]:size-3', className), ...props }));
|
|
5
|
+
}
|
|
6
|
+
export function KbdGroup({ className, ...props }) {
|
|
7
|
+
return _jsx("div", { "data-slot": "kbd-group", className: cn('inline-flex items-center gap-1', className), ...props });
|
|
8
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Label as LabelPrimitive } from "radix-ui";
|
|
5
|
+
import { cn } from '../lib/cn.js';
|
|
6
|
+
function Label({ className, ...props }) {
|
|
7
|
+
return (_jsx(LabelPrimitive.Root, { "data-slot": "label", className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className), ...props }));
|
|
8
|
+
}
|
|
9
|
+
export { Label };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { MarkdownEditor, markdownToHtml, serializeMarkdown } from './markdown-editor.js';
|
|
2
|
+
export type { MarkdownEditorProps } from './markdown-editor.js';
|
|
3
|
+
export { VimExtension, type VimExtensionOptions, type VimMode } from './vim.js';
|
|
4
|
+
export type { TiptapNode } from './serialize.js';
|