@devalok/shilp-sutra 0.34.1 → 0.36.1
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/LICENSE +21 -21
- package/dist/_chunks/badge-group.js +95 -95
- package/dist/_chunks/badge-group.js.map +1 -0
- package/dist/_chunks/chat.js +7 -2
- package/dist/_chunks/chat.js.map +1 -0
- package/dist/_chunks/date-picker.js.map +1 -0
- package/dist/_chunks/document-preview.js.map +1 -0
- package/dist/_chunks/file-preview.js.map +1 -0
- package/dist/_chunks/framer.js +62 -62
- package/dist/_chunks/framer.js.map +1 -0
- package/dist/_chunks/image-preview.js +1 -1
- package/dist/_chunks/image-preview.js.map +1 -0
- package/dist/_chunks/keybinding.js.map +1 -0
- package/dist/_chunks/link-context.js.map +1 -0
- package/dist/_chunks/mention-suggestion.js.map +1 -0
- package/dist/_chunks/motion-provider.js.map +1 -0
- package/dist/_chunks/popover.js +32 -36
- package/dist/_chunks/popover.js.map +1 -0
- package/dist/_chunks/primitives.js +686 -686
- package/dist/_chunks/primitives.js.map +1 -0
- package/dist/_chunks/rich-chat-input.js +651 -650
- package/dist/_chunks/rich-chat-input.js.map +1 -0
- package/dist/_chunks/shared.js.map +1 -0
- package/dist/_chunks/sonner.js.map +1 -0
- package/dist/_chunks/stat-row.js +158 -158
- package/dist/_chunks/stat-row.js.map +1 -0
- package/dist/_chunks/tiptap.js +11 -11
- package/dist/_chunks/tiptap.js.map +1 -0
- package/dist/_chunks/tree-view.js +1 -1
- package/dist/_chunks/tree-view.js.map +1 -0
- package/dist/_chunks/use-calendar.js.map +1 -0
- package/dist/_chunks/vendor-client.js +1 -1
- package/dist/_chunks/vendor-client.js.map +1 -0
- package/dist/_chunks/vendor-utils.js.map +1 -0
- package/dist/ai/ai-command-provider.js.map +1 -0
- package/dist/ai/block-renderer.js.map +1 -0
- package/dist/ai/blocks/loading.d.ts.map +1 -1
- package/dist/ai/command-bar.js.map +1 -0
- package/dist/ai/conversation.js +76 -76
- package/dist/ai/conversation.js.map +1 -0
- package/dist/ai/devadoot-icon.d.ts.map +1 -1
- package/dist/ai/index.js.map +1 -0
- package/dist/composed/activity-feed.js.map +1 -0
- package/dist/composed/avatar-group.js +1 -1
- package/dist/composed/avatar-group.js.map +1 -0
- package/dist/composed/bulk-action-bar.js +13 -21
- package/dist/composed/bulk-action-bar.js.map +1 -0
- package/dist/composed/command-palette.js.map +1 -0
- package/dist/composed/confirm-dialog.js.map +1 -0
- package/dist/composed/content-card.js.map +1 -0
- package/dist/composed/deadline-indicator.js.map +1 -0
- package/dist/composed/emoji-picker.js.map +1 -0
- package/dist/composed/empty-state.d.ts.map +1 -1
- package/dist/composed/empty-state.js +30 -30
- package/dist/composed/empty-state.js.map +1 -0
- package/dist/composed/error-boundary.js.map +1 -0
- package/dist/composed/filter-bar.js.map +1 -0
- package/dist/composed/form-section.js.map +1 -0
- package/dist/composed/global-loading.js.map +1 -0
- package/dist/composed/inline-edit.js.map +1 -0
- package/dist/composed/lib/string-utils.js.map +1 -0
- package/dist/composed/loading-skeleton.js.map +1 -0
- package/dist/composed/markdown-viewer.js.map +1 -0
- package/dist/composed/master-detail.js.map +1 -0
- package/dist/composed/member-picker.js.map +1 -0
- package/dist/composed/multi-select-popover.d.ts.map +1 -1
- package/dist/composed/multi-select-popover.js +4 -0
- package/dist/composed/multi-select-popover.js.map +1 -0
- package/dist/composed/page-header.js.map +1 -0
- package/dist/composed/page-skeletons.js.map +1 -0
- package/dist/composed/priority-indicator.js.map +1 -0
- package/dist/composed/responsive-overlay.js.map +1 -0
- package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
- package/dist/composed/rich-chat-input.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +1 -1
- package/dist/composed/rich-text-editor.js.map +1 -0
- package/dist/composed/schedule-view.js.map +1 -0
- package/dist/composed/simple-tooltip.js.map +1 -0
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js.map +1 -0
- package/dist/hooks/use-color-mode.js.map +1 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/hooks/use-touch-device.js.map +1 -0
- package/dist/hooks/use-viewport-height.js.map +1 -0
- package/dist/motion/check-motion-provider.d.ts +3 -0
- package/dist/motion/check-motion-provider.d.ts.map +1 -0
- package/dist/motion/index.js +14 -0
- package/dist/motion/index.js.map +1 -0
- package/dist/motion/primitives-index.js.map +1 -0
- package/dist/primitives/react-accordion.d.ts +114 -114
- package/dist/primitives/react-alert-dialog.d.ts +51 -51
- package/dist/primitives/react-aspect-ratio.d.ts +11 -11
- package/dist/primitives/react-avatar.d.ts +24 -24
- package/dist/primitives/react-checkbox.d.ts +50 -50
- package/dist/primitives/react-collapsible.d.ts +33 -33
- package/dist/primitives/react-context-menu.d.ts +96 -96
- package/dist/primitives/react-dialog.d.ts +103 -103
- package/dist/primitives/react-dropdown-menu.d.ts +97 -97
- package/dist/primitives/react-hover-card.d.ts +79 -79
- package/dist/primitives/react-label.d.ts +10 -10
- package/dist/primitives/react-menu.d.ts +169 -169
- package/dist/primitives/react-menubar.d.ts +115 -115
- package/dist/primitives/react-navigation-menu.d.ts +126 -126
- package/dist/primitives/react-popover.d.ts +85 -85
- package/dist/primitives/react-progress.d.ts +19 -19
- package/dist/primitives/react-radio-group.d.ts +58 -58
- package/dist/primitives/react-roving-focus.d.ts +49 -49
- package/dist/primitives/react-select.d.ts +137 -137
- package/dist/primitives/react-separator.d.ts +21 -21
- package/dist/primitives/react-slider.d.ts +75 -75
- package/dist/primitives/react-switch.d.ts +21 -21
- package/dist/primitives/react-tabs.d.ts +56 -56
- package/dist/primitives/react-toast.d.ts +120 -120
- package/dist/primitives/react-toggle-group.d.ts +75 -75
- package/dist/primitives/react-toggle.d.ts +24 -24
- package/dist/primitives/react-tooltip.d.ts +101 -101
- package/dist/primitives/react-visually-hidden.d.ts +22 -22
- package/dist/shell/app-command-palette.d.ts +2 -0
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js +42 -155
- package/dist/shell/app-command-palette.js.map +1 -0
- package/dist/shell/bottom-navbar.js +1 -1
- package/dist/shell/bottom-navbar.js.map +1 -0
- package/dist/shell/command-registry.js.map +1 -0
- package/dist/shell/notification-center.d.ts.map +1 -1
- package/dist/shell/notification-center.js +194 -169
- package/dist/shell/notification-center.js.map +1 -0
- package/dist/shell/notification-preferences.js.map +1 -0
- package/dist/shell/sidebar.js.map +1 -0
- package/dist/shell/top-bar.js +1 -1
- package/dist/shell/top-bar.js.map +1 -0
- package/dist/tailwind/index.cjs +48 -1
- package/dist/tailwind/preset.d.ts.map +1 -1
- package/dist/tailwind/preset.js +48 -1
- package/dist/tailwind/preset.js.map +1 -0
- package/dist/tokens/index.css +4 -4
- package/dist/tokens/primitives.css +442 -442
- package/dist/tokens/semantic.css +742 -547
- package/dist/tokens/typography-semantic.css +123 -100
- package/dist/tokens/typography.css +422 -422
- package/dist/ui/accordion.js +13 -13
- package/dist/ui/accordion.js.map +1 -0
- package/dist/ui/alert-dialog.d.ts +6 -2
- package/dist/ui/alert-dialog.d.ts.map +1 -1
- package/dist/ui/alert-dialog.js +43 -42
- package/dist/ui/alert-dialog.js.map +1 -0
- package/dist/ui/alert.d.ts +3 -2
- package/dist/ui/alert.d.ts.map +1 -1
- package/dist/ui/alert.js +31 -5
- package/dist/ui/alert.js.map +1 -0
- package/dist/ui/aspect-ratio.js +1 -1
- package/dist/ui/aspect-ratio.js.map +1 -0
- package/dist/ui/autocomplete.d.ts.map +1 -1
- package/dist/ui/autocomplete.js +92 -67
- package/dist/ui/autocomplete.js.map +1 -0
- package/dist/ui/avatar.js +9 -9
- package/dist/ui/avatar.js.map +1 -0
- package/dist/ui/badge-indicator.js.map +1 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/breadcrumb.js +1 -1
- package/dist/ui/breadcrumb.js.map +1 -0
- package/dist/ui/button-group.js.map +1 -0
- package/dist/ui/button-processing.d.ts.map +1 -1
- package/dist/ui/button-processing.js +61 -40
- package/dist/ui/button-processing.js.map +1 -0
- package/dist/ui/button.js +8 -8
- package/dist/ui/button.js.map +1 -0
- package/dist/ui/card.js.map +1 -0
- package/dist/ui/charts/bar-chart.d.ts.map +1 -1
- package/dist/ui/charts/chart-container.d.ts +2 -0
- package/dist/ui/charts/chart-container.d.ts.map +1 -1
- package/dist/ui/charts/index.js +88 -65
- package/dist/ui/charts/index.js.map +1 -0
- package/dist/ui/charts/line-chart.d.ts.map +1 -1
- package/dist/ui/chat/message-input.d.ts.map +1 -1
- package/dist/ui/chat/message-list.d.ts +1 -1
- package/dist/ui/chat/message-list.d.ts.map +1 -1
- package/dist/ui/chat/message.d.ts.map +1 -1
- package/dist/ui/chat/system-message.d.ts.map +1 -1
- package/dist/ui/checkbox.d.ts.map +1 -1
- package/dist/ui/checkbox.js +33 -28
- package/dist/ui/checkbox.js.map +1 -0
- package/dist/ui/code.js.map +1 -0
- package/dist/ui/collapsible.js +1 -1
- package/dist/ui/collapsible.js.map +1 -0
- package/dist/ui/color-input.d.ts.map +1 -1
- package/dist/ui/color-input.js +165 -163
- package/dist/ui/color-input.js.map +1 -0
- package/dist/ui/color-swatch.js.map +1 -0
- package/dist/ui/combobox.d.ts +7 -0
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +147 -113
- package/dist/ui/combobox.js.map +1 -0
- package/dist/ui/container.js +1 -1
- package/dist/ui/container.js.map +1 -0
- package/dist/ui/context-menu.js.map +1 -0
- package/dist/ui/data-table-body.js.map +1 -0
- package/dist/ui/data-table-bulk-actions.js +1 -1
- package/dist/ui/data-table-bulk-actions.js.map +1 -0
- package/dist/ui/data-table-card.js.map +1 -0
- package/dist/ui/data-table-context.js.map +1 -0
- package/dist/ui/data-table-header.js.map +1 -0
- package/dist/ui/data-table-pagination.js.map +1 -0
- package/dist/ui/data-table-toolbar.js.map +1 -0
- package/dist/ui/data-table.js +34 -31
- package/dist/ui/data-table.js.map +1 -0
- package/dist/ui/devalok-grain.js.map +1 -0
- package/dist/ui/dialog.js +31 -35
- package/dist/ui/dialog.js.map +1 -0
- package/dist/ui/dropdown-menu.js.map +1 -0
- package/dist/ui/file-upload.js +120 -120
- package/dist/ui/file-upload.js.map +1 -0
- package/dist/ui/form.d.ts +8 -0
- package/dist/ui/form.d.ts.map +1 -1
- package/dist/ui/form.js +14 -12
- package/dist/ui/form.js.map +1 -0
- package/dist/ui/hover-card.js.map +1 -0
- package/dist/ui/icon-button.js.map +1 -0
- package/dist/ui/icon-context.js.map +1 -0
- package/dist/ui/icon-group.js.map +1 -0
- package/dist/ui/icon.js.map +1 -0
- package/dist/ui/index.d.ts +4 -4
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +82 -66
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/input-otp.d.ts +12 -3
- package/dist/ui/input-otp.d.ts.map +1 -1
- package/dist/ui/input-otp.js +41 -27
- package/dist/ui/input-otp.js.map +1 -0
- package/dist/ui/input.d.ts.map +1 -1
- package/dist/ui/input.js +16 -15
- package/dist/ui/input.js.map +1 -0
- package/dist/ui/label.d.ts.map +1 -1
- package/dist/ui/label.js +19 -14
- package/dist/ui/label.js.map +1 -0
- package/dist/ui/lib/check-tokens.d.ts +3 -0
- package/dist/ui/lib/check-tokens.d.ts.map +1 -0
- package/dist/ui/lib/date-utils.js.map +1 -0
- package/dist/ui/lib/motion.d.ts +15 -4
- package/dist/ui/lib/motion.d.ts.map +1 -1
- package/dist/ui/lib/motion.js +18 -9
- package/dist/ui/lib/motion.js.map +1 -0
- package/dist/ui/lib/utils.js.map +1 -0
- package/dist/ui/link.js +2 -2
- package/dist/ui/link.js.map +1 -0
- package/dist/ui/menubar.js.map +1 -0
- package/dist/ui/navigation-menu.js.map +1 -0
- package/dist/ui/number-input.d.ts +16 -1
- package/dist/ui/number-input.d.ts.map +1 -1
- package/dist/ui/number-input.js +79 -49
- package/dist/ui/number-input.js.map +1 -0
- package/dist/ui/pagination.js +1 -1
- package/dist/ui/pagination.js.map +1 -0
- package/dist/ui/progress-ring.d.ts.map +1 -1
- package/dist/ui/progress-ring.js.map +1 -0
- package/dist/ui/progress.js.map +1 -0
- package/dist/ui/radio.d.ts.map +1 -1
- package/dist/ui/radio.js +27 -20
- package/dist/ui/radio.js.map +1 -0
- package/dist/ui/search-input.js.map +1 -0
- package/dist/ui/segmented-control.d.ts +1 -1
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +3 -1
- package/dist/ui/segmented-control.js.map +1 -0
- package/dist/ui/select.d.ts.map +1 -1
- package/dist/ui/select.js +54 -48
- package/dist/ui/select.js.map +1 -0
- package/dist/ui/separator.d.ts.map +1 -1
- package/dist/ui/separator.js +10 -7
- package/dist/ui/separator.js.map +1 -0
- package/dist/ui/sheet.js +29 -29
- package/dist/ui/sheet.js.map +1 -0
- package/dist/ui/sidebar.js +9 -9
- package/dist/ui/sidebar.js.map +1 -0
- package/dist/ui/skeleton.js.map +1 -0
- package/dist/ui/slider.d.ts +22 -3
- package/dist/ui/slider.d.ts.map +1 -1
- package/dist/ui/slider.js +57 -19
- package/dist/ui/slider.js.map +1 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/split-button.d.ts.map +1 -1
- package/dist/ui/split-button.js +77 -76
- package/dist/ui/split-button.js.map +1 -0
- package/dist/ui/stack.js.map +1 -0
- package/dist/ui/stat-card.js.map +1 -0
- package/dist/ui/status-dot.js.map +1 -0
- package/dist/ui/stepper.d.ts +10 -0
- package/dist/ui/stepper.d.ts.map +1 -1
- package/dist/ui/stepper.js +80 -75
- package/dist/ui/stepper.js.map +1 -0
- package/dist/ui/switch.d.ts.map +1 -1
- package/dist/ui/switch.js +26 -22
- package/dist/ui/switch.js.map +1 -0
- package/dist/ui/table.js.map +1 -0
- package/dist/ui/tabs.d.ts +3 -1
- package/dist/ui/tabs.d.ts.map +1 -1
- package/dist/ui/tabs.js +68 -48
- package/dist/ui/tabs.js.map +1 -0
- package/dist/ui/text.d.ts +1 -1
- package/dist/ui/text.d.ts.map +1 -1
- package/dist/ui/text.js +10 -2
- package/dist/ui/text.js.map +1 -0
- package/dist/ui/textarea.js +1 -1
- package/dist/ui/textarea.js.map +1 -0
- package/dist/ui/toast-registry.d.ts +8 -0
- package/dist/ui/toast-registry.d.ts.map +1 -0
- package/dist/ui/toast-registry.js +13 -0
- package/dist/ui/toast-registry.js.map +1 -0
- package/dist/ui/toast.d.ts.map +1 -1
- package/dist/ui/toast.js +141 -136
- package/dist/ui/toast.js.map +1 -0
- package/dist/ui/toaster.d.ts.map +1 -1
- package/dist/ui/toaster.js +15 -14
- package/dist/ui/toaster.js.map +1 -0
- package/dist/ui/toggle-group.d.ts +2 -0
- package/dist/ui/toggle-group.d.ts.map +1 -1
- package/dist/ui/toggle-group.js +23 -16
- package/dist/ui/toggle-group.js.map +1 -0
- package/dist/ui/toggle.d.ts +2 -0
- package/dist/ui/toggle.d.ts.map +1 -1
- package/dist/ui/toggle.js +14 -6
- package/dist/ui/toggle.js.map +1 -0
- package/dist/ui/tooltip.js.map +1 -0
- package/dist/ui/visually-hidden.js.map +1 -0
- package/docs/components/_header.md +85 -85
- package/docs/components/composed/activity-feed.md +62 -62
- package/docs/components/composed/avatar-group.md +65 -65
- package/docs/components/composed/bulk-action-bar.md +40 -40
- package/docs/components/composed/command-palette.md +40 -40
- package/docs/components/composed/confirm-dialog.md +46 -46
- package/docs/components/composed/content-card.md +36 -36
- package/docs/components/composed/date-picker.md +130 -130
- package/docs/components/composed/deadline-indicator.md +27 -27
- package/docs/components/composed/emoji-picker.md +52 -52
- package/docs/components/composed/empty-state.md +53 -53
- package/docs/components/composed/error-boundary.md +29 -29
- package/docs/components/composed/file-preview.md +40 -40
- package/docs/components/composed/filter-bar.md +57 -57
- package/docs/components/composed/form-section.md +31 -31
- package/docs/components/composed/global-loading.md +27 -27
- package/docs/components/composed/inline-edit.md +35 -35
- package/docs/components/composed/loading-skeleton.md +51 -51
- package/docs/components/composed/markdown-viewer.md +27 -27
- package/docs/components/composed/master-detail.md +48 -48
- package/docs/components/composed/member-picker.md +35 -35
- package/docs/components/composed/multi-select-popover.md +62 -62
- package/docs/components/composed/page-header.md +41 -41
- package/docs/components/composed/page-skeletons.md +32 -32
- package/docs/components/composed/priority-indicator.md +32 -32
- package/docs/components/composed/responsive-overlay.md +34 -34
- package/docs/components/composed/rich-text-editor.md +82 -82
- package/docs/components/composed/schedule-view.md +39 -39
- package/docs/components/composed/simple-tooltip.md +33 -33
- package/docs/components/composed/status-badge.md +55 -55
- package/docs/components/shell/app-command-palette.md +44 -44
- package/docs/components/shell/bottom-navbar.md +52 -52
- package/docs/components/shell/command-registry.md +48 -48
- package/docs/components/shell/link-context.md +41 -41
- package/docs/components/shell/notification-center.md +63 -63
- package/docs/components/shell/notification-preferences.md +42 -42
- package/docs/components/shell/sidebar.md +92 -92
- package/docs/components/shell/top-bar.md +143 -143
- package/docs/components/ui/accordion.md +51 -51
- package/docs/components/ui/alert-dialog.md +61 -61
- package/docs/components/ui/alert.md +46 -46
- package/docs/components/ui/aspect-ratio.md +25 -25
- package/docs/components/ui/autocomplete.md +48 -48
- package/docs/components/ui/avatar.md +56 -56
- package/docs/components/ui/badge.md +83 -82
- package/docs/components/ui/banner.md +42 -42
- package/docs/components/ui/breadcrumb.md +37 -37
- package/docs/components/ui/button-group.md +41 -41
- package/docs/components/ui/button.md +94 -93
- package/docs/components/ui/card.md +52 -52
- package/docs/components/ui/charts.md +43 -43
- package/docs/components/ui/checkbox.md +36 -36
- package/docs/components/ui/chip.md +47 -47
- package/docs/components/ui/code.md +28 -28
- package/docs/components/ui/collapsible.md +40 -40
- package/docs/components/ui/color-input.md +91 -91
- package/docs/components/ui/color-swatch.md +25 -25
- package/docs/components/ui/combobox.md +54 -54
- package/docs/components/ui/container.md +26 -26
- package/docs/components/ui/context-menu.md +43 -43
- package/docs/components/ui/data-table-body.md +1 -1
- package/docs/components/ui/data-table-bulk-actions.md +1 -1
- package/docs/components/ui/data-table-card.md +1 -1
- package/docs/components/ui/data-table-context.md +1 -1
- package/docs/components/ui/data-table-header.md +1 -1
- package/docs/components/ui/data-table-pagination.md +1 -1
- package/docs/components/ui/data-table-toolbar.md +44 -44
- package/docs/components/ui/data-table.md +94 -94
- package/docs/components/ui/dialog.md +54 -54
- package/docs/components/ui/dropdown-menu.md +48 -48
- package/docs/components/ui/file-upload.md +41 -41
- package/docs/components/ui/form.md +51 -51
- package/docs/components/ui/hover-card.md +32 -32
- package/docs/components/ui/icon-button.md +40 -40
- package/docs/components/ui/input-otp.md +44 -44
- package/docs/components/ui/input.md +74 -74
- package/docs/components/ui/label.md +25 -25
- package/docs/components/ui/link.md +29 -29
- package/docs/components/ui/menubar.md +44 -44
- package/docs/components/ui/navigation-menu.md +46 -46
- package/docs/components/ui/number-input.md +44 -44
- package/docs/components/ui/pagination.md +48 -48
- package/docs/components/ui/popover.md +30 -30
- package/docs/components/ui/progress-ring.md +41 -41
- package/docs/components/ui/progress.md +34 -34
- package/docs/components/ui/radio.md +34 -34
- package/docs/components/ui/search-input.md +43 -43
- package/docs/components/ui/segmented-control.md +50 -50
- package/docs/components/ui/select.md +53 -53
- package/docs/components/ui/separator.md +32 -32
- package/docs/components/ui/sheet.md +47 -47
- package/docs/components/ui/sidebar.md +72 -72
- package/docs/components/ui/skeleton.md +77 -77
- package/docs/components/ui/slider.md +29 -29
- package/docs/components/ui/spinner.md +54 -54
- package/docs/components/ui/stack.md +39 -39
- package/docs/components/ui/stat-card.md +61 -61
- package/docs/components/ui/status-dot.md +26 -26
- package/docs/components/ui/stepper.md +49 -49
- package/docs/components/ui/switch.md +47 -47
- package/docs/components/ui/table.md +47 -47
- package/docs/components/ui/tabs.md +60 -60
- package/docs/components/ui/text.md +37 -37
- package/docs/components/ui/textarea.md +39 -39
- package/docs/components/ui/toast.md +65 -65
- package/docs/components/ui/toaster.md +47 -47
- package/docs/components/ui/toggle-group.md +43 -43
- package/docs/components/ui/toggle.md +37 -37
- package/docs/components/ui/tooltip.md +38 -38
- package/docs/components/ui/tree-view.md +65 -65
- package/docs/components/ui/visually-hidden.md +21 -21
- package/llms-full.txt +5266 -5264
- package/llms.txt +624 -580
- package/package.json +7 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-context.js","names":[],"sources":["../../src/ui/data-table-context.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { type ColumnPinningState, type Table } from '@tanstack/react-table'\n\nimport type { Density } from './data-table-toolbar'\n\n// ── Shared types ────────────────────────────────────────────────\n\n/** Editing state: which cell is currently in edit mode */\nexport type EditingCell = { rowIndex: number; columnId: string } | null\n\n// ── Utility functions ───────────────────────────────────────────\n\nexport function getColumnMetaClasses(meta?: Record<string, unknown>): string {\n if (!meta) return ''\n const classes: string[] = []\n if (meta.align === 'right') classes.push('text-right tabular-nums')\n if (meta.align === 'center') classes.push('text-center')\n if (meta.hideBelow === 'sm') classes.push('hidden sm:table-cell')\n if (meta.hideBelow === 'md') classes.push('hidden md:table-cell')\n if (meta.hideBelow === 'lg') classes.push('hidden lg:table-cell')\n return classes.join(' ')\n}\n\nexport const densityPaddingMap: Record<Density, string> = {\n compact: 'py-ds-02',\n standard: 'py-ds-05',\n comfortable: 'py-ds-07',\n}\n\n/** Interactive element selectors for row click filtering */\nexport const INTERACTIVE_SELECTOR =\n 'button, a, input, select, textarea, [role=\"checkbox\"]'\n\n// ── Context ─────────────────────────────────────────────────────\n\nexport interface DataTableContextValue<TData = unknown> {\n table: Table<TData>\n /** All assembled columns (including _select, _expand) */\n allColumns: { id?: string; header?: unknown }[]\n /** Current cell padding class based on density */\n cellPadding: string\n /** Column pinning state for sticky positioning */\n columnPinningState: ColumnPinningState\n /** Whether sorting is enabled */\n sortable: boolean\n /** Whether per-column filters are enabled */\n filterable: boolean\n /** Whether inline editing is enabled */\n editable: boolean\n /** Whether row expansion is enabled */\n expandable: boolean\n /** Whether virtual rows are enabled */\n virtualRows: boolean\n /** Whether row selection is enabled */\n selectable: boolean\n /** Mobile view mode */\n mobileView: 'card' | 'table'\n /** Current editing cell */\n editingCell: EditingCell\n /** Set editing cell */\n setEditingCell: (cell: EditingCell) => void\n /** Callback when a cell value is edited */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void\n /** Render function for expanded row content */\n renderExpanded?: (row: TData) => React.ReactNode\n /** Row click handler */\n onRowClick?: (row: TData) => void\n}\n\nconst DataTableContext = React.createContext<DataTableContextValue | null>(null)\n\nexport function DataTableProvider<TData>({\n children,\n value,\n}: {\n children: React.ReactNode\n value: DataTableContextValue<TData>\n}) {\n return (\n <DataTableContext.Provider value={value as DataTableContextValue}>\n {children}\n </DataTableContext.Provider>\n )\n}\n\nexport function useDataTableContext<TData = unknown>() {\n const ctx = React.useContext(DataTableContext)\n if (!ctx) throw new Error('useDataTableContext must be used within DataTableProvider')\n return ctx as DataTableContextValue<TData>\n}\n\n// ── Shared helpers ──────────────────────────────────────────────\n\n/** Compute sticky positioning styles for pinned columns */\nexport function getPinnedCellStyle(\n columnId: string,\n columnPinningState: ColumnPinningState,\n) {\n const { left = [], right = [] } = columnPinningState\n const leftIndex = left.indexOf(columnId)\n const rightIndex = right.indexOf(columnId)\n\n if (leftIndex !== -1) {\n return {\n className: 'sticky bg-surface-base z-raised',\n style: { left: 0 } as React.CSSProperties,\n }\n }\n if (rightIndex !== -1) {\n return {\n className: 'sticky bg-surface-base z-raised',\n style: { right: 0 } as React.CSSProperties,\n }\n }\n return { className: '', style: {} as React.CSSProperties }\n}\n\n/** Check if a column allows editing */\nexport function isColumnEditable<TData>(\n columnId: string,\n editable: boolean,\n table: Table<TData>,\n): boolean {\n if (!editable) return false\n // Internal columns are never editable\n if (columnId === '_select' || columnId === '_expand') return false\n const col = table.getColumn(columnId)\n if (!col) return false\n const meta = col.columnDef.meta as\n | { enableEditing?: boolean }\n | undefined\n // Editable by default unless explicitly disabled\n if (meta?.enableEditing === false) return false\n return true\n}\n"],"mappings":";;;;AAcA,SAAgB,EAAqB,GAAwC;AAC3E,KAAI,CAAC,EAAM,QAAO;CAClB,IAAM,IAAoB,EAAE;AAM5B,QALI,EAAK,UAAU,WAAS,EAAQ,KAAK,0BAA0B,EAC/D,EAAK,UAAU,YAAU,EAAQ,KAAK,cAAc,EACpD,EAAK,cAAc,QAAM,EAAQ,KAAK,uBAAuB,EAC7D,EAAK,cAAc,QAAM,EAAQ,KAAK,uBAAuB,EAC7D,EAAK,cAAc,QAAM,EAAQ,KAAK,uBAAuB,EAC1D,EAAQ,KAAK,IAAI;;AAG1B,IAAa,IAA6C;CACxD,SAAS;CACT,UAAU;CACV,aAAa;CACd,EAGY,IACX,2DAsCI,IAAmB,EAAM,cAA4C,KAAK;AAEhF,SAAgB,EAAyB,EACvC,aACA,YAIC;AACD,QACE,kBAAC,EAAiB,UAAlB;EAAkC;EAC/B;EACyB,CAAA;;AAIhC,SAAgB,IAAuC;CACrD,IAAM,IAAM,EAAM,WAAW,EAAiB;AAC9C,KAAI,CAAC,EAAK,OAAU,MAAM,4DAA4D;AACtF,QAAO;;AAMT,SAAgB,EACd,GACA,GACA;CACA,IAAM,EAAE,UAAO,EAAE,EAAE,WAAQ,EAAE,KAAK,GAC5B,IAAY,EAAK,QAAQ,EAAS,EAClC,IAAa,EAAM,QAAQ,EAAS;AAc1C,QAZI,MAAc,KAMd,MAAe,KAMZ;EAAE,WAAW;EAAI,OAAO,EAAE;EAAyB,GALjD;EACL,WAAW;EACX,OAAO,EAAE,OAAO,GAAG;EACpB,GATM;EACL,WAAW;EACX,OAAO,EAAE,MAAM,GAAG;EACnB;;AAYL,SAAgB,EACd,GACA,GACA,GACS;AAGT,KAFI,CAAC,KAED,MAAa,aAAa,MAAa,UAAW,QAAO;CAC7D,IAAM,IAAM,EAAM,UAAU,EAAS;AAOrC,QADA,EALI,CAAC,KACQ,EAAI,UAAU,MAIjB,kBAAkB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-header.js","names":[],"sources":["../../src/ui/data-table-header.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { flexRender } from '@tanstack/react-table'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport {\n IconArrowDown,\n IconArrowUp,\n IconArrowsSort,\n} from '@tabler/icons-react'\n\nimport { Icon } from './icon'\nimport { TableHead, TableHeader, TableRow } from './table'\nimport { cn } from './lib/utils'\nimport { springs } from './lib/motion'\nimport {\n useDataTableContext,\n getColumnMetaClasses,\n getPinnedCellStyle,\n} from './data-table-context'\n\n/**\n * Renders the `<TableHeader>` block including sortable column headers\n * and optional per-column filter inputs. Internal — not exported to consumers.\n */\nfunction DataTableHeaderImpl({ stickyHeader }: { stickyHeader?: boolean }) {\n const { table, sortable, filterable, columnPinningState } =\n useDataTableContext()\n\n return (\n <TableHeader\n className={cn(\n stickyHeader && 'sticky top-0 z-10 bg-surface-base',\n )}\n >\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n const canSort = sortable && header.column.getCanSort()\n const sorted = header.column.getIsSorted()\n const pinned = getPinnedCellStyle(\n header.column.id,\n columnPinningState,\n )\n\n return (\n <TableHead\n key={header.id}\n className={cn(\n pinned.className,\n getColumnMetaClasses(\n header.column.columnDef.meta as Record<string, unknown>,\n ),\n )}\n style={pinned.style}\n aria-sort={\n canSort\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n {header.isPlaceholder ? null : canSort ? (\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-ds-01 font-medium',\n 'cursor-pointer select-none',\n '-ml-ds-01 rounded-ds-sm px-ds-01 py-ds-01',\n 'hover:bg-surface-raised transition-colors',\n )}\n onClick={header.column.getToggleSortingHandler()}\n aria-label={`Sort by ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id}`}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n <AnimatePresence mode=\"wait\" initial={false}>\n {sorted === 'asc' ? (\n <motion.span\n key=\"asc\"\n initial={{ opacity: 0, rotate: 90 }}\n animate={{ opacity: 1, rotate: 0 }}\n exit={{ opacity: 0, rotate: -90 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowUp}\n size=\"sm\"\n className=\"text-surface-fg-muted\"\n />\n </motion.span>\n ) : sorted === 'desc' ? (\n <motion.span\n key=\"desc\"\n initial={{ opacity: 0, rotate: -90 }}\n animate={{ opacity: 1, rotate: 0 }}\n exit={{ opacity: 0, rotate: 90 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowDown}\n size=\"sm\"\n className=\"text-surface-fg-muted\"\n />\n </motion.span>\n ) : (\n <motion.span\n key=\"unsorted\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowsSort}\n size=\"sm\"\n className=\"text-surface-fg-subtle\"\n />\n </motion.span>\n )}\n </AnimatePresence>\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </TableHead>\n )\n })}\n </TableRow>\n ))}\n\n {/* Column filter row */}\n {filterable &&\n table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={`${headerGroup.id}-filters`}>\n {headerGroup.headers.map((header) => (\n <TableHead key={`${header.id}-filter`} className=\"py-ds-01\">\n {header.isPlaceholder ||\n header.column.columnDef.enableColumnFilter === false ? null : (\n <input\n type=\"text\"\n value={\n (header.column.getFilterValue() as string) ?? ''\n }\n onChange={(e) =>\n header.column.setFilterValue(e.target.value)\n }\n placeholder={`Filter ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : ''}...`}\n aria-label={`Filter ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id}`}\n className={cn(\n 'h-ds-xs-plus w-full rounded-ds-md',\n 'border border-surface-border-strong bg-surface-raised-hover',\n 'px-ds-02 text-ds-sm',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden focus:border-accent-7',\n )}\n />\n )}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n )\n}\n\nexport { DataTableHeaderImpl as DataTableHeader }\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-pagination.js","names":[],"sources":["../../src/ui/data-table-pagination.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { type Table } from '@tanstack/react-table'\nimport { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'\n\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\n/**\n * Pagination controls: page size selector, prev/next buttons, page info.\n * Internal — not exported to consumers.\n */\nexport function DataTablePagination<TData>({\n table,\n totalRowCount,\n useServerPagination,\n pageSizeOptions,\n}: {\n table: Table<TData>\n totalRowCount: number\n useServerPagination: boolean\n pageSizeOptions?: number[]\n}) {\n return (\n <div className=\"flex items-center justify-between px-ds-03 py-ds-04 border-t border-surface-border\">\n <span className=\"text-ds-sm text-surface-fg-muted\">\n {totalRowCount} total rows\n </span>\n <div className=\"flex items-center gap-ds-03\">\n {/* Page size selector */}\n {!useServerPagination && (\n <select\n value={table.getState().pagination.pageSize}\n onChange={(e) => {\n table.setPageSize(Number(e.target.value))\n }}\n aria-label=\"Rows per page\"\n className={cn(\n 'h-ds-sm rounded-ds-md',\n 'border border-surface-border-strong bg-surface-raised-hover',\n 'px-ds-03 text-ds-sm',\n 'text-surface-fg',\n )}\n >\n {(pageSizeOptions ?? [10, 20, 50, 100]).map((size) => (\n <option key={size} value={size}>\n {size} rows\n </option>\n ))}\n </select>\n )}\n\n {/* Previous page button */}\n <button\n type=\"button\"\n disabled={!table.getCanPreviousPage()}\n onClick={() => table.previousPage()}\n aria-label=\"Previous page\"\n className={cn(\n 'h-ds-sm w-ds-sm flex items-center justify-center',\n 'rounded-ds-md border border-surface-border-strong',\n 'enabled:hover:bg-surface-raised',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n 'transition-colors',\n )}\n >\n <Icon icon={IconChevronLeft} size=\"sm\" />\n </button>\n\n {/* Page info */}\n <span className=\"text-ds-sm text-surface-fg-muted\">\n Page {table.getState().pagination.pageIndex + 1} of{' '}\n {table.getPageCount()}\n </span>\n\n {/* Next page button */}\n <button\n type=\"button\"\n disabled={!table.getCanNextPage()}\n onClick={() => table.nextPage()}\n aria-label=\"Next page\"\n className={cn(\n 'h-ds-sm w-ds-sm flex items-center justify-center',\n 'rounded-ds-md border border-surface-border-strong',\n 'enabled:hover:bg-surface-raised',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n 'transition-colors',\n )}\n >\n <Icon icon={IconChevronRight} size=\"sm\" />\n </button>\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,EAA2B,EACzC,UACA,kBACA,wBACA,sBAMC;AACD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACG,GAAc,cACV;MACP,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEG,CAAC,KACA,kBAAC,UAAD;KACE,OAAO,EAAM,UAAU,CAAC,WAAW;KACnC,WAAW,MAAM;AACf,QAAM,YAAY,OAAO,EAAE,OAAO,MAAM,CAAC;;KAE3C,cAAW;KACX,WAAW,EACT,yBACA,+DACA,uBACA,kBACD;gBAEC,KAAmB;MAAC;MAAI;MAAI;MAAI;MAAI,EAAE,KAAK,MAC3C,kBAAC,UAAD;MAAmB,OAAO;gBAA1B,CACG,GAAK,QACC;QAFI,EAEJ,CACT;KACK,CAAA;IAIX,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,CAAC,EAAM,oBAAoB;KACrC,eAAe,EAAM,cAAc;KACnC,cAAW;KACX,WAAW,EACT,oDACA,qDACA,mCACA,gEACA,oBACD;eAED,kBAAC,GAAD;MAAM,MAAM;MAAiB,MAAK;MAAO,CAAA;KAClC,CAAA;IAGT,kBAAC,QAAD;KAAM,WAAU;eAAhB;MAAmD;MAC3C,EAAM,UAAU,CAAC,WAAW,YAAY;MAAE;MAAI;MACnD,EAAM,cAAc;MAChB;;IAGP,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,CAAC,EAAM,gBAAgB;KACjC,eAAe,EAAM,UAAU;KAC/B,cAAW;KACX,WAAW,EACT,oDACA,qDACA,mCACA,gEACA,oBACD;eAED,kBAAC,GAAD;MAAM,MAAM;MAAkB,MAAK;MAAO,CAAA;KACnC,CAAA;IACL;KACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-toolbar.js","names":[],"sources":["../../src/ui/data-table-toolbar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { type Table } from '@tanstack/react-table'\nimport {\n IconSearch,\n IconColumns3,\n IconTextResize,\n IconDownload,\n} from '@tabler/icons-react'\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from './dropdown-menu'\nimport { cn } from './lib/utils'\nimport { Icon } from './icon'\n\nexport type Density = 'compact' | 'standard' | 'comfortable'\n\nconst densityLabels: Record<Density, string> = {\n compact: 'Compact',\n standard: 'Standard',\n comfortable: 'Comfortable',\n}\n\nconst densityCycle: Record<Density, Density> = {\n compact: 'standard',\n standard: 'comfortable',\n comfortable: 'compact',\n}\n\nexport interface DataTableToolbarProps<TData> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n table: Table<TData>\n globalFilter?: boolean\n globalFilterValue: string\n onGlobalFilterChange: (value: string) => void\n density: Density\n onDensityChange: (density: Density) => void\n enableExport?: boolean\n}\n\nconst toolbarButtonClass = cn(\n 'h-ds-sm px-ds-03 rounded-ds-md',\n 'border border-surface-border-strong',\n 'hover:bg-surface-raised',\n 'text-ds-sm flex items-center gap-ds-02 transition-colors',\n)\n\nconst toolbarIconClass = 'text-surface-fg-subtle'\n\nfunction exportToCsv<TData>(table: Table<TData>) {\n const headers = table\n .getAllLeafColumns()\n .filter((col) => col.getIsVisible() && col.id !== '_select')\n .map((col) => {\n const header = col.columnDef.header\n return typeof header === 'string' ? header : col.id\n })\n\n const rows = table.getFilteredRowModel().rows.map((row) =>\n table\n .getAllLeafColumns()\n .filter((col) => col.getIsVisible() && col.id !== '_select')\n .map((col) => {\n const value = row.getValue(col.id)\n const str = String(value ?? '')\n // Escape CSV: wrap in quotes if it contains comma, quote, or newline\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`\n }\n return str\n }),\n )\n\n const csvContent = [headers.join(','), ...rows.map((r) => r.join(','))].join(\n '\\n',\n )\n\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = 'table-export.csv'\n link.click()\n URL.revokeObjectURL(url)\n}\n\nexport function DataTableToolbar<TData>({\n table,\n globalFilter = false,\n globalFilterValue,\n onGlobalFilterChange,\n density,\n onDensityChange,\n enableExport = true,\n className,\n ...props\n}: DataTableToolbarProps<TData>) {\n const toggleableColumns = table\n .getAllColumns()\n .filter((col) => col.getCanHide() && col.id !== '_select')\n\n return (\n <div className={cn('flex items-center gap-ds-03 pb-ds-04', className)} {...props}>\n {/* Global search */}\n {globalFilter && (\n <div className=\"flex flex-1 items-center gap-ds-02\">\n <Icon icon={IconSearch} size=\"sm\" className={toolbarIconClass} />\n <input\n type=\"text\"\n value={globalFilterValue}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n placeholder=\"Search all columns...\"\n aria-label=\"Search all columns\"\n className={cn(\n 'flex-1 bg-transparent text-ds-md',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden',\n 'h-ds-sm',\n )}\n />\n </div>\n )}\n\n <div className=\"ml-auto flex items-center gap-ds-03\">\n {/* Column visibility dropdown */}\n {toggleableColumns.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className={toolbarButtonClass}\n aria-label=\"Toggle column visibility\"\n >\n <Icon icon={IconColumns3} size=\"sm\" className={toolbarIconClass} />\n Columns\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-40\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {toggleableColumns.map((column) => {\n const headerDef = column.columnDef.header\n const label =\n typeof headerDef === 'string' ? headerDef : column.id\n return (\n <DropdownMenuCheckboxItem\n key={column.id}\n checked={column.getIsVisible()}\n onCheckedChange={(value) =>\n column.toggleVisibility(!!value)\n }\n >\n {label}\n </DropdownMenuCheckboxItem>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Density toggle */}\n <button\n type=\"button\"\n className={toolbarButtonClass}\n onClick={() => onDensityChange(densityCycle[density])}\n aria-label={`Table density: ${densityLabels[density]}. Click to change.`}\n title={`Density: ${densityLabels[density]}`}\n >\n <Icon icon={IconTextResize} size=\"sm\" className={toolbarIconClass} />\n {densityLabels[density]}\n </button>\n\n {/* CSV Export */}\n {enableExport && (\n <button\n type=\"button\"\n className={toolbarButtonClass}\n onClick={() => exportToCsv(table)}\n aria-label=\"Export table as CSV\"\n >\n <Icon icon={IconDownload} size=\"sm\" className={toolbarIconClass} />\n Export\n </button>\n )}\n </div>\n </div>\n )\n}\nDataTableToolbar.displayName = 'DataTableToolbar'\n"],"mappings":"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"}
|
package/dist/ui/data-table.js
CHANGED
|
@@ -16,7 +16,7 @@ import { IconChevronRight as ce, IconSearch as le } from "@tabler/icons-react";
|
|
|
16
16
|
import { getCoreRowModel as ue, getExpandedRowModel as de, getFilteredRowModel as fe, getPaginationRowModel as pe, getSortedRowModel as me, useReactTable as he } from "@tanstack/react-table";
|
|
17
17
|
import { useVirtualizer as ge } from "@tanstack/react-virtual";
|
|
18
18
|
//#region src/ui/data-table.tsx
|
|
19
|
-
function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m = !1, filterable: h = !1, globalFilter: g = !1, paginated: ve = !1, pageSize: _, pageSizeOptions: ye, selectable: v = !1, onSelectionChange: y, toolbar:
|
|
19
|
+
function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m = !1, filterable: h = !1, globalFilter: g = !1, paginated: ve = !1, pageSize: _, pageSizeOptions: ye, selectable: v = !1, onSelectionChange: y, toolbar: b = !1, density: be = "standard", columnPinning: xe, editable: Se = !1, onCellEdit: Ce, expandable: x = !1, renderExpanded: we, virtualRows: S = !1, virtualRowHeight: Te = 48, maxHeight: Ee = 600, onSort: C, emptyState: w, loading: T = !1, selectedIds: E, selectableFilter: De, getRowId: D, pagination: O, singleExpand: k = !1, stickyHeader: Oe = !1, onRowClick: A, bulkActions: j, mobileView: M = "table" }) {
|
|
20
20
|
let [ke, N] = c(!1);
|
|
21
21
|
o(() => {
|
|
22
22
|
let e = window.matchMedia("(max-width: 639px)"), t = () => N(e.matches);
|
|
@@ -26,9 +26,9 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
26
26
|
pageIndex: O ? O.page - 1 : 0,
|
|
27
27
|
pageSize: O?.pageSize ?? _ ?? 10
|
|
28
28
|
}), [R, z] = c({}), [Fe, Ie] = c({}), [B, Le] = c({
|
|
29
|
-
left:
|
|
30
|
-
right:
|
|
31
|
-
}), [V, Re] = c(
|
|
29
|
+
left: xe?.left ?? [],
|
|
30
|
+
right: xe?.right ?? []
|
|
31
|
+
}), [V, Re] = c(be), [H, ze] = c(null), [Be, U] = c({}), W = s(null), G = s(!1);
|
|
32
32
|
o(() => {
|
|
33
33
|
if (E) {
|
|
34
34
|
G.current = !0;
|
|
@@ -47,9 +47,9 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
47
47
|
let Ve = a((e) => {
|
|
48
48
|
P((t) => {
|
|
49
49
|
let n = typeof e == "function" ? e(t) : e;
|
|
50
|
-
return
|
|
50
|
+
return C && (n.length === 0 && t.length > 0 ? C(t[0].id, !1) : n.length > 0 && C(n[0].id, n[0].desc ? "desc" : "asc")), n;
|
|
51
51
|
});
|
|
52
|
-
}, [
|
|
52
|
+
}, [C]), He = a((e) => {
|
|
53
53
|
U((t) => {
|
|
54
54
|
let n = typeof e == "function" ? e(t) : e;
|
|
55
55
|
if (!k || n === !0 || typeof n != "object") return n;
|
|
@@ -110,7 +110,7 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
110
110
|
columnPinning: B
|
|
111
111
|
};
|
|
112
112
|
m && (X.sorting = je), (h || g) && (X.columnFilters = Me, X.globalFilter = F), Y && (X.pagination = Pe), v && (X.rowSelection = R), x && (X.expanded = Be);
|
|
113
|
-
let Ke = m && !!
|
|
113
|
+
let Ke = m && !!C, Z = he({
|
|
114
114
|
data: f,
|
|
115
115
|
columns: q,
|
|
116
116
|
state: X,
|
|
@@ -158,9 +158,9 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
158
158
|
Q.current(t);
|
|
159
159
|
}, [R, f]);
|
|
160
160
|
let qe = ee[V], Je = Z.getRowModel().rows, Ye = ge({
|
|
161
|
-
count:
|
|
161
|
+
count: S ? Je.length : 0,
|
|
162
162
|
getScrollElement: () => W.current,
|
|
163
|
-
estimateSize: () =>
|
|
163
|
+
estimateSize: () => Te,
|
|
164
164
|
overscan: 10
|
|
165
165
|
}), Xe = O?.pageSize ?? _ ?? 5, Ze = se(() => {
|
|
166
166
|
if (!j || !v) return [];
|
|
@@ -185,15 +185,15 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
185
185
|
columnPinningState: B,
|
|
186
186
|
sortable: m,
|
|
187
187
|
filterable: h,
|
|
188
|
-
editable:
|
|
188
|
+
editable: Se,
|
|
189
189
|
expandable: x,
|
|
190
|
-
virtualRows:
|
|
190
|
+
virtualRows: S,
|
|
191
191
|
selectable: v,
|
|
192
192
|
mobileView: M,
|
|
193
193
|
editingCell: H,
|
|
194
194
|
setEditingCell: ze,
|
|
195
|
-
onCellEdit:
|
|
196
|
-
renderExpanded:
|
|
195
|
+
onCellEdit: Ce,
|
|
196
|
+
renderExpanded: we,
|
|
197
197
|
onRowClick: A
|
|
198
198
|
}), [
|
|
199
199
|
Z,
|
|
@@ -202,29 +202,32 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
202
202
|
B,
|
|
203
203
|
m,
|
|
204
204
|
h,
|
|
205
|
-
|
|
205
|
+
Se,
|
|
206
206
|
x,
|
|
207
|
-
|
|
207
|
+
S,
|
|
208
208
|
v,
|
|
209
209
|
M,
|
|
210
210
|
H,
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
Ce,
|
|
212
|
+
we,
|
|
213
213
|
A
|
|
214
|
-
]), tt =
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
]), tt = S ? Ye.getVirtualItems() : void 0, nt = S ? Ye.getTotalSize() : void 0, rt = /* @__PURE__ */ u(r, {
|
|
215
|
+
"aria-busy": T || void 0,
|
|
216
|
+
children: [/* @__PURE__ */ l(ie, { stickyHeader: Oe }), /* @__PURE__ */ l(te, {
|
|
217
|
+
loading: T,
|
|
218
|
+
skeletonRowCount: Xe,
|
|
219
|
+
noResultsText: p,
|
|
220
|
+
emptyState: w,
|
|
221
|
+
virtualItems: tt,
|
|
222
|
+
totalVirtualSize: nt
|
|
223
|
+
})]
|
|
224
|
+
});
|
|
222
225
|
return /* @__PURE__ */ l(i, {
|
|
223
226
|
value: et,
|
|
224
227
|
children: /* @__PURE__ */ u("div", {
|
|
225
228
|
className: e(_e),
|
|
226
229
|
children: [
|
|
227
|
-
|
|
230
|
+
b && /* @__PURE__ */ l(oe, {
|
|
228
231
|
table: Z,
|
|
229
232
|
globalFilter: g,
|
|
230
233
|
globalFilterValue: F,
|
|
@@ -232,7 +235,7 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
232
235
|
density: V,
|
|
233
236
|
onDensityChange: Re
|
|
234
237
|
}),
|
|
235
|
-
g && !
|
|
238
|
+
g && !b && /* @__PURE__ */ u("div", {
|
|
236
239
|
className: "flex items-center gap-ds-03 pb-ds-04 border-b border-surface-border mb-ds-04",
|
|
237
240
|
children: [/* @__PURE__ */ l(t, {
|
|
238
241
|
icon: le,
|
|
@@ -248,14 +251,14 @@ function d({ columns: d, data: f, className: _e, noResultsText: p, sortable: m =
|
|
|
248
251
|
})]
|
|
249
252
|
}),
|
|
250
253
|
Ae ? /* @__PURE__ */ l(re, {
|
|
251
|
-
loading:
|
|
254
|
+
loading: T,
|
|
252
255
|
skeletonRowCount: Xe,
|
|
253
256
|
noResultsText: p,
|
|
254
|
-
emptyState:
|
|
255
|
-
}) :
|
|
257
|
+
emptyState: w
|
|
258
|
+
}) : S ? /* @__PURE__ */ l("div", {
|
|
256
259
|
ref: W,
|
|
257
260
|
style: {
|
|
258
|
-
maxHeight: `${
|
|
261
|
+
maxHeight: `${Ee}px`,
|
|
259
262
|
overflowY: "auto"
|
|
260
263
|
},
|
|
261
264
|
children: rt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table.js","names":[],"sources":["../../src/ui/data-table.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnPinningState,\n type ExpandedState,\n type PaginationState,\n type Row,\n type RowData,\n type RowSelectionState,\n type SortingState,\n type TableState,\n type Updater,\n type VisibilityState,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { IconChevronRight, IconSearch } from '@tabler/icons-react'\n\nimport { Icon } from './icon'\nimport { Table } from './table'\nimport { Checkbox } from './checkbox'\nimport { cn } from './lib/utils'\nimport { DataTableToolbar, type Density } from './data-table-toolbar'\nimport {\n DataTableProvider,\n densityPaddingMap,\n type EditingCell,\n} from './data-table-context'\nimport { DataTableHeader } from './data-table-header'\nimport { DataTableBody } from './data-table-body'\nimport { DataTableCards } from './data-table-card'\nimport { DataTablePagination } from './data-table-pagination'\nimport { DataTableBulkActions, type BulkAction } from './data-table-bulk-actions'\n\n// Re-export public types so consumers' imports don't break\nexport type { BulkAction } from './data-table-bulk-actions'\n\ndeclare module '@tanstack/react-table' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface ColumnMeta<TData extends RowData, TValue> {\n align?: 'left' | 'center' | 'right'\n hideBelow?: 'sm' | 'md' | 'lg'\n }\n}\n\n/**\n * Props for DataTable — a feature-rich TanStack Table wrapper supporting sorting, filtering,\n * pagination, row selection, inline editing, row expansion, column pinning, and virtualization.\n *\n * All features are opt-in via boolean flags. The component manages its own internal state for\n * sorting, filtering, pagination, and selection — just pass `columns` and `data`.\n *\n * **Feature flags:** `sortable` | `filterable` | `globalFilter` | `paginated` | `selectable` |\n * `toolbar` | `editable` | `expandable` | `virtualRows`\n *\n * **Columns:** Use TanStack Table's `ColumnDef<TData, TValue>` type. Set\n * `meta: { enableEditing: false }` on a column to disable cell editing for that column.\n *\n * @example\n * // Minimal read-only table:\n * const columns: ColumnDef<User, string>[] = [\n * { accessorKey: 'name', header: 'Name' },\n * { accessorKey: 'email', header: 'Email' },\n * ]\n * <DataTable columns={columns} data={users} />\n *\n * @example\n * // Full-featured admin table with sorting, pagination, and selection:\n * <DataTable\n * columns={projectColumns}\n * data={projects}\n * sortable\n * paginated\n * pageSize={20}\n * selectable\n * onSelectionChange={(rows) => setSelectedProjects(rows)}\n * toolbar\n * />\n *\n * @example\n * // Virtualized table for large datasets (10k+ rows):\n * <DataTable\n * columns={logColumns}\n * data={allLogs}\n * virtualRows\n * virtualRowHeight={40}\n * maxHeight={500}\n * />\n *\n * @example\n * // Table with expandable rows for nested detail:\n * <DataTable\n * columns={orderColumns}\n * data={orders}\n * expandable\n * renderExpanded={(order) => <OrderLineItems items={order.lineItems} />}\n * />\n * // These are just a few ways — feel free to combine props creatively!\n */\n/**\n * A full-featured data table built on TanStack Table with sorting, filtering,\n * pagination, row selection, inline cell editing, expandable rows, column pinning,\n * a toolbar with density/export controls, and optional row virtualization.\n */\nexport interface DataTableProps<TData, TValue> {\n /** Column definitions passed to TanStack Table. */\n columns: ColumnDef<TData, TValue>[]\n /** Row data */\n data: TData[]\n /** Additional class name for the wrapper div */\n className?: string\n /** Text shown when the table has no rows */\n noResultsText?: string\n /** Enable column sorting (click headers to sort) */\n sortable?: boolean\n /** Enable per-column filter inputs below headers */\n filterable?: boolean\n /** Enable a global search input above the table */\n globalFilter?: boolean\n /** Enable pagination controls below the table */\n paginated?: boolean\n /** Number of rows per page when paginated (default 10) */\n pageSize?: number\n /** Options for the page size selector dropdown (default [10, 20, 50, 100]) */\n pageSizeOptions?: number[]\n /** Enable row selection with checkboxes */\n selectable?: boolean\n /** Callback when row selection changes */\n onSelectionChange?: (selectedRows: TData[]) => void\n /** Show toolbar above the table with column visibility, density, and export controls */\n toolbar?: boolean\n /** Row density — controls cell vertical padding */\n density?: Density\n /** Initial column pinning configuration */\n columnPinning?: { left?: string[]; right?: string[] }\n\n // --- Cell Editing ---\n /** Enable inline cell editing (double-click to edit) */\n editable?: boolean\n /** Callback when a cell value is edited */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void\n\n // --- Row Expansion ---\n /** Enable expandable rows with detail panels */\n expandable?: boolean\n /** Render function for expanded row content */\n renderExpanded?: (row: TData) => React.ReactNode\n\n // --- Virtualization ---\n /** Enable row virtualization for large datasets */\n virtualRows?: boolean\n /** Height of each virtual row in pixels (default 48) */\n virtualRowHeight?: number\n /** Maximum height of the scrollable container in pixels (default 600) */\n maxHeight?: number\n\n // --- Server-side sorting ---\n /** Callback for server-side sorting. When provided, sorting is manual (no client-side sort). */\n onSort?: (key: string, direction: 'asc' | 'desc' | false) => void\n\n // --- Empty state ---\n /** Custom ReactNode to render when data is empty (replaces noResultsText) */\n emptyState?: React.ReactNode\n\n // --- Loading ---\n /** Show shimmer skeleton rows instead of data */\n loading?: boolean\n\n // --- Controlled selection ---\n /** Controlled set of selected row IDs — syncs internal selection state */\n selectedIds?: Set<string>\n /** Per-row filter to determine if a row is selectable */\n selectableFilter?: (row: TData) => boolean\n /** Custom row ID getter */\n getRowId?: (row: TData) => string\n\n // --- Server-side pagination ---\n /** Server-side pagination config. When provided, pagination is manual. */\n pagination?: {\n page: number\n pageSize: number\n total: number\n onPageChange: (page: number) => void\n }\n\n // --- Single-expand mode ---\n /** When true, only one row can be expanded at a time */\n singleExpand?: boolean\n\n // --- Sticky header ---\n /** When true, the table header sticks to the top on scroll */\n stickyHeader?: boolean\n\n // --- Row click ---\n /** Callback when a row is clicked (not fired from interactive elements) */\n onRowClick?: (row: TData) => void\n\n // --- Bulk actions ---\n /** Actions shown in a floating bar when rows are selected */\n bulkActions?: BulkAction<TData>[]\n\n // --- Mobile view ---\n /** Render rows as stacked cards on small screens (below sm breakpoint). Default 'table'. */\n mobileView?: 'card' | 'table'\n}\n\nexport function DataTable<TData, TValue>({\n columns,\n data,\n className,\n noResultsText,\n sortable = false,\n filterable = false,\n globalFilter = false,\n paginated = false,\n pageSize: initialPageSize,\n pageSizeOptions,\n selectable = false,\n onSelectionChange,\n toolbar = false,\n density: initialDensity = 'standard',\n columnPinning: initialColumnPinning,\n editable = false,\n onCellEdit,\n expandable = false,\n renderExpanded,\n virtualRows = false,\n virtualRowHeight = 48,\n maxHeight = 600,\n onSort,\n emptyState,\n loading = false,\n selectedIds,\n selectableFilter,\n getRowId: getRowIdProp,\n pagination: serverPagination,\n singleExpand = false,\n stickyHeader = false,\n onRowClick,\n bulkActions,\n mobileView = 'table',\n}: DataTableProps<TData, TValue>) {\n // Detect below-sm viewport (640px) for card mode — separate from useIsMobile (768px)\n const [isBelowSm, setIsBelowSm] = useState(false)\n useEffect(() => {\n const mql = window.matchMedia('(max-width: 639px)')\n const onChange = () => setIsBelowSm(mql.matches)\n mql.addEventListener('change', onChange)\n setIsBelowSm(mql.matches)\n return () => mql.removeEventListener('change', onChange)\n }, [])\n\n const showCards = mobileView === 'card' && isBelowSm\n\n const [sorting, setSorting] = useState<SortingState>([])\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n const [globalFilterValue, setGlobalFilterValue] = useState('')\n const [paginationState, setPaginationState] = useState<PaginationState>({\n pageIndex: serverPagination ? serverPagination.page - 1 : 0,\n pageSize: serverPagination?.pageSize ?? initialPageSize ?? 10,\n })\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n const [columnPinningState, setColumnPinningState] =\n useState<ColumnPinningState>({\n left: initialColumnPinning?.left ?? [],\n right: initialColumnPinning?.right ?? [],\n })\n const [density, setDensity] = useState<Density>(initialDensity)\n const [editingCell, setEditingCell] = useState<EditingCell>(null)\n const [expanded, setExpanded] = useState<ExpandedState>({})\n\n // Ref for the virtual scroll container\n const scrollContainerRef = useRef<HTMLDivElement>(null)\n\n // Guard to prevent onSelectionChange firing when syncing from selectedIds prop\n const isSyncingFromPropRef = useRef(false)\n\n // Sync controlled selectedIds to internal rowSelection\n useEffect(() => {\n if (selectedIds) {\n isSyncingFromPropRef.current = true\n const newSelection: RowSelectionState = {}\n selectedIds.forEach((id) => {\n newSelection[id] = true\n })\n setRowSelection(newSelection)\n }\n }, [selectedIds])\n\n // Sync server pagination page to internal state\n useEffect(() => {\n if (serverPagination) {\n setPaginationState((prev) => ({\n ...prev,\n pageIndex: serverPagination.page - 1,\n pageSize: serverPagination.pageSize,\n }))\n }\n }, [serverPagination?.page, serverPagination?.pageSize]) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Server-side sorting handler\n const handleSortingChange = useCallback(\n (updater: Updater<SortingState>) => {\n setSorting((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (onSort) {\n if (next.length === 0 && prev.length > 0) {\n // Sorting cleared\n onSort(prev[0].id, false)\n } else if (next.length > 0) {\n onSort(next[0].id, next[0].desc ? 'desc' : 'asc')\n }\n }\n return next\n })\n },\n [onSort],\n )\n\n // Single-expand handler\n const handleExpandedChange = useCallback(\n (updater: Updater<ExpandedState>) => {\n setExpanded((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (!singleExpand) return next\n // If next is boolean true (expand all), just use it\n if (next === true) return next\n if (typeof next !== 'object') return next\n // Determine which row was just toggled on\n const prevKeys = typeof prev === 'object' ? Object.keys(prev).filter((k) => (prev as Record<string, boolean>)[k]) : []\n const nextKeys = Object.keys(next).filter((k) => (next as Record<string, boolean>)[k])\n // Find newly expanded row\n const newlyExpanded = nextKeys.filter((k) => !prevKeys.includes(k))\n if (newlyExpanded.length > 0) {\n // Keep only the most recently expanded row\n return { [newlyExpanded[newlyExpanded.length - 1]]: true } as ExpandedState\n }\n // If no new rows, means a row was collapsed — return as-is\n return next\n })\n },\n [singleExpand],\n )\n\n // Stable ref for server pagination callback to avoid useCallback invalidation\n const onPageChangeRef = useRef(serverPagination?.onPageChange)\n useEffect(() => {\n onPageChangeRef.current = serverPagination?.onPageChange\n }, [serverPagination?.onPageChange])\n\n // Server-side pagination handler\n const handlePaginationChange = useCallback(\n (updater: Updater<PaginationState>) => {\n setPaginationState((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (onPageChangeRef.current) {\n // Only call onPageChange if the page actually changed\n if (next.pageIndex !== prev.pageIndex) {\n onPageChangeRef.current(next.pageIndex + 1)\n }\n }\n return next\n })\n },\n [],\n )\n\n // Checkbox column prepended when selectable is enabled\n const selectColumn: ColumnDef<TData, unknown> = {\n id: '_select',\n header: ({ table: t }) => (\n <Checkbox\n size=\"sm\"\n checked={t.getIsAllPageRowsSelected()}\n indeterminate={t.getIsSomePageRowsSelected()}\n onCheckedChange={(v) => t.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all rows\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n size=\"sm\"\n checked={row.getIsSelected()}\n disabled={!row.getCanSelect()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n />\n ),\n enableSorting: false,\n enableColumnFilter: false,\n enableHiding: false,\n }\n\n // Expand toggle column\n const expandColumn: ColumnDef<TData, unknown> = {\n id: '_expand',\n header: () => null,\n cell: ({ row }) => (\n <button\n type=\"button\"\n onClick={() => row.toggleExpanded()}\n aria-label={row.getIsExpanded() ? 'Collapse row' : 'Expand row'}\n className=\"flex items-center justify-center p-ds-01 rounded-ds-sm hover:bg-surface-raised transition-colors\"\n >\n <Icon\n icon={IconChevronRight}\n size=\"sm\"\n className={cn(\n 'transition-transform duration-moderate-02',\n row.getIsExpanded() && 'rotate-90',\n )}\n />\n </button>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n enableHiding: false,\n }\n\n // Assemble all columns in order: select?, expand?, ...user columns\n const allColumns = [\n ...(selectable ? [selectColumn] : []),\n ...(expandable ? [expandColumn] : []),\n ...columns,\n ]\n\n // Determine if using server-side pagination\n const useServerPagination = !!serverPagination\n const showPagination = paginated || useServerPagination\n\n // Build state object once — sorting and filtering contribute independently\n const tableState: Partial<TableState> = {\n columnVisibility,\n columnPinning: columnPinningState,\n }\n if (sortable) tableState.sorting = sorting\n if (filterable || globalFilter) {\n tableState.columnFilters = columnFilters\n tableState.globalFilter = globalFilterValue\n }\n if (showPagination) tableState.pagination = paginationState\n if (selectable) tableState.rowSelection = rowSelection\n if (expandable) tableState.expanded = expanded\n\n // Determine server-side sort mode\n const isServerSort = sortable && !!onSort\n\n const table = useReactTable({\n data,\n columns: allColumns,\n state: tableState,\n onColumnVisibilityChange: setColumnVisibility,\n onColumnPinningChange: setColumnPinningState,\n getCoreRowModel: getCoreRowModel(),\n ...(sortable && {\n onSortingChange: isServerSort ? handleSortingChange : setSorting,\n ...(isServerSort\n ? { manualSorting: true }\n : { getSortedRowModel: getSortedRowModel() }),\n }),\n ...((filterable || globalFilter) && {\n onColumnFiltersChange: setColumnFilters,\n onGlobalFilterChange: setGlobalFilterValue,\n getFilteredRowModel: getFilteredRowModel(),\n }),\n ...(showPagination && {\n onPaginationChange: useServerPagination\n ? handlePaginationChange\n : setPaginationState,\n ...(useServerPagination\n ? {\n manualPagination: true,\n pageCount: Math.ceil(\n serverPagination!.total / serverPagination!.pageSize,\n ),\n }\n : { getPaginationRowModel: getPaginationRowModel() }),\n }),\n ...(selectable && {\n onRowSelectionChange: setRowSelection,\n enableRowSelection: selectableFilter\n ? (row: Row<TData>) => selectableFilter(row.original)\n : true,\n }),\n ...(expandable && {\n onExpandedChange: singleExpand ? handleExpandedChange : setExpanded,\n getExpandedRowModel: getExpandedRowModel(),\n }),\n ...(getRowIdProp && {\n getRowId: (row: TData) => getRowIdProp(row),\n }),\n })\n\n // Stable refs to avoid effect re-fires from inline callbacks\n const onSelectionChangeRef = useRef(onSelectionChange)\n const getRowIdRef = useRef(getRowIdProp)\n useEffect(() => {\n onSelectionChangeRef.current = onSelectionChange\n getRowIdRef.current = getRowIdProp\n }, [onSelectionChange, getRowIdProp])\n\n // Fire selection callback when row selection changes (skip when syncing from prop)\n useEffect(() => {\n if (isSyncingFromPropRef.current) {\n isSyncingFromPropRef.current = false\n return\n }\n if (!onSelectionChangeRef.current) return\n const selectedRowIds = Object.keys(rowSelection).filter((k) => rowSelection[k])\n const selected = data.filter((_, i) => {\n const id = getRowIdRef.current ? getRowIdRef.current(data[i]) : String(i)\n return selectedRowIds.includes(id)\n })\n onSelectionChangeRef.current(selected)\n }, [rowSelection, data])\n\n const cellPadding = densityPaddingMap[density]\n\n const rows = table.getRowModel().rows\n\n // Virtualizer — always called but only active when virtualRows is true\n const virtualizer = useVirtualizer({\n count: virtualRows ? rows.length : 0,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: () => virtualRowHeight,\n overscan: 10,\n })\n\n // Number of skeleton rows for loading state\n const skeletonRowCount = serverPagination?.pageSize ?? initialPageSize ?? 5\n\n // Get selected rows for bulk actions (derived from rowSelection + data, not table instance)\n const selectedRows = useMemo(() => {\n if (!bulkActions || !selectable) return []\n const selectedRowIds = Object.keys(rowSelection).filter((k) => rowSelection[k])\n return data.filter((_, i) => {\n const id = getRowIdProp ? getRowIdProp(data[i]) : String(i)\n return selectedRowIds.includes(id)\n })\n }, [bulkActions, selectable, rowSelection, data, getRowIdProp])\n\n const hasSelectedRows = selectedRows.length > 0\n\n // Total rows for pagination display\n const totalRowCount = useServerPagination\n ? serverPagination!.total\n : table.getFilteredRowModel().rows.length\n\n // Build context value for sub-components\n const contextValue = useMemo(\n () => ({\n table,\n allColumns: allColumns.map((col) => ({\n id: (col as { id?: string }).id,\n header: (col as { header?: unknown }).header,\n })),\n cellPadding,\n columnPinningState,\n sortable,\n filterable,\n editable,\n expandable,\n virtualRows,\n selectable,\n mobileView,\n editingCell,\n setEditingCell,\n onCellEdit,\n renderExpanded,\n onRowClick,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n table,\n allColumns.length,\n cellPadding,\n columnPinningState,\n sortable,\n filterable,\n editable,\n expandable,\n virtualRows,\n selectable,\n mobileView,\n editingCell,\n onCellEdit,\n renderExpanded,\n onRowClick,\n ],\n )\n\n // Virtual items for body\n const virtualItems = virtualRows ? virtualizer.getVirtualItems() : undefined\n const totalVirtualSize = virtualRows ? virtualizer.getTotalSize() : undefined\n\n // Determine if we need a scroll wrapper for virtualization\n const tableContent = (\n <Table aria-busy={loading || undefined}>\n <DataTableHeader stickyHeader={stickyHeader} />\n <DataTableBody\n loading={loading}\n skeletonRowCount={skeletonRowCount}\n noResultsText={noResultsText}\n emptyState={emptyState}\n virtualItems={virtualItems}\n totalVirtualSize={totalVirtualSize}\n />\n </Table>\n )\n\n return (\n <DataTableProvider value={contextValue}>\n <div className={cn(className)}>\n {/* Toolbar */}\n {toolbar && (\n <DataTableToolbar\n table={table}\n globalFilter={globalFilter}\n globalFilterValue={globalFilterValue}\n onGlobalFilterChange={setGlobalFilterValue}\n density={density}\n onDensityChange={setDensity}\n />\n )}\n\n {/* Global search input — only show standalone when toolbar is disabled */}\n {globalFilter && !toolbar && (\n <div className=\"flex items-center gap-ds-03 pb-ds-04 border-b border-surface-border mb-ds-04\">\n <Icon icon={IconSearch} size=\"sm\" className=\"text-surface-fg-subtle\" />\n <input\n type=\"text\"\n value={globalFilterValue}\n onChange={(e) => setGlobalFilterValue(e.target.value)}\n placeholder=\"Search all columns...\"\n aria-label=\"Search all columns\"\n className={cn(\n 'flex-1 bg-transparent text-ds-md',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden',\n )}\n />\n </div>\n )}\n\n {/* Card view on small screens, or standard table */}\n {showCards ? (\n <DataTableCards\n loading={loading}\n skeletonRowCount={skeletonRowCount}\n noResultsText={noResultsText}\n emptyState={emptyState}\n />\n ) : virtualRows ? (\n <div\n ref={scrollContainerRef}\n style={{ maxHeight: `${maxHeight}px`, overflowY: 'auto' }}\n >\n {tableContent}\n </div>\n ) : (\n tableContent\n )}\n\n {/* Pagination controls */}\n {showPagination && (\n <DataTablePagination\n table={table}\n totalRowCount={totalRowCount}\n useServerPagination={useServerPagination}\n pageSizeOptions={pageSizeOptions}\n />\n )}\n\n {/* Bulk action bar */}\n {bulkActions && selectable && hasSelectedRows && (\n <DataTableBulkActions\n table={table}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n />\n )}\n </div>\n </DataTableProvider>\n )\n}\nDataTable.displayName = 'DataTable'\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devalok-grain.js","names":[],"sources":["../../src/ui/devalok-grain.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion, useReducedMotion } from 'framer-motion'\n\nconst NOISE_SVG = `url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.45' numOctaves='3' seed='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E\")`\n\nexport type GrainIntensity = 'subtle' | 'medium' | 'heavy'\n\nconst NOISE_OPACITY = {\n subtle: { solid: 0.20, soft: 0.15 },\n medium: { solid: 0.28, soft: 0.22 },\n heavy: { solid: 0.45, soft: 0.35 },\n} as const\n\nconst GRADIENT = {\n subtle: { ld: 0.06, ll: 0.08, dk: 0.08 },\n medium: { ld: 0.10, ll: 0.12, dk: 0.12 },\n heavy: { ld: 0.16, ll: 0.18, dk: 0.18 },\n} as const\n\nexport interface DevalokGrainProps {\n /** Grain intensity level. Default: 'subtle' */\n intensity?: GrainIntensity\n /**\n * Surface type hint — affects noise opacity.\n * 'solid' for filled backgrounds (higher opacity).\n * 'soft' for tinted/muted backgrounds (lower opacity).\n * Default: 'solid'\n */\n surface?: 'solid' | 'soft'\n /**\n * Add an inner highlight (top-lit emboss) for a premium 3D feel.\n * Adds an inset shadow: light highlight on top edge, dark shadow on bottom edge.\n * Works best on solid variant buttons. Default: false\n */\n sheen?: boolean\n /**\n * Animate the grain entrance (fade in on mount). Default: false\n * When true, the grain fades in over 600ms with a slight scale for a natural reveal.\n */\n animated?: boolean\n /**\n * Increase grain visibility on parent hover. Default: false\n * When the parent element is hovered, the noise opacity increases by ~40%\n * and the gradient deepens slightly, creating a tactile \"pressing into paper\" feel.\n * Requires the parent to have a `group` class for `group-hover:` to work.\n */\n hoverIntensify?: boolean\n /**\n * Tint color for the directional gradient. Accepts any CSS color value.\n * The gradient goes from a darker shade of this color to a lighter shade.\n * Default: neutral black-to-white wash.\n *\n * @example\n * // Warm pink tint (Devalok brand)\n * <DevalokGrain tint=\"oklch(0.55 0.19 360)\" />\n *\n * // Cool blue tint\n * <DevalokGrain tint=\"oklch(0.55 0.12 240)\" />\n *\n * // Use a CSS variable\n * <DevalokGrain tint=\"var(--color-accent-9)\" />\n */\n tint?: string\n}\n\n/**\n * DevalokGrain — Brand texture that adds a subtle noise grain + directional gradient\n * to any surface. The Devalok signature: warm, tactile, paper-like.\n *\n * Drop as a child of any element that has `relative overflow-hidden isolate`.\n * The grain layers are absolute-positioned at z-[1] and use `rounded-[inherit]`\n * to match the parent's border-radius.\n *\n * @example\n * // Inside a Button (Button already has relative/overflow-hidden/isolate):\n * <Button>\n * <DevalokGrain />\n * Save changes\n * </Button>\n *\n * @example\n * // Inside a Card:\n * <Card className=\"relative overflow-hidden isolate\">\n * <DevalokGrain surface=\"soft\" />\n * Card content\n * </Card>\n *\n * @example\n * // Heavier grain for a hero section:\n * <div className=\"relative overflow-hidden isolate rounded-ds-lg bg-accent-9 p-8\">\n * <DevalokGrain intensity=\"heavy\" />\n * <h1 className=\"relative z-[2]\">Hero</h1>\n * </div>\n */\nexport function DevalokGrain({\n intensity = 'subtle',\n surface = 'solid',\n sheen = false,\n tint,\n animated = false,\n hoverIntensify = false,\n}: DevalokGrainProps) {\n const prefersReduced = useReducedMotion()\n const noise = NOISE_OPACITY[intensity][surface]\n const hoverNoise = Math.min(noise * 1.4, 0.6) // 40% more on hover, capped\n const g = GRADIENT[intensity]\n\n // Gradient adds directional dimensionality — a subtle diagonal wash that makes the\n // surface feel lit from the top-left. When tinted, the gradient carries the tint color.\n // When untinted, a neutral black→white wash still adds depth without coloring the surface.\n const lightGradient = tint\n ? `linear-gradient(135deg, color-mix(in oklch, ${tint} ${Math.round(g.ld * 100)}%, transparent), color-mix(in oklch, white ${Math.round(g.ll * 100)}%, transparent))`\n : `linear-gradient(135deg, oklch(0 0 0 / ${g.ld}), oklch(1 0 0 / ${g.ll}))`\n const darkGradient = tint\n ? `linear-gradient(135deg, transparent, color-mix(in oklch, ${tint} ${Math.round(g.dk * 100)}%, transparent))`\n : `linear-gradient(135deg, transparent, oklch(0 0 0 / ${g.dk}))`\n\n const shouldAnimate = animated && !prefersReduced\n\n const Wrapper = shouldAnimate ? motion.span : 'span'\n const wrapperProps = shouldAnimate\n ? {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n transition: { duration: 0.6, ease: [0.2, 0, 0.38, 0.9] },\n }\n : {}\n\n return (\n <Wrapper\n data-grain=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-[1] rounded-[inherit] isolate overflow-hidden\"\n {...(wrapperProps as any)}\n >\n {/* Gradient — only when tinted (neutral gradient looks like a dark smudge on light surfaces) */}\n {lightGradient && (\n <span\n className={`absolute inset-0 dark:hidden transition-opacity duration-300 ${\n hoverIntensify ? 'group-hover:opacity-100 opacity-80' : ''\n }`}\n style={{ background: lightGradient }}\n />\n )}\n {darkGradient && (\n <span\n className={`absolute inset-0 hidden dark:block transition-opacity duration-300 ${\n hoverIntensify ? 'group-hover:opacity-100 opacity-80' : ''\n }`}\n style={{ background: darkGradient }}\n />\n )}\n {/* Noise texture */}\n <span\n className={`absolute inset-0 transition-opacity duration-300 ${\n hoverIntensify ? 'group-hover:opacity-[var(--grain-hover-opacity)]' : ''\n }`}\n style={{\n backgroundImage: NOISE_SVG,\n backgroundSize: '100px 100px',\n filter: 'contrast(250%) brightness(105%)',\n opacity: noise,\n '--grain-hover-opacity': hoverIntensify ? hoverNoise : undefined,\n } as React.CSSProperties}\n />\n {/* Sheen — inner highlight */}\n {sheen && (\n <span className=\"absolute inset-0 shadow-raised-inner\" />\n )}\n </Wrapper>\n )\n}\n\nDevalokGrain.displayName = 'DevalokGrain'\n"],"mappings":";;;;;AAKA,IAAM,IAAY,+SAIZ,IAAgB;CACpB,QAAQ;EAAE,OAAO;EAAM,MAAM;EAAM;CACnC,QAAQ;EAAE,OAAO;EAAM,MAAM;EAAM;CACnC,OAAQ;EAAE,OAAO;EAAM,MAAM;EAAM;CACpC,EAEK,IAAW;CACf,QAAQ;EAAE,IAAI;EAAM,IAAI;EAAM,IAAI;EAAM;CACxC,QAAQ;EAAE,IAAI;EAAM,IAAI;EAAM,IAAI;EAAM;CACxC,OAAQ;EAAE,IAAI;EAAM,IAAI;EAAM,IAAI;EAAM;CACzC;AA6ED,SAAgB,EAAa,EAC3B,eAAY,UACZ,aAAU,SACV,WAAQ,IACR,SACA,cAAW,IACX,oBAAiB,MACG;CACpB,IAAM,IAAiB,GAAkB,EACnC,IAAQ,EAAc,GAAW,IACjC,IAAa,KAAK,IAAI,IAAQ,KAAK,GAAI,EACvC,IAAI,EAAS,IAKb,IAAgB,IAClB,+CAA+C,EAAK,GAAG,KAAK,MAAM,EAAE,KAAK,IAAI,CAAC,6CAA6C,KAAK,MAAM,EAAE,KAAK,IAAI,CAAC,oBAClJ,yCAAyC,EAAE,GAAG,mBAAmB,EAAE,GAAG,KACpE,IAAe,IACjB,4DAA4D,EAAK,GAAG,KAAK,MAAM,EAAE,KAAK,IAAI,CAAC,oBAC3F,sDAAsD,EAAE,GAAG,KAEzD,IAAgB,KAAY,CAAC;AAWnC,QACE,kBAVc,IAAgB,EAAO,OAAO,QAU5C;EACE,cAAW;EACX,eAAY;EACZ,WAAU;EACV,GAbiB,IACjB;GACE,SAAS,EAAE,SAAS,GAAG;GACvB,SAAS,EAAE,SAAS,GAAG;GACvB,YAAY;IAAE,UAAU;IAAK,MAAM;KAAC;KAAK;KAAG;KAAM;KAAI;IAAE;GACzD,GACD,EAAE;YAGJ;GAOG,KACC,kBAAC,QAAD;IACE,WAAW,gEACT,IAAiB,uCAAuC;IAE1D,OAAO,EAAE,YAAY,GAAe;IACpC,CAAA;GAEH,KACC,kBAAC,QAAD;IACE,WAAW,sEACT,IAAiB,uCAAuC;IAE1D,OAAO,EAAE,YAAY,GAAc;IACnC,CAAA;GAGJ,kBAAC,QAAD;IACE,WAAW,oDACT,IAAiB,qDAAqD;IAExE,OAAO;KACL,iBAAiB;KACjB,gBAAgB;KAChB,QAAQ;KACR,SAAS;KACT,yBAAyB,IAAiB,IAAa,KAAA;KACxD;IACD,CAAA;GAED,KACC,kBAAC,QAAD,EAAM,WAAU,wCAAyC,CAAA;GAEnD;;;AAId,EAAa,cAAc"}
|
package/dist/ui/dialog.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { An as e, Dn as t, En as n, Mn as r, Nn as i, On as a, jn as o, kn as s } from "../_chunks/primitives.js";
|
|
3
3
|
import { a as c, c as l } from "../_chunks/framer.js";
|
|
4
4
|
import { springs as u, tweens as d } from "./lib/motion.js";
|
|
5
5
|
import { cn as f } from "./lib/utils.js";
|
|
@@ -9,30 +9,30 @@ import * as h from "react";
|
|
|
9
9
|
import { jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
10
10
|
import { IconX as v } from "@tabler/icons-react";
|
|
11
11
|
//#region src/ui/dialog.tsx
|
|
12
|
-
var y = h.createContext({ open: !1 }), b = () => h.useContext(y), x = ({ open: e, defaultOpen: t, onOpenChange:
|
|
13
|
-
let [
|
|
14
|
-
s ||
|
|
15
|
-
}, [s,
|
|
12
|
+
var y = h.createContext({ open: !1 }), b = () => h.useContext(y), x = ({ open: e, defaultOpen: t, onOpenChange: n, ...r }) => {
|
|
13
|
+
let [i, a] = h.useState(t ?? !1), s = e !== void 0, c = s ? e : i, l = h.useCallback((e) => {
|
|
14
|
+
s || a(e), n?.(e);
|
|
15
|
+
}, [s, n]), u = h.useMemo(() => ({ open: c }), [c]);
|
|
16
16
|
return /* @__PURE__ */ g(y.Provider, {
|
|
17
17
|
value: u,
|
|
18
|
-
children: /* @__PURE__ */ g(
|
|
18
|
+
children: /* @__PURE__ */ g(o, {
|
|
19
19
|
open: c,
|
|
20
20
|
onOpenChange: l,
|
|
21
|
-
...
|
|
21
|
+
...r
|
|
22
22
|
})
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
x.displayName = "Dialog";
|
|
26
|
-
var S =
|
|
26
|
+
var S = i, C = e, w = n, T = h.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ g(s, {
|
|
27
27
|
ref: n,
|
|
28
28
|
forceMount: !0,
|
|
29
29
|
className: f("fixed inset-0 z-overlay bg-overlay", e),
|
|
30
30
|
...t
|
|
31
31
|
}));
|
|
32
|
-
T.displayName =
|
|
33
|
-
var E = h.forwardRef(({ className: e, children:
|
|
34
|
-
let { open:
|
|
35
|
-
return /* @__PURE__ */ g(l, { children:
|
|
32
|
+
T.displayName = s.displayName;
|
|
33
|
+
var E = h.forwardRef(({ className: e, children: r, responsive: i, ...a }, o) => {
|
|
34
|
+
let { open: s } = b(), h = m(), y = i !== !1 && h;
|
|
35
|
+
return /* @__PURE__ */ g(l, { children: s && /* @__PURE__ */ _(C, {
|
|
36
36
|
forceMount: !0,
|
|
37
37
|
children: [/* @__PURE__ */ g(T, {
|
|
38
38
|
asChild: !0,
|
|
@@ -42,11 +42,11 @@ var E = h.forwardRef(({ className: e, children: t, responsive: n, ...r }, a) =>
|
|
|
42
42
|
exit: { opacity: 0 },
|
|
43
43
|
transition: d.fade
|
|
44
44
|
})
|
|
45
|
-
}), /* @__PURE__ */ g(
|
|
46
|
-
ref:
|
|
45
|
+
}), /* @__PURE__ */ g(t, {
|
|
46
|
+
ref: o,
|
|
47
47
|
forceMount: !0,
|
|
48
48
|
asChild: !0,
|
|
49
|
-
...
|
|
49
|
+
...a,
|
|
50
50
|
children: /* @__PURE__ */ _(c.div, {
|
|
51
51
|
initial: y ? { y: "100%" } : {
|
|
52
52
|
opacity: 0,
|
|
@@ -66,16 +66,12 @@ var E = h.forwardRef(({ className: e, children: t, responsive: n, ...r }, a) =>
|
|
|
66
66
|
x: "-50%",
|
|
67
67
|
y: "-50%"
|
|
68
68
|
},
|
|
69
|
-
transition: y ? {
|
|
70
|
-
type: "spring",
|
|
71
|
-
damping: 30,
|
|
72
|
-
stiffness: 300
|
|
73
|
-
} : {
|
|
69
|
+
transition: y ? u.smooth : {
|
|
74
70
|
...u.smooth,
|
|
75
71
|
opacity: d.fade
|
|
76
72
|
},
|
|
77
|
-
className: f("fixed z-modal grid w-full gap-ds-05 bg-surface-overlay p-ds-06",
|
|
78
|
-
children: [
|
|
73
|
+
className: f("fixed z-modal grid w-full gap-ds-05 bg-surface-overlay p-ds-06", i === !1 ? "left-[50%] top-[50%] max-w-lg rounded-ds-xl border border-surface-border-strong shadow-overlay" : "inset-0 md:inset-auto md:left-[50%] md:top-[50%] md:max-w-lg md:rounded-ds-xl md:border md:border-surface-border-strong md:shadow-overlay", e),
|
|
74
|
+
children: [r, /* @__PURE__ */ _(n, {
|
|
79
75
|
title: "Close",
|
|
80
76
|
className: "absolute right-ds-05 top-ds-05 min-h-ds-xs min-w-ds-xs flex items-center justify-center rounded-ds-sm text-surface-fg-subtle transition-colors duration-fast-01 ease-productive-standard hover:text-surface-fg-muted hover:bg-surface-raised-hover active:scale-90 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 disabled:pointer-events-none",
|
|
81
77
|
children: [/* @__PURE__ */ g(p, {
|
|
@@ -90,11 +86,11 @@ var E = h.forwardRef(({ className: e, children: t, responsive: n, ...r }, a) =>
|
|
|
90
86
|
})]
|
|
91
87
|
}) });
|
|
92
88
|
});
|
|
93
|
-
E.displayName =
|
|
94
|
-
var D = h.forwardRef(({ className: e, ...
|
|
95
|
-
ref:
|
|
89
|
+
E.displayName = t.displayName;
|
|
90
|
+
var D = h.forwardRef(({ className: e, ...n }, r) => /* @__PURE__ */ g(t, {
|
|
91
|
+
ref: r,
|
|
96
92
|
className: f(e),
|
|
97
|
-
...
|
|
93
|
+
...n
|
|
98
94
|
}));
|
|
99
95
|
D.displayName = "DialogContentRaw";
|
|
100
96
|
var O = h.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ g("div", {
|
|
@@ -109,17 +105,17 @@ var k = h.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ g("div", {
|
|
|
109
105
|
...t
|
|
110
106
|
}));
|
|
111
107
|
k.displayName = "DialogFooter";
|
|
112
|
-
var A = h.forwardRef(({ className: e, ...
|
|
113
|
-
ref:
|
|
108
|
+
var A = h.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ g(r, {
|
|
109
|
+
ref: n,
|
|
114
110
|
className: f("text-ds-lg font-semibold", e),
|
|
115
|
-
...
|
|
111
|
+
...t
|
|
116
112
|
}));
|
|
117
|
-
A.displayName =
|
|
118
|
-
var j = h.forwardRef(({ className:
|
|
119
|
-
ref:
|
|
120
|
-
className: f("text-ds-md text-surface-fg-muted",
|
|
121
|
-
...
|
|
113
|
+
A.displayName = r.displayName;
|
|
114
|
+
var j = h.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ g(a, {
|
|
115
|
+
ref: n,
|
|
116
|
+
className: f("text-ds-md text-surface-fg-muted", e),
|
|
117
|
+
...t
|
|
122
118
|
}));
|
|
123
|
-
j.displayName =
|
|
119
|
+
j.displayName = a.displayName;
|
|
124
120
|
//#endregion
|
|
125
121
|
export { x as Dialog, w as DialogClose, E as DialogContent, D as DialogContentRaw, j as DialogDescription, k as DialogFooter, O as DialogHeader, T as DialogOverlay, C as DialogPortal, A as DialogTitle, S as DialogTrigger };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.js","names":[],"sources":["../../src/ui/dialog.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as DialogPrimitive from '@primitives/react-dialog'\nimport { IconX as CloseIcon } from '@tabler/icons-react'\nimport { motion, AnimatePresence } from 'framer-motion'\n\nimport { cn } from './lib/utils'\nimport { springs, tweens } from './lib/motion'\nimport { Icon } from './icon'\nimport { useIsMobile } from '../hooks/use-mobile'\n\n// ── Internal context to thread `open` state to animated children ──\n\ntype DialogContextValue = { open: boolean }\nconst DialogContext = React.createContext<DialogContextValue>({ open: false })\nconst useDialogOpen = () => React.useContext(DialogContext)\n\n/**\n * Dialog compound component — accessible modal overlay with focus trap and Escape dismissal.\n *\n * **Parts (in composition order):**\n * - `Dialog` — manages open/closed state (this root)\n * - `DialogTrigger` — element that opens the dialog (use `asChild` to render your own button)\n * - `DialogContent` — the modal panel (auto-includes portal, overlay, and close button)\n * - `DialogHeader` — optional layout wrapper for title + description\n * - `DialogTitle` — required for accessibility (sets the dialog's ARIA label)\n * - `DialogDescription` — optional subtitle text\n * - `DialogFooter` — optional layout wrapper for action buttons\n * - `DialogClose` — manual close trigger (a close button is already built into DialogContent)\n * - `DialogContentRaw` — use instead of DialogContent when you need full portal/overlay control\n * - `DialogPortal` — low-level portal wrapper (exported for custom layout; used internally by DialogContent)\n * - `DialogOverlay` — the backdrop element (exported for custom overlay styling or positioning)\n *\n * @compound\n * @example\n * // Confirmation dialog:\n * <Dialog>\n * <DialogTrigger asChild>\n * <Button variant=\"solid\" color=\"error\">Delete project</Button>\n * </DialogTrigger>\n * <DialogContent>\n * <DialogHeader>\n * <DialogTitle>Are you absolutely sure?</DialogTitle>\n * <DialogDescription>\n * This action cannot be undone. This will permanently delete your project.\n * </DialogDescription>\n * </DialogHeader>\n * <DialogFooter>\n * <DialogClose asChild><Button variant=\"outline\">Cancel</Button></DialogClose>\n * <Button variant=\"solid\" color=\"error\" onClick={handleDelete}>Delete</Button>\n * </DialogFooter>\n * </DialogContent>\n * </Dialog>\n *\n * @example\n * // Controlled open state (no trigger in markup):\n * const [open, setOpen] = useState(false)\n * <Dialog open={open} onOpenChange={setOpen}>\n * <DialogContent>\n * <DialogTitle>Edit profile</DialogTitle>\n * // form fields\n * </DialogContent>\n * </Dialog>\n */\nconst Dialog: React.FC<React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>> = ({\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}) => {\n // Track internal open state for uncontrolled usage\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const isControlled = openProp !== undefined\n const open = isControlled ? openProp : internalOpen\n\n const handleOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n if (!isControlled) setInternalOpen(nextOpen)\n onOpenChange?.(nextOpen)\n },\n [isControlled, onOpenChange],\n )\n\n const contextValue = React.useMemo(() => ({ open }), [open])\n\n return (\n <DialogContext.Provider value={contextValue}>\n <DialogPrimitive.Root open={open} onOpenChange={handleOpenChange} {...props} />\n </DialogContext.Provider>\n )\n}\nDialog.displayName = 'Dialog'\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = DialogPrimitive.Portal\n\nconst DialogClose = DialogPrimitive.Close\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n forceMount\n className={cn(\n 'fixed inset-0 z-overlay bg-overlay',\n className,\n )}\n {...props}\n />\n))\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\ninterface DialogContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {\n /** When true (default), Dialog fills the screen on mobile (<768px). Set false to always use centered modal. */\n responsive?: boolean\n}\n\nconst DialogContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n DialogContentProps\n>(({ className, children, responsive, ...props }, ref) => {\n const { open } = useDialogOpen()\n const isMobileRaw = useIsMobile()\n const isMobile = responsive !== false && isMobileRaw\n\n return (\n <AnimatePresence>\n {open && (\n <DialogPortal forceMount>\n <DialogOverlay asChild>\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={tweens.fade}\n />\n </DialogOverlay>\n <DialogPrimitive.Content\n ref={ref}\n forceMount\n asChild\n {...props}\n >\n <motion.div\n initial={isMobile ? { y: '100%' } : { opacity: 0, scale: 0.95, x: '-50%', y: '-50%' }}\n animate={isMobile ? { y: 0 } : { opacity: 1, scale: 1, x: '-50%', y: '-50%' }}\n exit={isMobile ? { y: '100%' } : { opacity: 0, scale: 0.95, x: '-50%', y: '-50%' }}\n transition={isMobile\n ? springs.smooth\n : { ...springs.smooth, opacity: tweens.fade }\n }\n className={cn(\n 'fixed z-modal grid w-full gap-ds-05 bg-surface-overlay p-ds-06',\n responsive !== false\n ? 'inset-0 md:inset-auto md:left-[50%] md:top-[50%] md:max-w-lg md:rounded-ds-xl md:border md:border-surface-border-strong md:shadow-overlay'\n : 'left-[50%] top-[50%] max-w-lg rounded-ds-xl border border-surface-border-strong shadow-overlay',\n className,\n )}\n >\n {children}\n <DialogPrimitive.Close title=\"Close\" className=\"absolute right-ds-05 top-ds-05 min-h-ds-xs min-w-ds-xs flex items-center justify-center rounded-ds-sm text-surface-fg-subtle transition-colors duration-fast-01 ease-productive-standard hover:text-surface-fg-muted hover:bg-surface-raised-hover active:scale-90 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 disabled:pointer-events-none\">\n <Icon icon={CloseIcon} size=\"lg\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </motion.div>\n </DialogPrimitive.Content>\n </DialogPortal>\n )}\n </AnimatePresence>\n )\n})\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\n/**\n * DialogContentRaw -- a minimal forwardRef wrapper around the primitive Content.\n * Unlike DialogContent, it does NOT include Portal, Overlay, or CloseButton.\n * Use this when you need full control over portal/overlay/close behaviour\n * (e.g. CommandPalette in shared/).\n */\nconst DialogContentRaw = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Content\n ref={ref}\n className={cn(className)}\n {...props}\n />\n))\nDialogContentRaw.displayName = 'DialogContentRaw'\n\nconst DialogHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col space-y-ds-02b text-center sm:text-left',\n className,\n )}\n {...props}\n />\n ),\n)\nDialogHeader.displayName = 'DialogHeader'\n\nconst DialogFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-ds-03',\n className,\n )}\n {...props}\n />\n ),\n)\nDialogFooter.displayName = 'DialogFooter'\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn(\n 'text-ds-lg font-semibold',\n className,\n )}\n {...props}\n />\n))\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-ds-md text-surface-fg-muted', className)}\n {...props}\n />\n))\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport type { DialogContentProps }\nexport type DialogTitleProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogContentRaw,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/ui/dropdown-menu.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as DropdownMenuPrimitive from '@primitives/react-dropdown-menu'\nimport { IconCheck, IconChevronRight, IconCircle } from '@tabler/icons-react'\nimport { motion, AnimatePresence } from 'framer-motion'\n\nimport { cn } from './lib/utils'\nimport { springs, tweens } from './lib/motion'\nimport { Icon } from './icon'\n\n// ── Internal contexts to thread open state ──\n\nconst DropdownMenuOpenContext = React.createContext(false)\nconst DropdownMenuSubOpenContext = React.createContext(false)\n\n/**\n * DropdownMenu compound component — accessible floating menu triggered by a button, with full\n * keyboard navigation and focus management.\n *\n * **Parts (in composition order):**\n * - `DropdownMenu` — manages open/closed state (this root)\n * - `DropdownMenuTrigger` — element that opens the menu (use `asChild` to render your own button)\n * - `DropdownMenuContent` — the floating menu panel (renders in a portal automatically)\n * - `DropdownMenuItem` — clickable menu item (use `onSelect` for actions)\n * - `DropdownMenuCheckboxItem` — item with a checkbox indicator\n * - `DropdownMenuRadioGroup` — wraps radio items for exclusive selection\n * - `DropdownMenuRadioItem` — item with a radio indicator (must be inside `DropdownMenuRadioGroup`)\n * - `DropdownMenuSub` — root for a nested submenu\n * - `DropdownMenuSubTrigger` — item that reveals a submenu on hover/focus\n * - `DropdownMenuSubContent` — the nested submenu panel\n * - `DropdownMenuLabel` — non-interactive group label (not selectable)\n * - `DropdownMenuSeparator` — horizontal divider between sections\n * - `DropdownMenuShortcut` — right-aligned keyboard shortcut hint text (display only)\n * - `DropdownMenuGroup` — semantic grouping wrapper (no visual output)\n * - `DropdownMenuPortal` — low-level portal wrapper (exported for custom positioning; used internally by DropdownMenuContent)\n *\n * @compound\n * @example\n * // Standard action menu:\n * <DropdownMenu>\n * <DropdownMenuTrigger asChild>\n * <Button variant=\"ghost\" size=\"icon\"><IconDotsVertical /></Button>\n * </DropdownMenuTrigger>\n * <DropdownMenuContent align=\"end\">\n * <DropdownMenuLabel>My account</DropdownMenuLabel>\n * <DropdownMenuSeparator />\n * <DropdownMenuItem>\n * <IconUser className=\"mr-ds-03\" />Profile\n * <DropdownMenuShortcut>⌘P</DropdownMenuShortcut>\n * </DropdownMenuItem>\n * <DropdownMenuItem>Settings</DropdownMenuItem>\n * <DropdownMenuSeparator />\n * <DropdownMenuItem className=\"text-error-11\">Sign out</DropdownMenuItem>\n * </DropdownMenuContent>\n * </DropdownMenu>\n *\n * @example\n * // Menu with checkbox items and a nested submenu:\n * <DropdownMenu>\n * <DropdownMenuTrigger asChild><Button>View options</Button></DropdownMenuTrigger>\n * <DropdownMenuContent>\n * <DropdownMenuCheckboxItem checked={showPanel} onCheckedChange={setShowPanel}>\n * Show side panel\n * </DropdownMenuCheckboxItem>\n * <DropdownMenuSeparator />\n * <DropdownMenuSub>\n * <DropdownMenuSubTrigger>More tools</DropdownMenuSubTrigger>\n * <DropdownMenuSubContent>\n * <DropdownMenuItem>Export CSV</DropdownMenuItem>\n * <DropdownMenuItem>Export PDF</DropdownMenuItem>\n * </DropdownMenuSubContent>\n * </DropdownMenuSub>\n * </DropdownMenuContent>\n * </DropdownMenu>\n */\nconst DropdownMenu: React.FC<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root>> = ({\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n ...props\n}) => {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n const isControlled = controlledOpen !== undefined\n const open = isControlled ? controlledOpen : uncontrolledOpen\n\n const handleOpenChange = React.useCallback(\n (value: boolean) => {\n if (!isControlled) setUncontrolledOpen(value)\n onOpenChange?.(value)\n },\n [isControlled, onOpenChange],\n )\n\n return (\n <DropdownMenuOpenContext.Provider value={open}>\n <DropdownMenuPrimitive.Root open={open} onOpenChange={handleOpenChange} {...props} />\n </DropdownMenuOpenContext.Provider>\n )\n}\nDropdownMenu.displayName = 'DropdownMenu'\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownMenuSub: React.FC<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Sub>> = ({\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n ...props\n}) => {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n const isControlled = controlledOpen !== undefined\n const open = isControlled ? controlledOpen : uncontrolledOpen\n\n const handleOpenChange = React.useCallback(\n (value: boolean) => {\n if (!isControlled) setUncontrolledOpen(value)\n onOpenChange?.(value)\n },\n [isControlled, onOpenChange],\n )\n\n return (\n <DropdownMenuSubOpenContext.Provider value={open}>\n <DropdownMenuPrimitive.Sub open={open} onOpenChange={handleOpenChange} {...props} />\n </DropdownMenuSubOpenContext.Provider>\n )\n}\nDropdownMenuSub.displayName = 'DropdownMenuSub'\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02b text-ds-md outline-hidden focus:bg-surface-raised data-[state=open]:bg-surface-raised [&_svg]:pointer-events-none [&_svg]:h-ico-sm [&_svg]:w-ico-sm [&_svg]:shrink-0',\n inset && 'pl-ds-07',\n className,\n )}\n {...props}\n >\n {children}\n <Icon icon={IconChevronRight} size=\"sm\" className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownMenuSubTrigger.displayName =\n DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, children, ...props }, ref) => {\n const open = React.useContext(DropdownMenuSubOpenContext)\n\n return (\n <AnimatePresence>\n {open && (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n forceMount\n asChild\n {...props}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ ...springs.snappy, opacity: tweens.fade }}\n className={cn(\n 'z-popover min-w-[8rem] overflow-hidden rounded-ds-lg border border-surface-border-strong bg-surface-overlay p-ds-02 text-surface-fg shadow-floating',\n className,\n )}\n >\n {children}\n </motion.div>\n </DropdownMenuPrimitive.SubContent>\n )}\n </AnimatePresence>\n )\n})\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, children, ...props }, ref) => {\n const open = React.useContext(DropdownMenuOpenContext)\n\n return (\n <AnimatePresence>\n {open && (\n <DropdownMenuPrimitive.Portal forceMount>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n forceMount\n asChild\n {...props}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ ...springs.snappy, opacity: tweens.fade }}\n className={cn(\n 'z-popover min-w-[8rem] rounded-ds-lg border border-surface-border-strong bg-surface-overlay p-ds-02 text-surface-fg shadow-floating',\n className,\n )}\n >\n {children}\n </motion.div>\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n )}\n </AnimatePresence>\n )\n})\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02b text-ds-md outline-hidden transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised focus:bg-surface-raised focus:text-surface-fg active:bg-surface-raised-hover data-[disabled]:pointer-events-none data-[disabled]:opacity-action-disabled [&>svg]:h-ico-sm [&>svg]:w-ico-sm [&>svg]:shrink-0',\n inset && 'pl-ds-07',\n className,\n )}\n {...props}\n />\n))\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-ds-md py-ds-02b pl-ds-07 pr-ds-03 text-ds-md outline-hidden transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised focus:bg-surface-raised focus:text-surface-fg active:bg-surface-raised-hover data-[disabled]:pointer-events-none data-[disabled]:opacity-action-disabled',\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-ds-03 flex h-ico-sm w-ico-sm items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Icon icon={IconCheck} size=\"sm\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownMenuCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-ds-md py-ds-02b pl-ds-07 pr-ds-03 text-ds-md outline-hidden transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised focus:bg-surface-raised focus:text-surface-fg active:bg-surface-raised-hover data-[disabled]:pointer-events-none data-[disabled]:opacity-action-disabled',\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-ds-03 flex h-ico-sm w-ico-sm items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <IconCircle className=\"h-2 w-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n))\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n 'px-ds-03 py-ds-02b text-ds-md font-semibold',\n inset && 'pl-ds-07',\n className,\n )}\n {...props}\n />\n))\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-ds-01 my-ds-02 h-px bg-surface-border', className)}\n {...props}\n />\n))\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn('ml-auto text-ds-sm text-surface-fg-subtle', className)}\n {...props}\n />\n )\n}\nDropdownMenuShortcut.displayName = 'DropdownMenuShortcut'\n\nexport type DropdownMenuContentProps = React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\nexport type DropdownMenuItemProps = React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n}\n"],"mappings":";;;;;;;;;;AAaA,IAAM,IAA0B,EAAM,cAAc,GAAM,EACpD,IAA6B,EAAM,cAAc,GAAM,EA8DvD,KAA6F,EACjG,MAAM,GACN,iBAAc,IACd,iBACA,GAAG,QACC;CACJ,IAAM,CAAC,GAAkB,KAAuB,EAAM,SAAS,EAAY,EACrE,IAAe,MAAmB,KAAA,GAClC,IAAO,IAAe,IAAiB,GAEvC,IAAmB,EAAM,aAC5B,MAAmB;AAElB,EADK,KAAc,EAAoB,EAAM,EAC7C,IAAe,EAAM;IAEvB,CAAC,GAAc,EAAa,CAC7B;AAED,QACE,kBAAC,EAAwB,UAAzB;EAAkC,OAAO;YACvC,kBAAC,GAAD;GAAkC;GAAM,cAAc;GAAkB,GAAI;GAAS,CAAA;EACpD,CAAA;;AAGvC,EAAa,cAAc;AAE3B,IAAM,IAAsB,GAEtB,IAAoB,GAEpB,IAAqB,GAErB,KAA+F,EACnG,MAAM,GACN,iBAAc,IACd,iBACA,GAAG,QACC;CACJ,IAAM,CAAC,GAAkB,KAAuB,EAAM,SAAS,EAAY,EACrE,IAAe,MAAmB,KAAA,GAClC,IAAO,IAAe,IAAiB,GAEvC,IAAmB,EAAM,aAC5B,MAAmB;AAElB,EADK,KAAc,EAAoB,EAAM,EAC7C,IAAe,EAAM;IAEvB,CAAC,GAAc,EAAa,CAC7B;AAED,QACE,kBAAC,EAA2B,UAA5B;EAAqC,OAAO;YAC1C,kBAAC,GAAD;GAAiC;GAAM,cAAc;GAAkB,GAAI;GAAS,CAAA;EAChD,CAAA;;AAG1C,EAAgB,cAAc;AAE9B,IAAM,IAAyB,GAEzB,IAAyB,EAAM,YAKlC,EAAE,cAAW,UAAO,aAAU,GAAG,KAAS,MAC3C,kBAAC,GAAD;CACO;CACL,WAAW,EACT,gQACA,KAAS,YACT,EACD;CACD,GAAI;WAPN,CASG,GACD,kBAAC,GAAD;EAAM,MAAM;EAAkB,MAAK;EAAK,WAAU;EAAY,CAAA,CAC7B;GACnC;AACF,EAAuB,cAAA,EACY;AAEnC,IAAM,IAAyB,EAAM,YAGlC,EAAE,cAAW,aAAU,GAAG,KAAS,MAIlC,kBAAC,GAAD,EAAA,UAHW,EAAM,WAAW,EAA2B,IAKnD,kBAAC,GAAD;CACO;CACL,YAAA;CACA,SAAA;CACA,GAAI;WAEJ,kBAAC,EAAO,KAAR;EACE,SAAS;GAAE,SAAS;GAAG,OAAO;GAAM;EACpC,SAAS;GAAE,SAAS;GAAG,OAAO;GAAG;EACjC,MAAM;GAAE,SAAS;GAAG,OAAO;GAAM;EACjC,YAAY;GAAE,GAAG,EAAQ;GAAQ,SAAS,EAAO;GAAM;EACvD,WAAW,EACT,uJACA,EACD;EAEA;EACU,CAAA;CACoB,CAAA,EAErB,CAAA,CAEpB;AACF,EAAuB,cAAA,EACY;AAEnC,IAAM,IAAsB,EAAM,YAG/B,EAAE,cAAW,gBAAa,GAAG,aAAU,GAAG,KAAS,MAIlD,kBAAC,GAAD,EAAA,UAHW,EAAM,WAAW,EAAwB,IAKhD,kBAAC,GAAD;CAA8B,YAAA;WAC5B,kBAAC,GAAD;EACO;EACO;EACZ,YAAA;EACA,SAAA;EACA,GAAI;YAEJ,kBAAC,EAAO,KAAR;GACE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GACpC,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GACjC,MAAM;IAAE,SAAS;IAAG,OAAO;IAAM;GACjC,YAAY;IAAE,GAAG,EAAQ;IAAQ,SAAS,EAAO;IAAM;GACvD,WAAW,EACT,uIACA,EACD;GAEA;GACU,CAAA;EACiB,CAAA;CACH,CAAA,EAEjB,CAAA,CAEpB;AACF,EAAoB,cAAA,EAA4C;AAEhE,IAAM,IAAmB,EAAM,YAK5B,EAAE,cAAW,UAAO,GAAG,KAAS,MACjC,kBAAC,GAAD;CACO;CACL,WAAW,EACT,8ZACA,KAAS,YACT,EACD;CACD,GAAI;CACJ,CAAA,CACF;AACF,EAAiB,cAAA,EAAyC;AAE1D,IAAM,IAA2B,EAAM,YAGpC,EAAE,cAAW,aAAU,YAAS,GAAG,KAAS,MAC7C,kBAAC,GAAD;CACO;CACL,WAAW,EACT,0WACA,EACD;CACQ;CACT,GAAI;WAPN,CASE,kBAAC,QAAD;EAAM,WAAU;YACd,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;GAAM,MAAM;GAAW,MAAK;GAAO,CAAA,EACC,CAAA;EACjC,CAAA,EACN,EACkC;GACrC;AACF,EAAyB,cAAA,EACY;AAErC,IAAM,IAAwB,EAAM,YAGjC,EAAE,cAAW,aAAU,GAAG,KAAS,MACpC,kBAAC,GAAD;CACO;CACL,WAAW,EACT,0WACA,EACD;CACD,GAAI;WANN,CAQE,kBAAC,QAAD;EAAM,WAAU;YACd,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAY,WAAU,wBAAyB,CAAA,EACX,CAAA;EACjC,CAAA,EACN,EAC+B;GAClC;AACF,EAAsB,cAAA,EAA8C;AAEpE,IAAM,IAAoB,EAAM,YAK7B,EAAE,cAAW,UAAO,GAAG,KAAS,MACjC,kBAAC,GAAD;CACO;CACL,WAAW,EACT,+CACA,KAAS,YACT,EACD;CACD,GAAI;CACJ,CAAA,CACF;AACF,EAAkB,cAAA,EAA0C;AAE5D,IAAM,IAAwB,EAAM,YAGjC,EAAE,cAAW,GAAG,KAAS,MAC1B,kBAAC,GAAD;CACO;CACL,WAAW,EAAG,6CAA6C,EAAU;CACrE,GAAI;CACJ,CAAA,CACF;AACF,EAAsB,cAAA,EAA8C;AAEpE,IAAM,KAAwB,EAC5B,cACA,GAAG,QAGD,kBAAC,QAAD;CACE,WAAW,EAAG,6CAA6C,EAAU;CACrE,GAAI;CACJ,CAAA;AAGN,EAAqB,cAAc"}
|