@kortix/ui 0.0.0-bootstrap.0 → 0.14.3
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 +153 -2
- package/dist/_vendor/kortix-shared.js +341 -0
- package/dist/chat/agent-picker.d.ts +8 -0
- package/dist/chat/agent-picker.js +18 -0
- package/dist/chat/composer.d.ts +31 -0
- package/dist/chat/composer.js +114 -0
- package/dist/chat/index.d.ts +22 -0
- package/dist/chat/index.js +22 -0
- package/dist/chat/markdown.d.ts +10 -0
- package/dist/chat/markdown.js +36 -0
- package/dist/chat/message-list.d.ts +25 -0
- package/dist/chat/message-list.js +73 -0
- package/dist/chat/message-view.d.ts +17 -0
- package/dist/chat/message-view.js +86 -0
- package/dist/chat/model-picker.d.ts +10 -0
- package/dist/chat/model-picker.js +68 -0
- package/dist/chat/permission-prompt.d.ts +10 -0
- package/dist/chat/permission-prompt.js +40 -0
- package/dist/chat/question-prompt.d.ts +8 -0
- package/dist/chat/question-prompt.js +60 -0
- package/dist/chat/send-failure.d.ts +9 -0
- package/dist/chat/send-failure.js +21 -0
- package/dist/chat/session-thread.d.ts +28 -0
- package/dist/chat/session-thread.js +47 -0
- package/dist/chat/streaming-markdown.d.ts +21 -0
- package/dist/chat/streaming-markdown.js +59 -0
- package/dist/chat/tool-call.d.ts +4 -0
- package/dist/chat/tool-call.js +150 -0
- package/dist/chat/user-message-parts.d.ts +6 -0
- package/dist/chat/user-message-parts.js +11 -0
- package/dist/components/ui/accordion.d.ts +7 -0
- package/dist/components/ui/accordion.js +18 -0
- package/dist/components/ui/alert-dialog.d.ts +19 -0
- package/dist/components/ui/alert-dialog.js +48 -0
- package/dist/components/ui/alert.d.ts +13 -0
- package/dist/components/ui/alert.js +67 -0
- package/dist/components/ui/avatar.d.ts +11 -0
- package/dist/components/ui/avatar.js +23 -0
- package/dist/components/ui/back-pill.d.ts +13 -0
- package/dist/components/ui/back-pill.js +18 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.js +42 -0
- package/dist/components/ui/breadcrumb.d.ts +11 -0
- package/dist/components/ui/breadcrumb.js +28 -0
- package/dist/components/ui/bubble.d.ts +20 -0
- package/dist/components/ui/bubble.js +38 -0
- package/dist/components/ui/button-group.d.ts +9 -0
- package/dist/components/ui/button-group.js +32 -0
- package/dist/components/ui/button.d.ts +13 -0
- package/dist/components/ui/button.js +67 -0
- package/dist/components/ui/calendar.d.ts +4 -0
- package/dist/components/ui/calendar.js +39 -0
- package/dist/components/ui/card.d.ts +96 -0
- package/dist/components/ui/card.js +291 -0
- package/dist/components/ui/chain-of-thought.d.ts +75 -0
- package/dist/components/ui/chain-of-thought.js +66 -0
- package/dist/components/ui/chart.d.ts +65 -0
- package/dist/components/ui/chart.js +118 -0
- package/dist/components/ui/checkbox-group.d.ts +19 -0
- package/dist/components/ui/checkbox-group.js +41 -0
- package/dist/components/ui/checkbox.d.ts +14 -0
- package/dist/components/ui/checkbox.js +27 -0
- package/dist/components/ui/collapsible.d.ts +5 -0
- package/dist/components/ui/collapsible.js +14 -0
- package/dist/components/ui/command.d.ts +58 -0
- package/dist/components/ui/command.js +135 -0
- package/dist/components/ui/confirm-dialog.d.ts +19 -0
- package/dist/components/ui/confirm-dialog.js +30 -0
- package/dist/components/ui/context-menu.d.ts +45 -0
- package/dist/components/ui/context-menu.js +93 -0
- package/dist/components/ui/count-badge.d.ts +26 -0
- package/dist/components/ui/count-badge.js +26 -0
- package/dist/components/ui/data-grid.d.ts +24 -0
- package/dist/components/ui/data-grid.js +107 -0
- package/dist/components/ui/date-range-picker.d.ts +119 -0
- package/dist/components/ui/date-range-picker.js +190 -0
- package/dist/components/ui/definition-list.d.ts +15 -0
- package/dist/components/ui/definition-list.js +26 -0
- package/dist/components/ui/dialog.d.ts +29 -0
- package/dist/components/ui/dialog.js +52 -0
- package/dist/components/ui/disclosure.d.ts +121 -0
- package/dist/components/ui/disclosure.js +138 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-10.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-10.js +29 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-12.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-12.js +19 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-13.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-13.js +19 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-15.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-15.js +22 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-16.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-16.js +5 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-18.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-18.js +5 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-19.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-19.js +5 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-2.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-2.js +3 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-20.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-20.js +5 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-21.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-21.js +5 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-3.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-3.js +3 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-4.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-4.js +3 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-5.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-5.js +3 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-6.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-6.js +19 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-7.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-7.js +19 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-8.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-8.js +19 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-9.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-3x3-9.js +23 -0
- package/dist/components/ui/dot-matrix/dotm-circular-1.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-1.js +28 -0
- package/dist/components/ui/dot-matrix/dotm-circular-10.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-10.js +40 -0
- package/dist/components/ui/dot-matrix/dotm-circular-11.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-11.js +37 -0
- package/dist/components/ui/dot-matrix/dotm-circular-12.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-12.js +42 -0
- package/dist/components/ui/dot-matrix/dotm-circular-14.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-14.js +37 -0
- package/dist/components/ui/dot-matrix/dotm-circular-15.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-15.js +49 -0
- package/dist/components/ui/dot-matrix/dotm-circular-17.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-17.js +31 -0
- package/dist/components/ui/dot-matrix/dotm-circular-2.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-2.js +37 -0
- package/dist/components/ui/dot-matrix/dotm-circular-3.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-3.js +54 -0
- package/dist/components/ui/dot-matrix/dotm-circular-4.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-4.js +35 -0
- package/dist/components/ui/dot-matrix/dotm-circular-5.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-5.js +30 -0
- package/dist/components/ui/dot-matrix/dotm-circular-6.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-6.js +37 -0
- package/dist/components/ui/dot-matrix/dotm-circular-7.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-7.js +25 -0
- package/dist/components/ui/dot-matrix/dotm-circular-8.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-8.js +26 -0
- package/dist/components/ui/dot-matrix/dotm-circular-9.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-circular-9.js +41 -0
- package/dist/components/ui/dot-matrix/dotm-square-1.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-1.js +27 -0
- package/dist/components/ui/dot-matrix/dotm-square-10.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-10.js +27 -0
- package/dist/components/ui/dot-matrix/dotm-square-11.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-11.js +25 -0
- package/dist/components/ui/dot-matrix/dotm-square-12.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-12.js +28 -0
- package/dist/components/ui/dot-matrix/dotm-square-13.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-13.js +45 -0
- package/dist/components/ui/dot-matrix/dotm-square-14.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-14.js +38 -0
- package/dist/components/ui/dot-matrix/dotm-square-15.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-15.js +31 -0
- package/dist/components/ui/dot-matrix/dotm-square-16.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-16.js +33 -0
- package/dist/components/ui/dot-matrix/dotm-square-17.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-17.js +27 -0
- package/dist/components/ui/dot-matrix/dotm-square-18.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-18.js +29 -0
- package/dist/components/ui/dot-matrix/dotm-square-19.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-19.js +74 -0
- package/dist/components/ui/dot-matrix/dotm-square-2.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-2.js +72 -0
- package/dist/components/ui/dot-matrix/dotm-square-20.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-20.js +79 -0
- package/dist/components/ui/dot-matrix/dotm-square-3.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-3.js +23 -0
- package/dist/components/ui/dot-matrix/dotm-square-4.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-4.js +41 -0
- package/dist/components/ui/dot-matrix/dotm-square-5.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-5.js +23 -0
- package/dist/components/ui/dot-matrix/dotm-square-6.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-6.js +20 -0
- package/dist/components/ui/dot-matrix/dotm-square-7.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-7.js +43 -0
- package/dist/components/ui/dot-matrix/dotm-square-8.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-8.js +57 -0
- package/dist/components/ui/dot-matrix/dotm-square-9.d.ts +4 -0
- package/dist/components/ui/dot-matrix/dotm-square-9.js +89 -0
- package/dist/components/ui/dot-matrix/session-dot-matrix.d.ts +46 -0
- package/dist/components/ui/dot-matrix/session-dot-matrix.js +153 -0
- package/dist/components/ui/drawer.d.ts +15 -0
- package/dist/components/ui/drawer.js +35 -0
- package/dist/components/ui/dropdown-menu.d.ts +49 -0
- package/dist/components/ui/dropdown-menu.js +113 -0
- package/dist/components/ui/emoji-picker.d.ts +15 -0
- package/dist/components/ui/emoji-picker.js +137 -0
- package/dist/components/ui/emoji-tint.d.ts +41 -0
- package/dist/components/ui/emoji-tint.js +131 -0
- package/dist/components/ui/empty.d.ts +11 -0
- package/dist/components/ui/empty.js +33 -0
- package/dist/components/ui/entity-avatar.d.ts +84 -0
- package/dist/components/ui/entity-avatar.js +106 -0
- package/dist/components/ui/faded-scroll-area.d.ts +8 -0
- package/dist/components/ui/faded-scroll-area.js +80 -0
- package/dist/components/ui/favicon-avatar.d.ts +32 -0
- package/dist/components/ui/favicon-avatar.js +18 -0
- package/dist/components/ui/field.d.ts +15 -0
- package/dist/components/ui/field.js +48 -0
- package/dist/components/ui/file-tree.d.ts +32 -0
- package/dist/components/ui/file-tree.js +30 -0
- package/dist/components/ui/glyph-face.d.ts +18 -0
- package/dist/components/ui/glyph-face.js +37 -0
- package/dist/components/ui/glyph-paths-source.d.ts +2 -0
- package/dist/components/ui/glyph-paths-source.js +40 -0
- package/dist/components/ui/glyph-paths.generated.d.ts +2 -0
- package/dist/components/ui/glyph-paths.generated.js +207 -0
- package/dist/components/ui/glyph-picker.d.ts +22 -0
- package/dist/components/ui/glyph-picker.js +118 -0
- package/dist/components/ui/glyph-registry.d.ts +36 -0
- package/dist/components/ui/glyph-registry.js +479 -0
- package/dist/components/ui/glyph-tint.d.ts +6 -0
- package/dist/components/ui/glyph-tint.js +93 -0
- package/dist/components/ui/hint.d.ts +14 -0
- package/dist/components/ui/hint.js +12 -0
- package/dist/components/ui/histogram-bars.d.ts +38 -0
- package/dist/components/ui/histogram-bars.js +93 -0
- package/dist/components/ui/hover-card.d.ts +28 -0
- package/dist/components/ui/hover-card.js +35 -0
- package/dist/components/ui/icon-provider.d.ts +23 -0
- package/dist/components/ui/icon-provider.js +30 -0
- package/dist/components/ui/info-banner.d.ts +14 -0
- package/dist/components/ui/info-banner.js +72 -0
- package/dist/components/ui/inline-meta.d.ts +6 -0
- package/dist/components/ui/inline-meta.js +8 -0
- package/dist/components/ui/input-group.d.ts +19 -0
- package/dist/components/ui/input-group.js +73 -0
- package/dist/components/ui/input.d.ts +26 -0
- package/dist/components/ui/input.js +23 -0
- package/dist/components/ui/item.d.ts +23 -0
- package/dist/components/ui/item.js +67 -0
- package/dist/components/ui/kbd.d.ts +3 -0
- package/dist/components/ui/kbd.js +20 -0
- package/dist/components/ui/kortix-asterisk.d.ts +6 -0
- package/dist/components/ui/kortix-asterisk.js +17 -0
- package/dist/components/ui/kortix-icons.d.ts +2 -0
- package/dist/components/ui/kortix-icons.js +17 -0
- package/dist/components/ui/kortix-loader.d.ts +76 -0
- package/dist/components/ui/kortix-loader.js +74 -0
- package/dist/components/ui/kortix-logo.d.ts +30 -0
- package/dist/components/ui/kortix-logo.js +47 -0
- package/dist/components/ui/label.d.ts +4 -0
- package/dist/components/ui/label.js +9 -0
- package/dist/components/ui/list.d.ts +15 -0
- package/dist/components/ui/list.js +25 -0
- package/dist/components/ui/loading.d.ts +19 -0
- package/dist/components/ui/loading.js +31 -0
- package/dist/components/ui/local-time.d.ts +34 -0
- package/dist/components/ui/local-time.js +60 -0
- package/dist/components/ui/map.d.ts +101 -0
- package/dist/components/ui/map.js +257 -0
- package/dist/components/ui/marker.d.ts +14 -0
- package/dist/components/ui/marker.js +28 -0
- package/dist/components/ui/menu-recipe.d.ts +102 -0
- package/dist/components/ui/menu-recipe.js +129 -0
- package/dist/components/ui/mermaid-render.d.ts +51 -0
- package/dist/components/ui/mermaid-render.js +65 -0
- package/dist/components/ui/mermaid-renderer.d.ts +13 -0
- package/dist/components/ui/mermaid-renderer.js +340 -0
- package/dist/components/ui/message.d.ts +15 -0
- package/dist/components/ui/message.js +26 -0
- package/dist/components/ui/modal.d.ts +104 -0
- package/dist/components/ui/modal.js +180 -0
- package/dist/components/ui/navigation-menu.d.ts +16 -0
- package/dist/components/ui/navigation-menu.js +35 -0
- package/dist/components/ui/page-search-bar.d.ts +11 -0
- package/dist/components/ui/page-search-bar.js +13 -0
- package/dist/components/ui/phone-input.d.ts +7 -0
- package/dist/components/ui/phone-input.js +59 -0
- package/dist/components/ui/pixel-kortix-mark.d.ts +13 -0
- package/dist/components/ui/pixel-kortix-mark.js +40 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +38 -0
- package/dist/components/ui/portal.d.ts +5 -0
- package/dist/components/ui/portal.js +15 -0
- package/dist/components/ui/preview-image.d.ts +14 -0
- package/dist/components/ui/preview-image.js +58 -0
- package/dist/components/ui/progress-ring.d.ts +6 -0
- package/dist/components/ui/progress-ring.js +9 -0
- package/dist/components/ui/progress.d.ts +6 -0
- package/dist/components/ui/progress.js +8 -0
- package/dist/components/ui/radio-group.d.ts +12 -0
- package/dist/components/ui/radio-group.js +20 -0
- package/dist/components/ui/resizable.d.ts +24 -0
- package/dist/components/ui/resizable.js +16 -0
- package/dist/components/ui/scroll-area.d.ts +5 -0
- package/dist/components/ui/scroll-area.js +11 -0
- package/dist/components/ui/section-card.d.ts +37 -0
- package/dist/components/ui/section-card.js +14 -0
- package/dist/components/ui/section.d.ts +10 -0
- package/dist/components/ui/section.js +22 -0
- package/dist/components/ui/select.d.ts +25 -0
- package/dist/components/ui/select.js +59 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/separator.js +8 -0
- package/dist/components/ui/shader-safe.d.ts +48 -0
- package/dist/components/ui/shader-safe.js +74 -0
- package/dist/components/ui/sheet.d.ts +32 -0
- package/dist/components/ui/sheet.js +55 -0
- package/dist/components/ui/sidebar-context.d.ts +72 -0
- package/dist/components/ui/sidebar-context.js +36 -0
- package/dist/components/ui/sidebar-menu-primitives.d.ts +38 -0
- package/dist/components/ui/sidebar-menu-primitives.js +97 -0
- package/dist/components/ui/sidebar-panel.d.ts +36 -0
- package/dist/components/ui/sidebar-panel.js +265 -0
- package/dist/components/ui/sidebar-peek.d.ts +27 -0
- package/dist/components/ui/sidebar-peek.js +70 -0
- package/dist/components/ui/sidebar-width.d.ts +48 -0
- package/dist/components/ui/sidebar-width.js +62 -0
- package/dist/components/ui/sidebar.d.ts +18 -0
- package/dist/components/ui/sidebar.js +194 -0
- package/dist/components/ui/skeleton.d.ts +3 -0
- package/dist/components/ui/skeleton.js +6 -0
- package/dist/components/ui/slider-native.d.ts +7 -0
- package/dist/components/ui/slider-native.js +16 -0
- package/dist/components/ui/slider.d.ts +14 -0
- package/dist/components/ui/slider.js +48 -0
- package/dist/components/ui/sliding-tab-indicator.d.ts +61 -0
- package/dist/components/ui/sliding-tab-indicator.js +128 -0
- package/dist/components/ui/split-sheet.d.ts +61 -0
- package/dist/components/ui/split-sheet.js +239 -0
- package/dist/components/ui/spotlight-card.d.ts +8 -0
- package/dist/components/ui/spotlight-card.js +43 -0
- package/dist/components/ui/status-ring.d.ts +38 -0
- package/dist/components/ui/status-ring.js +38 -0
- package/dist/components/ui/status.d.ts +58 -0
- package/dist/components/ui/status.js +76 -0
- package/dist/components/ui/stepper.d.ts +28 -0
- package/dist/components/ui/stepper.js +73 -0
- package/dist/components/ui/switch.d.ts +8 -0
- package/dist/components/ui/switch.js +131 -0
- package/dist/components/ui/system-message.d.ts +23 -0
- package/dist/components/ui/system-message.js +51 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/table.js +28 -0
- package/dist/components/ui/tabs.d.ts +73 -0
- package/dist/components/ui/tabs.js +207 -0
- package/dist/components/ui/tag.d.ts +7 -0
- package/dist/components/ui/tag.js +22 -0
- package/dist/components/ui/text-shimmer.d.ts +13 -0
- package/dist/components/ui/text-shimmer.js +91 -0
- package/dist/components/ui/textarea.d.ts +33 -0
- package/dist/components/ui/textarea.js +87 -0
- package/dist/components/ui/toast.d.ts +105 -0
- package/dist/components/ui/toast.js +233 -0
- package/dist/components/ui/toggle.d.ts +12 -0
- package/dist/components/ui/toggle.js +26 -0
- package/dist/components/ui/tooltip.d.ts +9 -0
- package/dist/components/ui/tooltip.js +16 -0
- package/dist/components/ui/trigger-variants.d.ts +14 -0
- package/dist/components/ui/trigger-variants.js +67 -0
- package/dist/components/ui/type-to-confirm-dialog.d.ts +88 -0
- package/dist/components/ui/type-to-confirm-dialog.js +101 -0
- package/dist/components/ui/typed-title-logic.d.ts +22 -0
- package/dist/components/ui/typed-title-logic.js +33 -0
- package/dist/components/ui/typed-title.d.ts +38 -0
- package/dist/components/ui/typed-title.js +66 -0
- package/dist/components/ui/typing-animation.d.ts +36 -0
- package/dist/components/ui/typing-animation.js +141 -0
- package/dist/components/ui/user-avatar.d.ts +47 -0
- package/dist/components/ui/user-avatar.js +46 -0
- package/dist/hooks/use-debounce.d.ts +4 -0
- package/dist/hooks/use-debounce.js +17 -0
- package/dist/hooks/use-is-dark.d.ts +2 -0
- package/dist/hooks/use-is-dark.js +27 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/hooks/use-proximity-hover.d.ts +52 -0
- package/dist/hooks/use-proximity-hover.js +232 -0
- package/dist/icons/close.d.ts +2 -0
- package/dist/icons/close.js +7 -0
- package/dist/icons/copy.d.ts +3 -0
- package/dist/icons/copy.js +6 -0
- package/dist/icons/sidebar-toggle.d.ts +13 -0
- package/dist/icons/sidebar-toggle.js +13 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +33 -0
- package/dist/lib/dotmatrix-core.d.ts +113 -0
- package/dist/lib/dotmatrix-core.js +920 -0
- package/dist/lib/dotmatrix-hooks.d.ts +28 -0
- package/dist/lib/dotmatrix-hooks.js +151 -0
- package/dist/lib/favicon.d.ts +4 -0
- package/dist/lib/favicon.js +21 -0
- package/dist/lib/font-weight.d.ts +6 -0
- package/dist/lib/font-weight.js +6 -0
- package/dist/lib/icon-config.d.ts +33 -0
- package/dist/lib/icon-config.js +22 -0
- package/dist/lib/icon-context.d.ts +34 -0
- package/dist/lib/icon-context.js +81 -0
- package/dist/lib/portal-root.d.ts +8 -0
- package/dist/lib/portal-root.js +26 -0
- package/dist/lib/settle.d.ts +16 -0
- package/dist/lib/settle.js +29 -0
- package/dist/lib/springs.d.ts +31 -0
- package/dist/lib/springs.js +29 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/lib/z-stack.d.ts +55 -0
- package/dist/lib/z-stack.js +130 -0
- package/dist/providers/ui-provider.d.ts +141 -0
- package/dist/providers/ui-provider.js +93 -0
- package/dist/styles/dotmatrix-loader.css +1239 -0
- package/dist/styles/fonts.css +46 -0
- package/dist/styles/tailwind.css +10 -0
- package/dist/styles/theme.css +1019 -0
- package/dist/styles/tokens.css +146 -0
- package/dist/styles.css +2 -0
- package/package.json +874 -4
- package/skills/kortix-ui/SKILL.md +150 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Input } from './input.js';
|
|
5
|
+
import { Separator } from './separator.js';
|
|
6
|
+
import { SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON, SidebarContext, resolveInstant, useOptionalSidebar, useSidebar, } from './sidebar-context.js';
|
|
7
|
+
import { createPeekController } from './sidebar-peek.js';
|
|
8
|
+
import { SIDEBAR_WIDTH_COOKIE_NAME, SIDEBAR_WIDTH_PX, clampSidebarWidth, maxSidebarWidth, parseSidebarWidthCookie, } from './sidebar-width.js';
|
|
9
|
+
import { TooltipProvider } from './tooltip.js';
|
|
10
|
+
import { useIsMobile } from '../../hooks/use-mobile.js';
|
|
11
|
+
import { cn } from '../../lib/utils.js';
|
|
12
|
+
import { Sidebar, SidebarTrigger, SidebarEdgePeek, SidebarRail, SidebarInset } from './sidebar-panel.js';
|
|
13
|
+
import { SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, } from './sidebar-menu-primitives.js';
|
|
14
|
+
function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }) {
|
|
15
|
+
const isMobile = useIsMobile();
|
|
16
|
+
const [openMobile, setOpenMobile] = React.useState(false);
|
|
17
|
+
// This is the internal state of the sidebar.
|
|
18
|
+
// We use openProp and setOpenProp for control from outside the component.
|
|
19
|
+
const [_open, _setOpen] = React.useState(defaultOpen);
|
|
20
|
+
const open = openProp ?? _open;
|
|
21
|
+
const setOpen = React.useCallback((value) => {
|
|
22
|
+
const openState = typeof value === 'function' ? value(open) : value;
|
|
23
|
+
if (setOpenProp) {
|
|
24
|
+
// Controlled: whoever owns the state owns its persistence. The
|
|
25
|
+
// settings shell (`features/accounts/hub/account-settings-shell.tsx`)
|
|
26
|
+
// controls its sidebar precisely so a collapse there does not land in
|
|
27
|
+
// this cookie and hide the project sidebar on the next app load.
|
|
28
|
+
setOpenProp(openState);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
_setOpen(openState);
|
|
32
|
+
// This sets the cookie to keep the sidebar state.
|
|
33
|
+
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
34
|
+
}, [setOpenProp, open]);
|
|
35
|
+
// Helper to toggle the sidebar.
|
|
36
|
+
//
|
|
37
|
+
// ⌘B — and any Enter/Space activation of a toggle button — is a
|
|
38
|
+
// keyboard-initiated action on a surface the user hits many times a day, and
|
|
39
|
+
// those get NO motion. The frequency rule is not about the number of
|
|
40
|
+
// milliseconds; it is about the hand expecting the panel to already be there
|
|
41
|
+
// when the fingers come off the keys.
|
|
42
|
+
const [instantToggle, setInstantToggle] = React.useState(false);
|
|
43
|
+
const toggleSidebar = React.useCallback((options) => {
|
|
44
|
+
setInstantToggle(resolveInstant(options));
|
|
45
|
+
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
|
|
46
|
+
}, [isMobile, setOpen, setOpenMobile]);
|
|
47
|
+
// Release the instant flag once the browser has painted the snapped frame, so
|
|
48
|
+
// the NEXT pointer-driven toggle animates again. Double rAF, not a timeout: a
|
|
49
|
+
// `setTimeout(0)` can land before the paint, which would re-declare the
|
|
50
|
+
// transition while the transform is still mid-change and animate the very
|
|
51
|
+
// toggle that asked not to be animated.
|
|
52
|
+
React.useEffect(() => {
|
|
53
|
+
if (!instantToggle)
|
|
54
|
+
return;
|
|
55
|
+
let second = 0;
|
|
56
|
+
const first = requestAnimationFrame(() => {
|
|
57
|
+
second = requestAnimationFrame(() => setInstantToggle(false));
|
|
58
|
+
});
|
|
59
|
+
return () => {
|
|
60
|
+
cancelAnimationFrame(first);
|
|
61
|
+
cancelAnimationFrame(second);
|
|
62
|
+
};
|
|
63
|
+
}, [instantToggle]);
|
|
64
|
+
// Edge-peek flyout state — hover intent lives in a plain controller so the
|
|
65
|
+
// open/close delays are testable without React or wall-clock timers.
|
|
66
|
+
const [peek, setPeek] = React.useState(false);
|
|
67
|
+
const peekController = React.useMemo(() => createPeekController(setPeek), []);
|
|
68
|
+
React.useEffect(() => () => peekController.cancel(), [peekController]);
|
|
69
|
+
React.useEffect(() => {
|
|
70
|
+
if (open || isMobile)
|
|
71
|
+
peekController.cancel();
|
|
72
|
+
}, [open, isMobile, peekController]);
|
|
73
|
+
// Tracks whether the pointer is currently over the panel/edge zone so a
|
|
74
|
+
// menu closing can decide whether to re-arm the flyout's close timer.
|
|
75
|
+
const pointerOverRef = React.useRef(false);
|
|
76
|
+
const peekEnter = React.useCallback(() => {
|
|
77
|
+
pointerOverRef.current = true;
|
|
78
|
+
peekController.enter();
|
|
79
|
+
}, [peekController]);
|
|
80
|
+
const peekLeave = React.useCallback(() => {
|
|
81
|
+
pointerOverRef.current = false;
|
|
82
|
+
peekController.leave();
|
|
83
|
+
}, [peekController]);
|
|
84
|
+
const holdPeek = React.useCallback((held) => peekController.hold(held, () => pointerOverRef.current), [peekController]);
|
|
85
|
+
// ── Resizable width ────────────────────────────────────────────────────
|
|
86
|
+
// `null` means "use the default"; a number is the user's persisted choice.
|
|
87
|
+
// Read straight out of the cookie in the initializer so a resized sidebar
|
|
88
|
+
// never paints at 256px first and then jumps — the wrapper below carries
|
|
89
|
+
// `suppressHydrationWarning` because that read makes the client's first
|
|
90
|
+
// style attribute legitimately differ from the server's.
|
|
91
|
+
const wrapperRef = React.useRef(null);
|
|
92
|
+
const [width, setWidthState] = React.useState(() => typeof document === 'undefined' ? null : parseSidebarWidthCookie(document.cookie));
|
|
93
|
+
const setWidth = React.useCallback((next) => {
|
|
94
|
+
const clamped = clampSidebarWidth(next, window.innerWidth);
|
|
95
|
+
// Write the committed value to the node BEFORE the state update, and never
|
|
96
|
+
// clear the override. A drag leaves an inline `--sidebar-width` on the
|
|
97
|
+
// wrapper; removing it here would paint one frame at the default 20rem if
|
|
98
|
+
// React defers the re-render past the next paint. Writing the same value
|
|
99
|
+
// React is about to render makes the hand-off unobservable.
|
|
100
|
+
wrapperRef.current?.style.setProperty('--sidebar-width', `${clamped}px`);
|
|
101
|
+
setWidthState(clamped);
|
|
102
|
+
document.cookie = `${SIDEBAR_WIDTH_COOKIE_NAME}=${clamped}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
103
|
+
}, []);
|
|
104
|
+
// Live drag feedback without a React render per pointermove. The gap and the
|
|
105
|
+
// panel both size off this one variable, so writing it on the wrapper node
|
|
106
|
+
// IS the update. (Custom properties inherit, so this does cost a style
|
|
107
|
+
// recalc down the tree — acceptable for a drag the user is watching, and the
|
|
108
|
+
// reason it is not used for anything else.)
|
|
109
|
+
const previewWidth = React.useCallback((next) => {
|
|
110
|
+
wrapperRef.current?.style.setProperty('--sidebar-width', `${next}px`);
|
|
111
|
+
}, []);
|
|
112
|
+
// The ratio cap is a live rule, not a write-time one: a stored 416px must
|
|
113
|
+
// not survive the window being dragged down to 900px. Runs once on mount too,
|
|
114
|
+
// which is what re-clamps a value persisted at a wider viewport.
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
const capToViewport = () => setWidthState((current) => {
|
|
117
|
+
if (current === null)
|
|
118
|
+
return current;
|
|
119
|
+
const capped = Math.min(current, maxSidebarWidth(window.innerWidth));
|
|
120
|
+
return capped === current ? current : capped;
|
|
121
|
+
});
|
|
122
|
+
capToViewport();
|
|
123
|
+
window.addEventListener('resize', capToViewport);
|
|
124
|
+
return () => window.removeEventListener('resize', capToViewport);
|
|
125
|
+
}, []);
|
|
126
|
+
// Adds a keyboard shortcut to toggle the sidebar.
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
const handleKeyDown = (event) => {
|
|
129
|
+
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
130
|
+
event.preventDefault();
|
|
131
|
+
toggleSidebar({ instant: true });
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
135
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
136
|
+
}, [toggleSidebar]);
|
|
137
|
+
// We add a state so that we can do data-state="expanded" or "collapsed".
|
|
138
|
+
// This makes it easier to style the sidebar with Tailwind classes.
|
|
139
|
+
const state = open ? 'expanded' : 'collapsed';
|
|
140
|
+
const contextValue = React.useMemo(() => ({
|
|
141
|
+
state,
|
|
142
|
+
open,
|
|
143
|
+
setOpen,
|
|
144
|
+
isMobile,
|
|
145
|
+
openMobile,
|
|
146
|
+
setOpenMobile,
|
|
147
|
+
toggleSidebar,
|
|
148
|
+
instantToggle,
|
|
149
|
+
peek,
|
|
150
|
+
peekEnter,
|
|
151
|
+
peekLeave,
|
|
152
|
+
holdPeek,
|
|
153
|
+
width: width ?? SIDEBAR_WIDTH_PX,
|
|
154
|
+
setWidth,
|
|
155
|
+
previewWidth,
|
|
156
|
+
}), [
|
|
157
|
+
state,
|
|
158
|
+
open,
|
|
159
|
+
setOpen,
|
|
160
|
+
isMobile,
|
|
161
|
+
openMobile,
|
|
162
|
+
setOpenMobile,
|
|
163
|
+
toggleSidebar,
|
|
164
|
+
instantToggle,
|
|
165
|
+
peek,
|
|
166
|
+
peekEnter,
|
|
167
|
+
peekLeave,
|
|
168
|
+
holdPeek,
|
|
169
|
+
width,
|
|
170
|
+
setWidth,
|
|
171
|
+
previewWidth,
|
|
172
|
+
]);
|
|
173
|
+
return (_jsx(SidebarContext.Provider, { value: contextValue, children: _jsx(TooltipProvider, { delayDuration: 0, children: _jsx("div", { "data-slot": "sidebar-wrapper", suppressHydrationWarning: true, style: {
|
|
174
|
+
'--sidebar-width': width === null ? SIDEBAR_WIDTH : `${width}px`,
|
|
175
|
+
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
|
|
176
|
+
...style,
|
|
177
|
+
}, className: cn('group/sidebar-wrapper has-data-[variant=inset]:bg-background flex min-h-svh w-full', className), ...props, ref: wrapperRef, children: children }) }) }));
|
|
178
|
+
}
|
|
179
|
+
function SidebarInput({ className, ...props }) {
|
|
180
|
+
return (_jsx(Input, { "data-slot": "sidebar-input", "data-sidebar": "input", className: cn('bg-background h-8 w-full shadow-none', className), ...props }));
|
|
181
|
+
}
|
|
182
|
+
function SidebarHeader({ className, ...props }) {
|
|
183
|
+
return (_jsx("div", { "data-slot": "sidebar-header", "data-sidebar": "header", className: cn('flex flex-col gap-2 p-2', className), ...props }));
|
|
184
|
+
}
|
|
185
|
+
function SidebarFooter({ className, ...props }) {
|
|
186
|
+
return (_jsx("div", { "data-slot": "sidebar-footer", "data-sidebar": "footer", className: cn('flex flex-col gap-2 p-2', className), ...props }));
|
|
187
|
+
}
|
|
188
|
+
function SidebarSeparator({ className, ...props }) {
|
|
189
|
+
return (_jsx(Separator, { "data-slot": "sidebar-separator", "data-sidebar": "separator", className: cn('bg-background-border mx-2 w-auto', className), ...props }));
|
|
190
|
+
}
|
|
191
|
+
function SidebarContent({ className, ...props }) {
|
|
192
|
+
return (_jsx("div", { "data-slot": "sidebar-content", "data-sidebar": "content", className: cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className), ...props }));
|
|
193
|
+
}
|
|
194
|
+
export { Sidebar, SidebarContent, SidebarContext, SidebarEdgePeek, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useOptionalSidebar, useSidebar, };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '../../lib/utils.js';
|
|
3
|
+
function Skeleton({ className, ...props }) {
|
|
4
|
+
return (_jsx("div", { ...props, className: cn('bg-primary/10 relative animate-pulse overflow-hidden rounded-md py-4', className) }));
|
|
5
|
+
}
|
|
6
|
+
export { Skeleton };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Slider as SliderPrimitive } from 'radix-ui';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
declare function NativeSlider({ className, defaultValue, value, min, max, tooltip, ...props }: React.ComponentProps<typeof SliderPrimitive.Root> & {
|
|
4
|
+
/** Shown in a Hint above the thumb while hovering it. */
|
|
5
|
+
tooltip?: React.ReactNode;
|
|
6
|
+
}): React.JSX.Element;
|
|
7
|
+
export { NativeSlider };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Slider as SliderPrimitive } from 'radix-ui';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import Hint from './hint.js';
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
|
+
const thumb = (_jsx(SliderPrimitive.Thumb, { "data-slot": "slider-thumb", className: "border-ring ring-ring/50 hit-area-4 relative block size-3.5 shrink-0 rounded-full border bg-white transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 disabled:pointer-events-none disabled:opacity-50" }));
|
|
8
|
+
function NativeSlider({ className, defaultValue, value, min = 0, max = 100, tooltip, ...props }) {
|
|
9
|
+
const _values = React.useMemo(() => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]), [value, defaultValue, min, max]);
|
|
10
|
+
return (_jsxs(SliderPrimitive.Root, { "data-slot": "slider", defaultValue: defaultValue, value: value, min: min, max: max, className: cn('relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-40 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col', className), ...props, children: [_jsx(SliderPrimitive.Track, { "data-slot": "slider-track", className: "bg-kortix-base/60 relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1", children: _jsx(SliderPrimitive.Range, { "data-slot": "slider-range", className: "bg-kortix-blue absolute select-none data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full" }) }), Array.from({ length: _values.length }, (_, index) => {
|
|
11
|
+
if (tooltip == null)
|
|
12
|
+
return _jsx(React.Fragment, { children: thumb }, index);
|
|
13
|
+
return (_jsx(Hint, { side: "top", label: tooltip, children: thumb }, index));
|
|
14
|
+
})] }));
|
|
15
|
+
}
|
|
16
|
+
export { NativeSlider };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
type SliderProps = React.ComponentProps<typeof SliderPrimitive.Root> & {
|
|
4
|
+
/**
|
|
5
|
+
* Accessible name for the thumb(s). Radix renders each thumb as the
|
|
6
|
+
* `role="slider"` node, so a name on the root is never announced — it has to
|
|
7
|
+
* land here. Pass an array to name each thumb of a range slider.
|
|
8
|
+
*/
|
|
9
|
+
thumbLabel?: string | string[];
|
|
10
|
+
/** Announced in place of the raw number (`aria-valuetext`), e.g. `40%`, `0.85`. */
|
|
11
|
+
formatValue?: (value: number, index: number) => string;
|
|
12
|
+
};
|
|
13
|
+
declare function Slider({ className, defaultValue, value, min, max, onValueChange, thumbLabel, formatValue, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }: SliderProps): React.JSX.Element;
|
|
14
|
+
export { Slider };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { cn } from '../../lib/utils.js';
|
|
6
|
+
function Slider({ className, defaultValue, value, min = 0, max = 100, onValueChange, thumbLabel, formatValue, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }) {
|
|
7
|
+
const [uncontrolledValues, setUncontrolledValues] = React.useState(() => Array.isArray(defaultValue) ? defaultValue : [min, max]);
|
|
8
|
+
const values = Array.isArray(value) ? value : uncontrolledValues;
|
|
9
|
+
const handleValueChange = React.useCallback((next) => {
|
|
10
|
+
setUncontrolledValues(next);
|
|
11
|
+
onValueChange?.(next);
|
|
12
|
+
}, [onValueChange]);
|
|
13
|
+
const labelFor = (index) => {
|
|
14
|
+
if (Array.isArray(thumbLabel))
|
|
15
|
+
return thumbLabel[index];
|
|
16
|
+
const base = thumbLabel ?? ariaLabel;
|
|
17
|
+
if (!base || values.length < 2)
|
|
18
|
+
return base;
|
|
19
|
+
if (index === 0)
|
|
20
|
+
return `${base} minimum`;
|
|
21
|
+
if (index === values.length - 1)
|
|
22
|
+
return `${base} maximum`;
|
|
23
|
+
return `${base} ${index + 1}`;
|
|
24
|
+
};
|
|
25
|
+
return (_jsxs(SliderPrimitive.Root, { "data-slot": "slider", defaultValue: defaultValue, value: value, min: min, max: max, onValueChange: handleValueChange, className: cn('group/slider relative flex w-full cursor-pointer touch-none items-center select-none', 'data-disabled:pointer-events-none data-disabled:cursor-default data-disabled:opacity-50', // cursor-default: disabled control.
|
|
26
|
+
'data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col', className), ...props, children: [_jsx(SliderPrimitive.Track, { "data-slot": "slider-track", className: cn(
|
|
27
|
+
// Hairline rail: the whole control is one thin ink stroke.
|
|
28
|
+
'bg-primary/10 relative grow overflow-hidden rounded-full', 'data-[orientation=horizontal]:h-2 data-[orientation=horizontal]:w-full', 'data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1'), children: _jsx(SliderPrimitive.Range, { "data-slot": "slider-range", className: cn('bg-primary absolute rounded-full data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full') }) }), values.map((_, index) => (_jsx(SliderPrimitive.Thumb, { "data-slot": "slider-thumb", "aria-label": labelFor(index), "aria-labelledby": ariaLabelledBy, "aria-valuetext": formatValue ? formatValue(values[index] ?? min, index) : undefined, className: cn(
|
|
29
|
+
// Caret thumb: a short vertical bar in the same ink as the fill, so
|
|
30
|
+
// the range reads as one continuous stroke that rises into a handle.
|
|
31
|
+
'bg-primary block h-4 w-2 shrink-0 rounded-full', 'group-data-[orientation=vertical]/slider:h-1 group-data-[orientation=vertical]/slider:w-4',
|
|
32
|
+
// 44x51px touch target without shifting layout.
|
|
33
|
+
'hit-area-x-4 hit-area-y-5 cursor-pointer',
|
|
34
|
+
// `scale` composes with Radix's inline `translate(-50%)` (Tailwind v4
|
|
35
|
+
// uses the standalone `scale` property), so the bar grows around its
|
|
36
|
+
// own center without breaking thumb positioning.
|
|
37
|
+
'duration-fast ease-default transition-[scale,box-shadow] outline-none', 'active:scale-x-150 active:scale-y-125',
|
|
38
|
+
// Focus: accent ring with a surface-coloured gap that punches through
|
|
39
|
+
// the track, so the indicator reads as "on the thumb".
|
|
40
|
+
// `:focus`, not `:focus-visible` — Chrome resolves focus-visible once, at
|
|
41
|
+
// focus time, so a thumb grabbed by pointer would stay unringed for the
|
|
42
|
+
// rest of the interaction even after the user switches to arrow keys.
|
|
43
|
+
'focus:ring-ring focus:ring-offset-background focus:ring-2 focus:ring-offset-2',
|
|
44
|
+
// Forced-colors mode strips box-shadow rings; a transparent outline is
|
|
45
|
+
// repainted there as a real system-coloured focus ring.
|
|
46
|
+
'focus:outline-2 focus:outline-offset-2 focus:outline-transparent focus:outline-solid', 'data-disabled:pointer-events-none data-disabled:cursor-default') }, index)))] }));
|
|
47
|
+
}
|
|
48
|
+
export { Slider };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type Transition } from 'motion/react';
|
|
2
|
+
import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
3
|
+
type IndicatorRect = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
type Box = {
|
|
10
|
+
left: number;
|
|
11
|
+
top: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The tab's rect in the container's own untransformed coordinate space, or
|
|
17
|
+
* `null` while the container has no layout box.
|
|
18
|
+
*
|
|
19
|
+
* `getBoundingClientRect` reports TRANSFORMED geometry; the indicator is
|
|
20
|
+
* positioned in layout space. Divide the transform back out, or a scaled
|
|
21
|
+
* ancestor bakes its scale into the saved rect.
|
|
22
|
+
*
|
|
23
|
+
* This is not hypothetical. `Modal`/`Dialog` open with
|
|
24
|
+
* `data-[state=open]:zoom-in-95`, and the measuring layout effect runs while
|
|
25
|
+
* that animation is on its first frames — so the pill was saved at 95% and
|
|
26
|
+
* stayed there. `ResizeObserver` cannot rescue it: it reports border-box
|
|
27
|
+
* LAYOUT size, which a transform never changes, so it never fires when the
|
|
28
|
+
* animation lands on `scale(1)`. Measured in a dialog at 1280px: the pill sat
|
|
29
|
+
* 4.5px left and 3.7px narrow of its tab, indefinitely — until an unrelated
|
|
30
|
+
* re-measure (clicking another tab) happened to run unscaled.
|
|
31
|
+
*
|
|
32
|
+
* `layout` is the container's border box from `getComputedStyle`, which is
|
|
33
|
+
* fractional. It must not be `offsetWidth`/`offsetHeight`: those round to whole
|
|
34
|
+
* pixels, and every track here is a fraction wide (`--spacing` is 0.23rem). A
|
|
35
|
+
* 258.61px track divided by its rounded 259 is a scale of 0.9985, which pushed
|
|
36
|
+
* the pill right and widened it in proportion to its distance from the left
|
|
37
|
+
* edge — nothing on the first tab, 0.37px on the last of three, enough to put
|
|
38
|
+
* the chip's ring on the track's right edge.
|
|
39
|
+
*
|
|
40
|
+
* An unscaled rect is also snapped to device pixels, edge by edge, the way the
|
|
41
|
+
* browser snaps the tab's own box. The tab sits at a fractional offset and the
|
|
42
|
+
* pill is moved there by a transform, which the browser does not snap: the
|
|
43
|
+
* pill's ring blurred across two pixels and ate the track beside it, while the
|
|
44
|
+
* track and the first tab stayed sharp. Whole device pixels for the offset and
|
|
45
|
+
* the size make the pill land on exactly the pixels the tab covers.
|
|
46
|
+
*/
|
|
47
|
+
export declare function toLayoutRect(container: Box, tab: Box, layout: {
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
}, scroll: {
|
|
51
|
+
left: number;
|
|
52
|
+
top: number;
|
|
53
|
+
}, dpr?: number): IndicatorRect | null;
|
|
54
|
+
export declare function SlidingTabIndicator({ activeId, indicatorClassName, className, transition, children, ...props }: {
|
|
55
|
+
activeId: string;
|
|
56
|
+
indicatorClassName?: string;
|
|
57
|
+
className?: string;
|
|
58
|
+
transition?: Transition;
|
|
59
|
+
children: ReactNode;
|
|
60
|
+
} & ComponentPropsWithoutRef<'div'>): import("react").JSX.Element;
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../../lib/utils.js';
|
|
4
|
+
import { m, useReducedMotion } from 'motion/react';
|
|
5
|
+
import { useCallback, useLayoutEffect, useRef, useState, } from 'react';
|
|
6
|
+
const EMPTY_RECT = { x: 0, y: 0, width: 0, height: 0 };
|
|
7
|
+
/**
|
|
8
|
+
* The tab's rect in the container's own untransformed coordinate space, or
|
|
9
|
+
* `null` while the container has no layout box.
|
|
10
|
+
*
|
|
11
|
+
* `getBoundingClientRect` reports TRANSFORMED geometry; the indicator is
|
|
12
|
+
* positioned in layout space. Divide the transform back out, or a scaled
|
|
13
|
+
* ancestor bakes its scale into the saved rect.
|
|
14
|
+
*
|
|
15
|
+
* This is not hypothetical. `Modal`/`Dialog` open with
|
|
16
|
+
* `data-[state=open]:zoom-in-95`, and the measuring layout effect runs while
|
|
17
|
+
* that animation is on its first frames — so the pill was saved at 95% and
|
|
18
|
+
* stayed there. `ResizeObserver` cannot rescue it: it reports border-box
|
|
19
|
+
* LAYOUT size, which a transform never changes, so it never fires when the
|
|
20
|
+
* animation lands on `scale(1)`. Measured in a dialog at 1280px: the pill sat
|
|
21
|
+
* 4.5px left and 3.7px narrow of its tab, indefinitely — until an unrelated
|
|
22
|
+
* re-measure (clicking another tab) happened to run unscaled.
|
|
23
|
+
*
|
|
24
|
+
* `layout` is the container's border box from `getComputedStyle`, which is
|
|
25
|
+
* fractional. It must not be `offsetWidth`/`offsetHeight`: those round to whole
|
|
26
|
+
* pixels, and every track here is a fraction wide (`--spacing` is 0.23rem). A
|
|
27
|
+
* 258.61px track divided by its rounded 259 is a scale of 0.9985, which pushed
|
|
28
|
+
* the pill right and widened it in proportion to its distance from the left
|
|
29
|
+
* edge — nothing on the first tab, 0.37px on the last of three, enough to put
|
|
30
|
+
* the chip's ring on the track's right edge.
|
|
31
|
+
*
|
|
32
|
+
* An unscaled rect is also snapped to device pixels, edge by edge, the way the
|
|
33
|
+
* browser snaps the tab's own box. The tab sits at a fractional offset and the
|
|
34
|
+
* pill is moved there by a transform, which the browser does not snap: the
|
|
35
|
+
* pill's ring blurred across two pixels and ate the track beside it, while the
|
|
36
|
+
* track and the first tab stayed sharp. Whole device pixels for the offset and
|
|
37
|
+
* the size make the pill land on exactly the pixels the tab covers.
|
|
38
|
+
*/
|
|
39
|
+
export function toLayoutRect(container, tab, layout, scroll, dpr = 1) {
|
|
40
|
+
const scaleX = layout.width > 0 ? container.width / layout.width : 0;
|
|
41
|
+
const scaleY = layout.height > 0 ? container.height / layout.height : 0;
|
|
42
|
+
if (!scaleX || !scaleY)
|
|
43
|
+
return null;
|
|
44
|
+
// A computed size is serialized to a few decimals, so an unscaled ratio is
|
|
45
|
+
// 1 within ~1e-5. A real transform (`zoom-in-95`) is far outside this.
|
|
46
|
+
if (Math.abs(scaleX - 1) < 1e-4 && Math.abs(scaleY - 1) < 1e-4) {
|
|
47
|
+
const snap = (v) => Math.round(v * dpr) / dpr;
|
|
48
|
+
const left = snap(tab.left);
|
|
49
|
+
const top = snap(tab.top);
|
|
50
|
+
// The offset is from the container's UNSNAPPED origin. The pill is an
|
|
51
|
+
// absolute child moved by a transform, so it paints at the container's
|
|
52
|
+
// fractional position plus `x`; only the track's own background is
|
|
53
|
+
// snapped. Subtracting the snapped origin left the container's fraction in
|
|
54
|
+
// the pill — a whole-pill shift of up to half a device pixel. On a track at
|
|
55
|
+
// x = 29.25 (2x) the first tab's chip sat 1.75px from the track's left edge
|
|
56
|
+
// and the last tab's 2.25px from its right: the 1px ring swallowed the
|
|
57
|
+
// track on one side only.
|
|
58
|
+
return {
|
|
59
|
+
x: left - container.left + scroll.left,
|
|
60
|
+
y: top - container.top + scroll.top,
|
|
61
|
+
width: snap(tab.left + tab.width) - left,
|
|
62
|
+
height: snap(tab.top + tab.height) - top,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
x: (tab.left - container.left) / scaleX + scroll.left,
|
|
67
|
+
y: (tab.top - container.top) / scaleY + scroll.top,
|
|
68
|
+
width: tab.width / scaleX,
|
|
69
|
+
height: tab.height / scaleY,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function SlidingTabIndicator({ activeId, indicatorClassName, className, transition, children, ...props }) {
|
|
73
|
+
const reduceMotion = useReducedMotion();
|
|
74
|
+
const containerRef = useRef(null);
|
|
75
|
+
const [rect, setRect] = useState(EMPTY_RECT);
|
|
76
|
+
const [visible, setVisible] = useState(false);
|
|
77
|
+
const measure = useCallback(() => {
|
|
78
|
+
const container = containerRef.current;
|
|
79
|
+
if (!container)
|
|
80
|
+
return;
|
|
81
|
+
const tab = container.querySelector(`[data-sliding-tab="${activeId}"]`);
|
|
82
|
+
if (!tab) {
|
|
83
|
+
setVisible(false);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Preflight makes every box `border-box`, so the computed width and height
|
|
87
|
+
// are the border box — the same box `getBoundingClientRect` measures.
|
|
88
|
+
const style = getComputedStyle(container);
|
|
89
|
+
const next = toLayoutRect(container.getBoundingClientRect(), tab.getBoundingClientRect(), { width: parseFloat(style.width), height: parseFloat(style.height) }, { left: container.scrollLeft, top: container.scrollTop }, window.devicePixelRatio);
|
|
90
|
+
// No layout box yet (an unmounted or `display:none` ancestor). Showing a
|
|
91
|
+
// pill from a zero rect draws it at 0×0 in the corner; wait for the
|
|
92
|
+
// ResizeObserver below, which DOES fire for a real size change.
|
|
93
|
+
if (!next) {
|
|
94
|
+
setVisible(false);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
setRect(next);
|
|
98
|
+
setVisible(true);
|
|
99
|
+
}, [activeId]);
|
|
100
|
+
useLayoutEffect(() => {
|
|
101
|
+
measure();
|
|
102
|
+
}, [measure]);
|
|
103
|
+
useLayoutEffect(() => {
|
|
104
|
+
const container = containerRef.current;
|
|
105
|
+
if (!container)
|
|
106
|
+
return;
|
|
107
|
+
const ro = new ResizeObserver(() => measure());
|
|
108
|
+
ro.observe(container);
|
|
109
|
+
const tabs = container.querySelectorAll('[data-sliding-tab]');
|
|
110
|
+
tabs.forEach((tab) => ro.observe(tab));
|
|
111
|
+
window.addEventListener('resize', measure);
|
|
112
|
+
container.addEventListener('scroll', measure, { passive: true });
|
|
113
|
+
return () => {
|
|
114
|
+
ro.disconnect();
|
|
115
|
+
window.removeEventListener('resize', measure);
|
|
116
|
+
container.removeEventListener('scroll', measure);
|
|
117
|
+
};
|
|
118
|
+
}, [measure, activeId]);
|
|
119
|
+
const resolvedTransition = reduceMotion
|
|
120
|
+
? { duration: 0 }
|
|
121
|
+
: (transition ?? { type: 'spring', stiffness: 380, damping: 32 });
|
|
122
|
+
return (_jsxs("div", { ref: containerRef, className: cn('relative', className), ...props, children: [visible ? (_jsx(m.div, { "aria-hidden": true, className: cn('pointer-events-none absolute top-0 left-0 z-0', indicatorClassName), initial: false, animate: {
|
|
123
|
+
x: rect.x,
|
|
124
|
+
y: rect.y,
|
|
125
|
+
width: rect.width,
|
|
126
|
+
height: rect.height,
|
|
127
|
+
}, transition: resolvedTransition })) : null, children] }));
|
|
128
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type TriggerVariantProps } from './trigger-variants.js';
|
|
3
|
+
export type SplitSheetSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
4
|
+
/**
|
|
5
|
+
* The one decision every open/close request goes through. A controlled sheet
|
|
6
|
+
* writes no state of its own: the parent's `open` prop is the only source of
|
|
7
|
+
* truth. Same contract `Disclosure` adopted after its mirrored-state bug.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveSplitSheetChange(state: {
|
|
10
|
+
open: boolean;
|
|
11
|
+
nextOpen: boolean;
|
|
12
|
+
isControlled: boolean;
|
|
13
|
+
}): {
|
|
14
|
+
changed: boolean;
|
|
15
|
+
writesInternalState: boolean;
|
|
16
|
+
};
|
|
17
|
+
/** Read or set the nearest sheet's open state from anywhere inside it. */
|
|
18
|
+
declare function useSplitSheet(): {
|
|
19
|
+
open: boolean;
|
|
20
|
+
setOpen: (open: boolean) => void;
|
|
21
|
+
};
|
|
22
|
+
type SplitSheetProps = React.ComponentProps<'div'> & {
|
|
23
|
+
/** Controlled. Omit entirely (not `false`) for an uncontrolled sheet. */
|
|
24
|
+
open?: boolean;
|
|
25
|
+
/** Uncontrolled starting value. Ignored when `open` is provided. */
|
|
26
|
+
defaultOpen?: boolean;
|
|
27
|
+
onOpenChange?: (open: boolean) => void;
|
|
28
|
+
/** Sheet column width when the root is wide enough to split. */
|
|
29
|
+
size?: SplitSheetSize;
|
|
30
|
+
/** The open sheet COVERS the page cell instead of taking a second column —
|
|
31
|
+
* the same takeover the narrow-container fallback already does, made
|
|
32
|
+
* deliberate. For a root that is itself one pane of a wider split: a
|
|
33
|
+
* second column inside it would put three surfaces on one row. The page
|
|
34
|
+
* stays mounted and keeps its scroll; closing uncovers it. */
|
|
35
|
+
cover?: boolean;
|
|
36
|
+
};
|
|
37
|
+
declare function SplitSheet({ open: openProp, defaultOpen, onOpenChange, size, cover, className, children, ...props }: SplitSheetProps): React.JSX.Element;
|
|
38
|
+
/** The page. Always the first column; it scrolls on its own. */
|
|
39
|
+
declare function SplitSheetMain({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
40
|
+
type SplitSheetTriggerProps = Omit<React.ComponentProps<'button'>, 'ref'> & TriggerVariantProps & {
|
|
41
|
+
asChild?: boolean;
|
|
42
|
+
};
|
|
43
|
+
/** Toggles the sheet. Call `event.preventDefault()` in `onClick` to handle the click yourself. */
|
|
44
|
+
declare function SplitSheetTrigger({ asChild, variant, size, className, type, onClick, ...props }: SplitSheetTriggerProps): React.JSX.Element;
|
|
45
|
+
type SplitSheetCloseProps = Omit<React.ComponentProps<'button'>, 'ref'> & {
|
|
46
|
+
asChild?: boolean;
|
|
47
|
+
};
|
|
48
|
+
declare function SplitSheetClose({ asChild, type, onClick, ...props }: SplitSheetCloseProps): React.JSX.Element;
|
|
49
|
+
/** The sheet column. Renders nothing while closed. Always include a `SplitSheetTitle`. */
|
|
50
|
+
declare function SplitSheetContent(props: Omit<React.ComponentProps<'aside'>, 'ref'>): React.JSX.Element | null;
|
|
51
|
+
type SplitSheetHeaderProps = React.ComponentProps<'div'> & {
|
|
52
|
+
showCloseButton?: boolean;
|
|
53
|
+
closeLabel?: string;
|
|
54
|
+
};
|
|
55
|
+
declare function SplitSheetHeader({ className, children, showCloseButton, closeLabel, ...props }: SplitSheetHeaderProps): React.JSX.Element;
|
|
56
|
+
declare function SplitSheetTitle({ className, ...props }: React.ComponentProps<'h2'>): React.JSX.Element;
|
|
57
|
+
declare function SplitSheetDescription({ className, ...props }: React.ComponentProps<'p'>): React.JSX.Element;
|
|
58
|
+
declare function SplitSheetBody({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
59
|
+
declare function SplitSheetFooter({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
60
|
+
export { SplitSheet, SplitSheetBody, SplitSheetClose, SplitSheetContent, SplitSheetDescription, SplitSheetFooter, SplitSheetHeader, SplitSheetMain, SplitSheetTitle, SplitSheetTrigger, useSplitSheet, };
|
|
61
|
+
export type { SplitSheetProps };
|