@kortix/ui 0.0.0-stage → 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 +155 -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 +881 -4
- package/skills/kortix-ui/SKILL.md +150 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Bubble: the surface of one conversational message. The default variant is
|
|
5
|
+
* the Kortix user bubble (`bg-muted`, `rounded-lg`, the session transcript's
|
|
6
|
+
* BUBBLE_SURFACE). `align` pulls it to the row edge and squares the corner
|
|
7
|
+
* that points at the speaker.
|
|
8
|
+
*/
|
|
9
|
+
declare const bubbleVariants: (props?: ({
|
|
10
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
11
|
+
align?: "start" | "end" | null | undefined;
|
|
12
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
13
|
+
declare function Bubble({ className, variant, align, ...props }: React.ComponentProps<'div'> & VariantProps<typeof bubbleVariants>): React.JSX.Element;
|
|
14
|
+
declare function BubbleContent({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
15
|
+
declare function BubbleReactions({ className, side, align, ...props }: React.ComponentProps<'div'> & {
|
|
16
|
+
side?: 'top' | 'bottom';
|
|
17
|
+
align?: 'start' | 'end';
|
|
18
|
+
}): React.JSX.Element;
|
|
19
|
+
declare function BubbleGroup({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
|
|
20
|
+
export { Bubble, BubbleContent, BubbleGroup, BubbleReactions, bubbleVariants };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from 'class-variance-authority';
|
|
3
|
+
import { cn } from '../../lib/utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Bubble: the surface of one conversational message. The default variant is
|
|
6
|
+
* the Kortix user bubble (`bg-muted`, `rounded-lg`, the session transcript's
|
|
7
|
+
* BUBBLE_SURFACE). `align` pulls it to the row edge and squares the corner
|
|
8
|
+
* that points at the speaker.
|
|
9
|
+
*/
|
|
10
|
+
const bubbleVariants = cva('relative w-fit max-w-[85%] rounded-lg px-3.5 py-2.5 text-sm', {
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: 'bg-muted text-foreground',
|
|
14
|
+
secondary: 'bg-secondary text-secondary-foreground',
|
|
15
|
+
outline: 'border border-border bg-transparent text-foreground',
|
|
16
|
+
ghost: 'bg-transparent px-0 py-0 text-foreground',
|
|
17
|
+
destructive: 'bg-destructive/10 text-foreground',
|
|
18
|
+
},
|
|
19
|
+
align: {
|
|
20
|
+
start: 'mr-auto rounded-bl-sm',
|
|
21
|
+
end: 'ml-auto rounded-br-sm',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: { variant: 'default', align: 'start' },
|
|
25
|
+
});
|
|
26
|
+
function Bubble({ className, variant, align, ...props }) {
|
|
27
|
+
return (_jsx("div", { "data-slot": "bubble", "data-align": align ?? 'start', className: cn(bubbleVariants({ variant, align }), className), ...props }));
|
|
28
|
+
}
|
|
29
|
+
function BubbleContent({ className, ...props }) {
|
|
30
|
+
return (_jsx("div", { "data-slot": "bubble-content", className: cn('font-medium wrap-break-word whitespace-pre-wrap select-text', className), ...props }));
|
|
31
|
+
}
|
|
32
|
+
function BubbleReactions({ className, side = 'bottom', align = 'end', ...props }) {
|
|
33
|
+
return (_jsx("div", { "data-slot": "bubble-reactions", "data-side": side, className: cn('flex flex-wrap gap-1', side === 'top' ? '-mt-1 mb-1' : '-mb-1 mt-1', align === 'end' ? 'justify-end' : 'justify-start', className), ...props }));
|
|
34
|
+
}
|
|
35
|
+
function BubbleGroup({ className, ...props }) {
|
|
36
|
+
return _jsx("div", { "data-slot": "bubble-group", className: cn('flex flex-col gap-1', className), ...props });
|
|
37
|
+
}
|
|
38
|
+
export { Bubble, BubbleContent, BubbleGroup, BubbleReactions, bubbleVariants };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Separator } from './separator.js';
|
|
4
|
+
declare const buttonGroupVariants: (props?: ({
|
|
5
|
+
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare function ButtonGroup({ className, orientation, ...props }: React.ComponentProps<'div'> & VariantProps<typeof buttonGroupVariants>): React.JSX.Element;
|
|
8
|
+
declare function ButtonGroupSeparator({ className, orientation, ...props }: React.ComponentProps<typeof Separator>): React.JSX.Element;
|
|
9
|
+
export { ButtonGroup, ButtonGroupSeparator };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// This file must import the `react` module namespace rather than rely on the
|
|
3
|
+
// ambient UMD `React` global. Two `@types/react` copies are in this program
|
|
4
|
+
// (19.2.18 for apps/web, 19.1.17 pulled in by `next` and `@sentry/react`), and
|
|
5
|
+
// the UMD global binds to 19.1.17 — which still types `DOMAttributes.onChange`
|
|
6
|
+
// as `FormEventHandler<T>` instead of 19.2.18's `ChangeEventHandler<T>`. That
|
|
7
|
+
// version skew, not any real prop incompatibility, is what made the props bag
|
|
8
|
+
// below fail against `Slot.Root`. The explicit import pins every `React.*` type
|
|
9
|
+
// here to the same copy the JSX checker and `radix-ui` use.
|
|
10
|
+
import { cva } from 'class-variance-authority';
|
|
11
|
+
import { Separator } from './separator.js';
|
|
12
|
+
import { cn } from '../../lib/utils.js';
|
|
13
|
+
// Members sit 1px apart. Outer corners keep the member's own radius; the
|
|
14
|
+
// corners that face a neighbour shrink to `--radius - 6px` (4px).
|
|
15
|
+
const buttonGroupVariants = cva("flex w-fit items-stretch gap-px has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1", {
|
|
16
|
+
variants: {
|
|
17
|
+
orientation: {
|
|
18
|
+
horizontal: '[&>*:not(:first-child)]:rounded-l-[calc(var(--radius)-6px)] [&>*:not(:last-child)]:rounded-r-[calc(var(--radius)-6px)]',
|
|
19
|
+
vertical: 'flex-col [&>*:not(:first-child)]:rounded-t-[calc(var(--radius)-6px)] [&>*:not(:last-child)]:rounded-b-[calc(var(--radius)-6px)]',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
orientation: 'horizontal',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
function ButtonGroup({ className, orientation, ...props }) {
|
|
27
|
+
return (_jsx("div", { role: "group", "data-slot": "button-group", "data-orientation": orientation, className: cn(buttonGroupVariants({ orientation }), className), ...props }));
|
|
28
|
+
}
|
|
29
|
+
function ButtonGroupSeparator({ className, orientation = 'vertical', ...props }) {
|
|
30
|
+
return (_jsx(Separator, { "data-slot": "button-group-separator", orientation: orientation, className: cn('bg-input relative m-0! self-stretch data-[orientation=vertical]:h-auto', className), ...props }));
|
|
31
|
+
}
|
|
32
|
+
export { ButtonGroup, ButtonGroupSeparator };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "popover" | "link" | "text" | "default" | "brand" | "blue" | "blue-ghost" | "blue-secondary" | "danger" | "destructive" | "outline" | "outline-ghost" | "secondary" | "secondary-outline" | "sidebar" | "background" | "input" | "accent" | "ghost" | "muted" | "foreground" | "outline-foreground" | "inverse" | "invert-outline-foreground" | "transparent" | "ghost-input" | "ghost-sidebar" | "outline-sidebar" | "success" | "error" | "info" | "warning" | null | undefined;
|
|
5
|
+
size?: "toolbar" | "default" | "xs" | "base" | "sm" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-base" | "icon-md" | "icon-lg" | "magic-sm" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { cn } from '../../lib/utils.js';
|
|
5
|
+
const buttonVariants = cva("flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,background-color,border-color,box-shadow,opacity,scale,translate] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive text-center shadow-none data-[state=open]:ring-0 focus-visible:outline-none focus-visible:ring-kortix-base focus-visible:ring-[0.6px]", {
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
default: 'bg-foreground text-background hover:bg-foreground/90',
|
|
9
|
+
brand: 'bg-kortix-blue/90 dark:bg-kortix-blue/60 text-background dark:text-foreground shadow-xs hover:bg-kortix-blue/85 dark:hover:bg-kortix-blue/50 transition-colors duration-200 ease-out',
|
|
10
|
+
blue: 'bg-kortix-blue text-background dark:text-foreground shadow-xs hover:bg-kortix-blue/90',
|
|
11
|
+
'blue-ghost': 'hover:bg-sidebar-accent/40 text-kortix-blue',
|
|
12
|
+
'blue-secondary': 'bg-kortix-blue/10 text-kortix-blue hover:bg-kortix-blue/20',
|
|
13
|
+
danger: 'bg-destructive text-background hover:bg-destructive/90 focus-visible:ring-destructive/35 focus-visible:ring-offset-4 focus-visible:ring-2',
|
|
14
|
+
destructive: 'bg-destructive/80 text-background hover:bg-destructive/85 focus-visible:ring-destructive/35 focus-visible:ring-offset-1 focus-visible:ring-2',
|
|
15
|
+
outline: 'border border-border bg-transparent text-foreground hover:bg-foreground/5 hover:text-foreground',
|
|
16
|
+
'outline-ghost': 'border border-primary/10 hover:bg-background/50 hover:text-foreground',
|
|
17
|
+
secondary: 'bg-secondary hover:bg-secondary/90 text-foreground ',
|
|
18
|
+
'secondary-outline': 'bg-secondary hover:bg-secondary border border-border text-foreground',
|
|
19
|
+
sidebar: 'text-sidebar-foreground hover:bg-sidebar-accent/80 ',
|
|
20
|
+
background: 'bg-background hover:bg-background/90 text-foreground ',
|
|
21
|
+
input: 'bg-input dark:bg-input/30 text-foreground hover:bg-input/95 dark:hover:bg-input/235',
|
|
22
|
+
accent: 'bg-foreground/5 text-accent-foreground hover:bg-foreground/8 rounded-md',
|
|
23
|
+
ghost: 'bg-transparent text-foreground hover:bg-foreground/10 hover:text-foreground',
|
|
24
|
+
muted: 'bg-muted text-foreground hover:bg-muted/90',
|
|
25
|
+
link: 'text-foreground underline-offset-4 hover:underline bg-transparent',
|
|
26
|
+
foreground: 'bg-foreground text-foreground-foreground hover:bg-foreground/90',
|
|
27
|
+
'outline-foreground': 'border border-foreground/10 bg-foreground/80 hover:bg-foreground/90 text-foreground/80 hover:text-foreground',
|
|
28
|
+
inverse: 'w-fit dark:bg-[#0a0a0a] dark:hover:bg-[#0a0a0a]/95 dark:text-[#fafafa] bg-[#fafafa] hover:bg-[#fafafa]/95 text-[#0a0a0a]',
|
|
29
|
+
'invert-outline-foreground': 'border border-background/10 bg-foreground/90 hover:bg-foreground text-background hover:text-background',
|
|
30
|
+
transparent: 'bg-transparent hover:bg-transparent text-foreground',
|
|
31
|
+
text: 'text-muted-foreground hover:text-primary',
|
|
32
|
+
'ghost-input': 'bg-transparent hover:bg-input ',
|
|
33
|
+
'ghost-sidebar': 'bg-transparent hover:bg-sidebar hover:text-sidebar-accent-foreground',
|
|
34
|
+
'outline-sidebar': 'border border-border bg-transparent hover:bg-sidebar hover:text-sidebar-accent-foreground',
|
|
35
|
+
success: 'bg-kortix-green/80 text-background hover:bg-kortix-green/85',
|
|
36
|
+
error: 'bg-kortix-red/80 text-background hover:bg-kortix-red/85',
|
|
37
|
+
info: 'bg-kortix-blue/80 text-background hover:bg-kortix-blue/85',
|
|
38
|
+
warning: 'bg-kortix-orange/80 text-background hover:bg-kortix-orange/85',
|
|
39
|
+
popover: 'bg-popover text-foreground',
|
|
40
|
+
},
|
|
41
|
+
size: {
|
|
42
|
+
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
|
43
|
+
xs: 'h-7 gap-1.5 px-2.5 rounded-sm has-[>svg]:px-2',
|
|
44
|
+
base: "h-7 gap-1 px-2.5 in-data-[slot=button-group]:rounded-2xl has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
45
|
+
sm: 'h-8 gap-1.5 px-3 has-[>svg]:px-2.5',
|
|
46
|
+
lg: 'h-10 px-6 has-[>svg]:px-4',
|
|
47
|
+
xl: 'h-12 px-8 has-[>svg]:px-6',
|
|
48
|
+
icon: 'size-7 ',
|
|
49
|
+
'icon-xs': 'size-6 rounded-sm',
|
|
50
|
+
'icon-sm': 'size-7',
|
|
51
|
+
'icon-base': 'size-8 rounded-md',
|
|
52
|
+
'icon-md': 'size-9',
|
|
53
|
+
'icon-lg': 'size-10 rounded-md',
|
|
54
|
+
'magic-sm': 'h-9 px-4 py-2 has-[>svg]:px-3 sm:h-8 sm:gap-1.5 sm:px-3 sm:has-[>svg]:px-2.5',
|
|
55
|
+
toolbar: "h-7 gap-1.5 px-2.5 text-xs [&_svg:not([class*='size-'])]:size-3.5",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
defaultVariants: {
|
|
59
|
+
variant: 'default',
|
|
60
|
+
size: 'default',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
function Button({ className, variant, size, asChild = false, ...props }) {
|
|
64
|
+
const Comp = asChild ? Slot : 'button';
|
|
65
|
+
return (_jsx(Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props }));
|
|
66
|
+
}
|
|
67
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CaretLeftIcon as ChevronLeft, CaretRightIcon as ChevronRight, } from '@phosphor-icons/react';
|
|
4
|
+
import { DayPicker } from 'react-day-picker';
|
|
5
|
+
import { buttonVariants } from './button.js';
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
|
+
function Calendar({ className, classNames, showOutsideDays = true, fixedWeeks = true, ...props }) {
|
|
8
|
+
return (_jsx(DayPicker, { showOutsideDays: showOutsideDays, fixedWeeks: fixedWeeks, className: cn('p-3', className), classNames: {
|
|
9
|
+
months: 'flex flex-col sm:flex-row gap-2',
|
|
10
|
+
month: 'flex flex-col gap-4',
|
|
11
|
+
caption: 'flex justify-center pt-1 relative items-center w-full',
|
|
12
|
+
caption_label: 'text-sm font-medium',
|
|
13
|
+
nav: 'flex items-center gap-1',
|
|
14
|
+
nav_button: cn(buttonVariants({ variant: 'outline' }), 'size-7 bg-transparent p-0 opacity-50 hover:opacity-100'),
|
|
15
|
+
nav_button_previous: 'absolute left-1',
|
|
16
|
+
nav_button_next: 'absolute right-1',
|
|
17
|
+
table: 'w-full border-collapse space-x-1',
|
|
18
|
+
head_row: 'flex',
|
|
19
|
+
head_cell: 'text-muted-foreground rounded-md w-8 font-normal text-xs',
|
|
20
|
+
row: 'flex w-full mt-2',
|
|
21
|
+
cell: cn('relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-range-end)]:rounded-r-md', props.mode === 'range'
|
|
22
|
+
? '[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md'
|
|
23
|
+
: '[&:has([aria-selected])]:rounded-md'),
|
|
24
|
+
day: cn(buttonVariants({ variant: 'ghost' }), 'size-8 p-0 font-normal aria-selected:opacity-100'),
|
|
25
|
+
day_range_start: 'day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground',
|
|
26
|
+
day_range_end: 'day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground',
|
|
27
|
+
day_selected: 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
|
|
28
|
+
day_today: 'bg-accent text-accent-foreground',
|
|
29
|
+
day_outside: 'day-outside text-muted-foreground aria-selected:text-muted-foreground',
|
|
30
|
+
day_disabled: 'text-muted-foreground opacity-50',
|
|
31
|
+
day_range_middle: 'aria-selected:bg-transparent aria-selected:text-accent-foreground',
|
|
32
|
+
day_hidden: 'invisible',
|
|
33
|
+
...classNames,
|
|
34
|
+
}, components: {
|
|
35
|
+
IconLeft: ({ className, ...props }) => (_jsx(ChevronLeft, { className: cn('size-4', className), ...props })),
|
|
36
|
+
IconRight: ({ className, ...props }) => (_jsx(ChevronRight, { className: cn('size-4', className), ...props })),
|
|
37
|
+
}, ...props }));
|
|
38
|
+
}
|
|
39
|
+
export { Calendar };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Button } from './button.js';
|
|
2
|
+
import { type IconComponent } from '../../lib/icon-context.js';
|
|
3
|
+
import { type ComponentProps, type HTMLAttributes } from 'react';
|
|
4
|
+
type CardOrientation = 'card' | 'inline';
|
|
5
|
+
type CardBorder = 'none' | 'outlined';
|
|
6
|
+
interface CardGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onDrag'> {
|
|
7
|
+
/** How each card lays its own content out.
|
|
8
|
+
* "card" — stacked vertically (media/header on top). "inline" — a
|
|
9
|
+
* horizontal row (leading media, trailing footer), like a Table row.
|
|
10
|
+
* @default "card" */
|
|
11
|
+
orientation?: CardOrientation;
|
|
12
|
+
/** Number of grid columns. >1 enables 2-D proximity across rows and columns.
|
|
13
|
+
* @default 1 */
|
|
14
|
+
columns?: number;
|
|
15
|
+
/** "none" — borderless (default), separated only by subtle dividers.
|
|
16
|
+
* "outlined" — draws a border: one shared frame when grouped, or one per
|
|
17
|
+
* card when `separated`. @default "none" */
|
|
18
|
+
border?: CardBorder;
|
|
19
|
+
/** Split the group into individually-shaped cards with a gap between them
|
|
20
|
+
* (a grid of tiles) instead of one continuous divided block. @default false */
|
|
21
|
+
separated?: boolean;
|
|
22
|
+
/** Enable the magnetic proximity-hover highlight. @default true */
|
|
23
|
+
proximityHover?: boolean;
|
|
24
|
+
}
|
|
25
|
+
declare const CardGroup: import("react").ForwardRefExoticComponent<CardGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
26
|
+
interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onClick'> {
|
|
27
|
+
/** Makes the whole card an interactive target; proximity hover previews it.
|
|
28
|
+
* Renders a stretched link when `href` is set, else a stretched button. */
|
|
29
|
+
onClick?: () => void;
|
|
30
|
+
href?: string;
|
|
31
|
+
external?: boolean;
|
|
32
|
+
/** Accessible name for the stretched link/button when the whole card is
|
|
33
|
+
* clickable (the card's visible title isn't wired up automatically). */
|
|
34
|
+
label?: string;
|
|
35
|
+
/** Persistent selected state, on top of the transient proximity hover. */
|
|
36
|
+
selected?: boolean;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
/** Shows a dismiss (✕) button in the corner. */
|
|
39
|
+
dismissible?: boolean;
|
|
40
|
+
onDismiss?: () => void;
|
|
41
|
+
/** Injected by CardGroup — do not set by hand. */
|
|
42
|
+
index?: number;
|
|
43
|
+
}
|
|
44
|
+
declare const Card: import("react").ForwardRefExoticComponent<CardProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
45
|
+
declare const CardHeader: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
46
|
+
declare const CardTitle: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
47
|
+
declare const CardDescription: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & import("react").RefAttributes<HTMLParagraphElement>>;
|
|
48
|
+
declare const CardAction: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
49
|
+
declare const CardContent: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
50
|
+
declare const CardFooter: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
51
|
+
type CardLogo = string | [string, string];
|
|
52
|
+
interface CardMediaProps {
|
|
53
|
+
logo?: CardLogo;
|
|
54
|
+
logoAlt?: string;
|
|
55
|
+
icon?: IconComponent;
|
|
56
|
+
size?: number;
|
|
57
|
+
className?: string;
|
|
58
|
+
}
|
|
59
|
+
declare function CardMedia({ logo, logoAlt, icon: Icon, size, className }: CardMediaProps): import("react").JSX.Element | null;
|
|
60
|
+
interface CardImageProps {
|
|
61
|
+
src: string;
|
|
62
|
+
alt?: string;
|
|
63
|
+
className?: string;
|
|
64
|
+
}
|
|
65
|
+
declare function CardImage({ src, alt, className }: CardImageProps): import("react").JSX.Element;
|
|
66
|
+
declare namespace CardImage {
|
|
67
|
+
var displayName: string;
|
|
68
|
+
}
|
|
69
|
+
declare const CardEyebrow: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
70
|
+
interface CardFeatureProps {
|
|
71
|
+
icon?: IconComponent;
|
|
72
|
+
title: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
}
|
|
75
|
+
declare function CardFeature({ icon: Icon, title, description }: CardFeatureProps): import("react").JSX.Element;
|
|
76
|
+
/** Button's own variant and size unions, verbatim. Card defines neither of its
|
|
77
|
+
* own: everything Button ships is available here, and stays available as
|
|
78
|
+
* Button grows. Both props are left undefined by default, so Button's
|
|
79
|
+
* `defaultVariants` decide — `default` / `default`. */
|
|
80
|
+
type CardButtonVariant = ComponentProps<typeof Button>['variant'];
|
|
81
|
+
type CardButtonSize = ComponentProps<typeof Button>['size'];
|
|
82
|
+
interface CardButtonProps {
|
|
83
|
+
children: React.ReactNode;
|
|
84
|
+
onClick?: () => void;
|
|
85
|
+
href?: string;
|
|
86
|
+
variant?: CardButtonVariant;
|
|
87
|
+
size?: CardButtonSize;
|
|
88
|
+
icon?: IconComponent;
|
|
89
|
+
iconPosition?: 'start' | 'end';
|
|
90
|
+
/** Opens the href in a new tab and appends an outward arrow glyph. */
|
|
91
|
+
external?: boolean;
|
|
92
|
+
disabled?: boolean;
|
|
93
|
+
}
|
|
94
|
+
declare function CardButton({ children, onClick, href, variant, size, icon: Icon, iconPosition, external, disabled, }: CardButtonProps): import("react").JSX.Element;
|
|
95
|
+
export { Card, CardAction, CardButton, CardContent, CardDescription, CardEyebrow, CardFeature, CardFooter, CardGroup, CardHeader, CardImage, CardMedia, CardTitle, };
|
|
96
|
+
export type { CardButtonProps, CardButtonSize, CardButtonVariant, CardGroupProps, CardLogo, CardProps, };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from './button.js';
|
|
4
|
+
import { useProximityHover } from '../../hooks/use-proximity-hover.js';
|
|
5
|
+
import { fontWeights } from '../../lib/font-weight.js';
|
|
6
|
+
import { useIcon } from '../../lib/icon-context.js';
|
|
7
|
+
import { useUiLink } from '../../providers/ui-provider.js';
|
|
8
|
+
import { spring } from '../../lib/springs.js';
|
|
9
|
+
import { cn } from '../../lib/utils.js';
|
|
10
|
+
import { AnimatePresence, m } from 'motion/react';
|
|
11
|
+
import { Children, cloneElement, createContext, forwardRef, isValidElement, useContext, useEffect, useMemo, useRef, } from 'react';
|
|
12
|
+
const CardGroupContext = createContext(null);
|
|
13
|
+
const CardContext = createContext({
|
|
14
|
+
emphasized: false,
|
|
15
|
+
orientation: 'card',
|
|
16
|
+
clickable: false,
|
|
17
|
+
hasImage: false,
|
|
18
|
+
});
|
|
19
|
+
const CardGroup = forwardRef(({ orientation = 'card', columns = 1, border = 'none', separated = false, proximityHover = true, className, children, ...props }, ref) => {
|
|
20
|
+
const containerRef = useRef(null);
|
|
21
|
+
// >1 column wraps into a grid, where nearest-item must be resolved in two
|
|
22
|
+
// dimensions; a single column is a plain vertical list.
|
|
23
|
+
const axis = columns > 1 ? 'xy' : 'y';
|
|
24
|
+
const { activeIndex, itemRects, sessionRef, handlers, registerItem, measureItems } = useProximityHover(containerRef, { axis });
|
|
25
|
+
// Assign each valid child a stable proximity index so callers never thread
|
|
26
|
+
// one through by hand (Table asks for it; here the group owns it).
|
|
27
|
+
const childArray = Children.toArray(children).filter(isValidElement);
|
|
28
|
+
const count = childArray.length;
|
|
29
|
+
const indexed = childArray.map((child, i) => cloneElement(child, { index: i }));
|
|
30
|
+
// Which card is selected — so its neighbours can drop the divider that
|
|
31
|
+
// would otherwise slice through the selection fill.
|
|
32
|
+
const selectedIndex = childArray.findIndex((child) => child.props.selected);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
measureItems();
|
|
35
|
+
}, [measureItems, count, columns, orientation, separated, border]);
|
|
36
|
+
const outlined = border === 'outlined';
|
|
37
|
+
const divided = !separated;
|
|
38
|
+
const contextValue = useMemo(() => ({
|
|
39
|
+
registerItem,
|
|
40
|
+
activeIndex,
|
|
41
|
+
selectedIndex,
|
|
42
|
+
orientation,
|
|
43
|
+
columns,
|
|
44
|
+
count,
|
|
45
|
+
separated,
|
|
46
|
+
divided,
|
|
47
|
+
outlined,
|
|
48
|
+
}), [
|
|
49
|
+
registerItem,
|
|
50
|
+
activeIndex,
|
|
51
|
+
selectedIndex,
|
|
52
|
+
orientation,
|
|
53
|
+
columns,
|
|
54
|
+
count,
|
|
55
|
+
separated,
|
|
56
|
+
divided,
|
|
57
|
+
outlined,
|
|
58
|
+
]);
|
|
59
|
+
const activeRect = proximityHover && activeIndex !== null ? itemRects[activeIndex] : null;
|
|
60
|
+
return (_jsx(CardGroupContext.Provider, { value: contextValue, children: _jsxs("div", { ref: (node) => {
|
|
61
|
+
containerRef.current = node;
|
|
62
|
+
if (typeof ref === 'function')
|
|
63
|
+
ref(node);
|
|
64
|
+
else if (ref)
|
|
65
|
+
ref.current = node;
|
|
66
|
+
}, ...props, "data-slot": "card-group", "data-orientation": orientation, className: cn('relative grid',
|
|
67
|
+
// A shared frame clips the highlight + dividers to its rounded
|
|
68
|
+
// corners; separated tiles clip themselves.
|
|
69
|
+
outlined && !separated && 'border-border/60 overflow-hidden rounded-xl border', separated ? 'gap-2' : 'gap-0', className), style: {
|
|
70
|
+
gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))`,
|
|
71
|
+
}, onMouseEnter: proximityHover ? handlers.onMouseEnter : undefined, onMouseMove: proximityHover ? handlers.onMouseMove : undefined, onMouseLeave: proximityHover ? handlers.onMouseLeave : undefined, children: [_jsx(AnimatePresence, { children: activeRect && (_jsx(m.div, { "aria-hidden": true, layout: true, className: "bg-hover pointer-events-none absolute z-0 rounded-xl", style: {
|
|
72
|
+
top: activeRect.top,
|
|
73
|
+
left: activeRect.left,
|
|
74
|
+
width: activeRect.width,
|
|
75
|
+
height: activeRect.height,
|
|
76
|
+
}, initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0, transition: spring.fast.exit }, transition: { ...spring.fast, opacity: { duration: 0.08 } } }, sessionRef.current)) }), indexed] }) }));
|
|
77
|
+
});
|
|
78
|
+
CardGroup.displayName = 'CardGroup';
|
|
79
|
+
const Card = forwardRef(({ onClick, href, external, label, selected = false, disabled = false, dismissible = false, onDismiss, index, className, children, ...props }, ref) => {
|
|
80
|
+
const internalRef = useRef(null);
|
|
81
|
+
const group = useContext(CardGroupContext);
|
|
82
|
+
const XIcon = useIcon('x');
|
|
83
|
+
const Link = useUiLink();
|
|
84
|
+
const orientation = group?.orientation ?? 'card';
|
|
85
|
+
const columns = group?.columns ?? 1;
|
|
86
|
+
const count = group?.count ?? 1;
|
|
87
|
+
const separated = group?.separated ?? true;
|
|
88
|
+
const divided = group?.divided ?? false;
|
|
89
|
+
const outlined = group?.outlined ?? false;
|
|
90
|
+
const activeIndex = group?.activeIndex ?? null;
|
|
91
|
+
const selectedIndex = group?.selectedIndex ?? -1;
|
|
92
|
+
// Depend on the stable registerItem callback, not the whole group context —
|
|
93
|
+
// the context object's identity changes on every proximity/selection frame,
|
|
94
|
+
// which would otherwise re-register every card each frame.
|
|
95
|
+
const registerItem = group?.registerItem;
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (index === undefined || !registerItem)
|
|
98
|
+
return;
|
|
99
|
+
registerItem(index, internalRef.current);
|
|
100
|
+
return () => registerItem(index, null);
|
|
101
|
+
}, [index, registerItem]);
|
|
102
|
+
// Divider geometry: draw a hairline toward the neighbour below / to the
|
|
103
|
+
// right, but drop it next to the active OR selected card so the highlight
|
|
104
|
+
// and selection fill read clean (the same trick Table uses on row borders).
|
|
105
|
+
const col = index !== undefined ? index % columns : 0;
|
|
106
|
+
const hasBelow = index !== undefined && index + columns < count;
|
|
107
|
+
const hasRight = index !== undefined && col < columns - 1 && index + 1 < count;
|
|
108
|
+
const self = index ?? -1;
|
|
109
|
+
const touchesBelow = (i) => i === self || i === self + columns;
|
|
110
|
+
const touchesRight = (i) => i === self || i === self + 1;
|
|
111
|
+
const showBottom = divided && hasBelow && !(touchesBelow(activeIndex ?? -1) || touchesBelow(selectedIndex));
|
|
112
|
+
const showRight = divided && hasRight && !(touchesRight(activeIndex ?? -1) || touchesRight(selectedIndex));
|
|
113
|
+
const isInline = orientation === 'inline';
|
|
114
|
+
// An inline card with a full-bleed image reflows so its actions stack under
|
|
115
|
+
// the text (see the body wrapper below + CardHeader/CardFooter). Match the
|
|
116
|
+
// image child by identity OR displayName so detection and the split below
|
|
117
|
+
// agree even when module identity drifts (e.g. HMR duplication).
|
|
118
|
+
const isCardImage = (child) => isValidElement(child) &&
|
|
119
|
+
(child.type === CardImage ||
|
|
120
|
+
child.type?.displayName === 'CardImage');
|
|
121
|
+
const hasImage = Children.toArray(children).some(isCardImage);
|
|
122
|
+
const inlineImage = isInline && hasImage;
|
|
123
|
+
const clickable = !!href || !!onClick;
|
|
124
|
+
// Title weight follows the persistent selected state only — proximity hover
|
|
125
|
+
// previews via the highlight fill, not by bolding the label.
|
|
126
|
+
const emphasized = selected;
|
|
127
|
+
// A standalone card (no group) is its own tile — always rounded + clipped.
|
|
128
|
+
// Inside a group, a separated tile carries its own rounding + clip only when
|
|
129
|
+
// it draws a visible frame; a borderless separated tile has no surface to
|
|
130
|
+
// hug, so it stays unclipped and its media reads as a plain square, and a
|
|
131
|
+
// card in a continuous block leans on the shared group frame for both.
|
|
132
|
+
const tileShape = !group
|
|
133
|
+
? 'rounded-xl overflow-hidden'
|
|
134
|
+
: separated && outlined
|
|
135
|
+
? 'rounded-xl overflow-hidden border border-border/60'
|
|
136
|
+
: '';
|
|
137
|
+
// Stretched overlay makes the whole card the click target while keeping
|
|
138
|
+
// action buttons (higher z) independently clickable — the accessible
|
|
139
|
+
// alternative to nesting interactive elements inside a button/anchor. A
|
|
140
|
+
// disabled card drops the overlay entirely so it can't be tabbed to or
|
|
141
|
+
// activated by keyboard (pointer-events-none only blocks the mouse).
|
|
142
|
+
const overlay = clickable && !disabled ? (href ? (_jsx(Link, { href: href, onClick: onClick, target: external ? '_blank' : undefined, rel: external ? 'noopener noreferrer' : undefined, "aria-label": label, className: "absolute inset-0 z-20 rounded-[inherit] outline-none focus-visible:ring-1 focus-visible:ring-[color:var(--focus-ring,#6B97FF)]" })) : (_jsx("button", { type: "button", onClick: onClick, "aria-label": label, "aria-pressed": selected || undefined, className: "absolute inset-0 z-20 rounded-[inherit] outline-none focus-visible:ring-1 focus-visible:ring-[color:var(--focus-ring,#6B97FF)]" }))) : null;
|
|
143
|
+
const cardContext = useMemo(() => ({ emphasized, orientation, clickable, hasImage }), [emphasized, orientation, clickable, hasImage]);
|
|
144
|
+
// Inline image cards wrap their non-image parts in a centred column so the
|
|
145
|
+
// title, description, and actions hug together and sit vertically centred
|
|
146
|
+
// against the image instead of stretching to its full height.
|
|
147
|
+
let body = children;
|
|
148
|
+
if (inlineImage) {
|
|
149
|
+
const parts = Children.toArray(children);
|
|
150
|
+
const image = parts.find(isCardImage);
|
|
151
|
+
const rest = parts.filter((part) => part !== image);
|
|
152
|
+
body = (_jsxs(_Fragment, { children: [image, _jsx("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-2 py-3.5 pr-4", children: rest })] }));
|
|
153
|
+
}
|
|
154
|
+
return (_jsx(CardContext.Provider, { value: cardContext, children: _jsxs("div", { ref: (node) => {
|
|
155
|
+
internalRef.current = node;
|
|
156
|
+
if (typeof ref === 'function')
|
|
157
|
+
ref(node);
|
|
158
|
+
else if (ref)
|
|
159
|
+
ref.current = node;
|
|
160
|
+
}, "data-slot": "card", "data-proximity-index": index, "data-selected": selected || undefined, "data-orientation": orientation, "aria-disabled": disabled || undefined, className: cn('group/card relative z-10 min-h-[60px] min-w-0', inlineImage
|
|
161
|
+
? // Image on the left; the text + actions ride in a centred
|
|
162
|
+
// column beside it (see the wrapper in the body below).
|
|
163
|
+
'flex flex-row items-center gap-3'
|
|
164
|
+
: isInline
|
|
165
|
+
? 'flex flex-row items-center gap-3 pl-4'
|
|
166
|
+
: 'flex flex-col pb-4',
|
|
167
|
+
// Standalone (no group) cards can't lean on the group highlight, so
|
|
168
|
+
// they carry their own hover tint when interactive.
|
|
169
|
+
!group && clickable && !disabled && 'hover:bg-hover transition-colors duration-80', tileShape, disabled && 'pointer-events-none opacity-50', className), ...props, children: [selected && (_jsx("span", { "aria-hidden": true, className: "bg-active pointer-events-none absolute inset-0 -z-10 rounded-xl" })), showBottom && (_jsx("span", { "aria-hidden": true, className: "bg-border/60 pointer-events-none absolute inset-x-0 bottom-0 -z-10 h-px" })), showRight && (_jsx("span", { "aria-hidden": true, className: cn('bg-border/60 pointer-events-none absolute top-0 right-0 -z-10 w-px', showBottom ? 'bottom-px' : 'bottom-0') })), overlay, body, dismissible && (_jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: onDismiss, "aria-label": "Dismiss", className: "text-muted-foreground hover:text-foreground absolute top-2 right-2 z-30", children: _jsx(XIcon, { size: 15, strokeWidth: 1.5, className: "size-[15px]" }) }))] }) }));
|
|
170
|
+
});
|
|
171
|
+
Card.displayName = 'Card';
|
|
172
|
+
// ── CardHeader ───────────────────────────────────────────
|
|
173
|
+
// shadcn's header grid: title + description stack, with CardAction pinned to
|
|
174
|
+
// the top-right column. In an inline card it becomes the flexible text column
|
|
175
|
+
// between the leading media and trailing footer.
|
|
176
|
+
const CardHeader = forwardRef(({ className, ...props }, ref) => {
|
|
177
|
+
const { orientation, hasImage } = useContext(CardContext);
|
|
178
|
+
const inlineImage = orientation === 'inline' && hasImage;
|
|
179
|
+
return (_jsx("div", { ref: ref, "data-slot": "card-header", className: cn('grid auto-rows-min items-start gap-1 has-data-[slot=card-action]:grid-cols-[1fr_auto]',
|
|
180
|
+
// With an action present the header is two columns, but only the
|
|
181
|
+
// action belongs in the second one. Auto-placement would otherwise
|
|
182
|
+
// flow a third sibling (media, eyebrow…) into the free right-hand
|
|
183
|
+
// cell and park the description beside the title.
|
|
184
|
+
'[&>*:not([data-slot=card-action])]:col-start-1', inlineImage
|
|
185
|
+
? 'min-w-0'
|
|
186
|
+
: orientation === 'inline'
|
|
187
|
+
? 'min-w-0 flex-1 py-3.5'
|
|
188
|
+
: 'px-4 pt-4', className), ...props }));
|
|
189
|
+
});
|
|
190
|
+
CardHeader.displayName = 'CardHeader';
|
|
191
|
+
// ── CardTitle ────────────────────────────────────────────
|
|
192
|
+
const CardTitle = forwardRef(({ className, children, ...props }, ref) => {
|
|
193
|
+
const { emphasized, orientation } = useContext(CardContext);
|
|
194
|
+
// Inline rows trim the title to cap height so it centres tightly against
|
|
195
|
+
// the media/actions; stacked cards keep the natural line box.
|
|
196
|
+
const trim = orientation === 'inline' ? '[text-box:trim-both_cap_alphabetic]' : '';
|
|
197
|
+
// Ghost-span pattern: an invisible semibold copy reserves the width so the
|
|
198
|
+
// resting→active weight animation never reflows the row.
|
|
199
|
+
return (_jsxs("span", { ref: ref, "data-slot": "card-title", className: cn('inline-grid text-[14px] leading-snug', className), ...props, children: [_jsx("span", { className: cn('invisible col-start-1 row-start-1', trim), style: { fontVariationSettings: fontWeights.semibold }, "aria-hidden": "true", children: children }), _jsx("span", { className: cn('text-foreground col-start-1 row-start-1 transition-[font-variation-settings] duration-80', trim), style: {
|
|
200
|
+
// normal → semibold on emphasis, matching nav-item / menu-item /
|
|
201
|
+
// table (the opsz-paired tokens keep the advance width ~constant).
|
|
202
|
+
fontVariationSettings: emphasized ? fontWeights.semibold : fontWeights.normal,
|
|
203
|
+
}, children: children })] }));
|
|
204
|
+
});
|
|
205
|
+
CardTitle.displayName = 'CardTitle';
|
|
206
|
+
// ── CardDescription ──────────────────────────────────────
|
|
207
|
+
const CardDescription = forwardRef(({ className, ...props }, ref) => (_jsx("p", { ref: ref, "data-slot": "card-description", className: cn('text-muted-foreground text-[14px] leading-normal', className), ...props })));
|
|
208
|
+
CardDescription.displayName = 'CardDescription';
|
|
209
|
+
// ── CardAction ───────────────────────────────────────────
|
|
210
|
+
// Pinned to the header's top-right column (shadcn's slot). Sits above the
|
|
211
|
+
// stretched overlay so any control inside stays independently clickable.
|
|
212
|
+
const CardAction = forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, "data-slot": "card-action", className: cn('relative z-30 col-start-2 row-span-2 row-start-1 self-start justify-self-end', className), ...props })));
|
|
213
|
+
CardAction.displayName = 'CardAction';
|
|
214
|
+
// ── CardContent ──────────────────────────────────────────
|
|
215
|
+
const CardContent = forwardRef(({ className, ...props }, ref) => {
|
|
216
|
+
const { orientation } = useContext(CardContext);
|
|
217
|
+
return (_jsx("div", { ref: ref, "data-slot": "card-content", className: cn(orientation === 'inline' ? '' : 'px-4 pt-3', className), ...props }));
|
|
218
|
+
});
|
|
219
|
+
CardContent.displayName = 'CardContent';
|
|
220
|
+
// ── CardFooter ───────────────────────────────────────────
|
|
221
|
+
// Actions row. Rises above the stretched overlay (z-30) so buttons stay
|
|
222
|
+
// clickable. In an inline card it becomes the trailing, right-aligned slot.
|
|
223
|
+
const CardFooter = forwardRef(({ className, ...props }, ref) => {
|
|
224
|
+
const { orientation, hasImage } = useContext(CardContext);
|
|
225
|
+
const inlineImage = orientation === 'inline' && hasImage;
|
|
226
|
+
return (_jsx("div", { ref: ref, "data-slot": "card-footer", className: cn('relative z-30 flex items-center gap-1', inlineImage
|
|
227
|
+
? // Under the text, left-aligned in natural order (the inline
|
|
228
|
+
// wrapper owns the spacing).
|
|
229
|
+
'flex-wrap'
|
|
230
|
+
: orientation === 'inline'
|
|
231
|
+
? 'ml-auto shrink-0 pr-4'
|
|
232
|
+
: 'flex-wrap px-4 pt-3', className), ...props }));
|
|
233
|
+
});
|
|
234
|
+
CardFooter.displayName = 'CardFooter';
|
|
235
|
+
function CardMedia({ logo, logoAlt, icon: Icon, size = 22, className }) {
|
|
236
|
+
const { orientation } = useContext(CardContext);
|
|
237
|
+
// Stacked: sits in the header grid; add an extra 8px so the gap below the
|
|
238
|
+
// icon reads 12px (header gap-1 + mb-2). Inline: leading slot — the card owns
|
|
239
|
+
// the left inset, so no extra padding here.
|
|
240
|
+
const wrap = cn(orientation === 'inline' ? '' : 'mb-2', className);
|
|
241
|
+
if (logo) {
|
|
242
|
+
const logos = Array.isArray(logo) ? logo : [logo];
|
|
243
|
+
return (_jsx("span", { "data-slot": "card-media", className: cn('inline-flex shrink-0 items-center gap-1.5', wrap), children: logos.map((src, i) => (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [i > 0 && _jsx("span", { "aria-hidden": true, className: "bg-border h-px w-2" }), _jsx("img", { src: src, alt: logoAlt ?? '', width: size, height: size, className: "rounded-lg object-contain", style: { width: size, height: size } })] }, src))) }));
|
|
244
|
+
}
|
|
245
|
+
if (Icon) {
|
|
246
|
+
// The icon sits in a 32×32 tinted tile so it reads as a media slot rather
|
|
247
|
+
// than a bare glyph. The tile is an overlay tint (not a solid surface) so it
|
|
248
|
+
// blends over whatever is behind it — the substrate or the hover highlight.
|
|
249
|
+
return (_jsx("span", { "data-slot": "card-media", className: cn('bg-hover inline-flex size-8 shrink-0 items-center justify-center rounded-lg', wrap), children: _jsx(Icon, { size: 18, strokeWidth: 1.5, className: "text-muted-foreground" }) }));
|
|
250
|
+
}
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
function CardImage({ src, alt, className }) {
|
|
254
|
+
const { orientation } = useContext(CardContext);
|
|
255
|
+
return (
|
|
256
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
257
|
+
_jsx("img", { src: src, alt: alt ?? '', "data-slot": "card-image",
|
|
258
|
+
// The image keeps a fixed 2px corner radius in every state — stacked or
|
|
259
|
+
// inline, framed or borderless — rather than inheriting a frame's larger
|
|
260
|
+
// clip. (A framed tile still clips the surrounding surface as before.)
|
|
261
|
+
className: cn('rounded-[2px] object-cover', orientation === 'inline' ? 'size-40 shrink-0' : 'aspect-[16/9] w-full', className) }));
|
|
262
|
+
}
|
|
263
|
+
// A stable marker so the Card can recognise an image child by name, surviving
|
|
264
|
+
// module-identity mismatches (e.g. HMR duplication) that break `type ===`.
|
|
265
|
+
CardImage.displayName = 'CardImage';
|
|
266
|
+
// ── CardEyebrow ──────────────────────────────────────────
|
|
267
|
+
// Small uppercase label above the title (e.g. "New Model").
|
|
268
|
+
const CardEyebrow = forwardRef(({ className, ...props }, ref) => (_jsx("span", { ref: ref, "data-slot": "card-eyebrow", className: cn('text-muted-foreground text-[11px] tracking-wide uppercase', className), style: { fontVariationSettings: fontWeights.semibold }, ...props })));
|
|
269
|
+
CardEyebrow.displayName = 'CardEyebrow';
|
|
270
|
+
function CardFeature({ icon: Icon, title, description }) {
|
|
271
|
+
return (_jsxs("div", { "data-slot": "card-feature", className: "flex items-start gap-2.5", children: [Icon && (_jsx(Icon, { size: 16, strokeWidth: 1.5, className: "text-muted-foreground mt-0.5 shrink-0" })), _jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "text-foreground text-[13px] [text-box:trim-both_cap_alphabetic]", style: { fontVariationSettings: fontWeights.medium }, children: title }), description && (_jsx("span", { className: "text-muted-foreground text-[12px] leading-relaxed", children: description }))] })] }));
|
|
272
|
+
}
|
|
273
|
+
function CardButton({ children, onClick, href, variant, size = 'sm', icon: Icon, iconPosition, external = false, disabled = false, }) {
|
|
274
|
+
const ArrowRight = useIcon('arrow-right');
|
|
275
|
+
const Link = useUiLink();
|
|
276
|
+
const position = iconPosition ?? (external ? 'end' : 'start');
|
|
277
|
+
// No size class on either glyph: Button's own svg rules own the scale, so an
|
|
278
|
+
// icon tracks whichever `size` the caller picked instead of being pinned.
|
|
279
|
+
const glyph = Icon ? (_jsx(Icon, { strokeWidth: 1.5, className: "shrink-0 transition-[stroke-width] duration-80 group-hover/action:stroke-[2]" })) : null;
|
|
280
|
+
const externalGlyph = external ? (_jsx(ArrowRight, { strokeWidth: 1.5, className: "shrink-0 -rotate-45 transition-[stroke-width] duration-80 group-hover/action:stroke-[2]" })) : null;
|
|
281
|
+
const inner = (_jsxs(_Fragment, { children: [position === 'start' && glyph, _jsx("span", { className: "[text-box:trim-both_cap_alphabetic]", children: children }), position === 'end' && glyph, externalGlyph] }));
|
|
282
|
+
// Button owns the whole box — height, padding, radius, type scale. The card
|
|
283
|
+
// adds only what the surface needs: a hover group for the glyph, a lift above
|
|
284
|
+
// the stretched overlay, and `link`'s bare-text box.
|
|
285
|
+
const classes = cn('group/action relative z-30', variant === 'link' && 'h-auto px-0');
|
|
286
|
+
if (href) {
|
|
287
|
+
return (_jsx(Button, { asChild: true, variant: variant, size: size, className: classes, children: _jsx(Link, { href: href, onClick: onClick, target: external ? '_blank' : undefined, rel: external ? 'noopener noreferrer' : undefined, children: inner }) }));
|
|
288
|
+
}
|
|
289
|
+
return (_jsx(Button, { type: "button", variant: variant, size: size, onClick: onClick, disabled: disabled, className: classes, children: inner }));
|
|
290
|
+
}
|
|
291
|
+
export { Card, CardAction, CardButton, CardContent, CardDescription, CardEyebrow, CardFeature, CardFooter, CardGroup, CardHeader, CardImage, CardMedia, CardTitle, };
|