@devalok/shilp-sutra 0.36.0 → 0.37.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +346 -0
- package/README.md +26 -29
- package/dist/_chunks/badge-group.js +42 -42
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/chat.js +324 -327
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/date-picker.js +245 -245
- package/dist/_chunks/date-picker.js.map +1 -1
- package/dist/_chunks/document-preview.js +33 -33
- package/dist/_chunks/document-preview.js.map +1 -1
- package/dist/_chunks/file-preview.js +264 -264
- package/dist/_chunks/file-preview.js.map +1 -1
- package/dist/_chunks/image-preview.js +45 -45
- package/dist/_chunks/image-preview.js.map +1 -1
- package/dist/_chunks/mention-suggestion.js +85 -85
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/motion-provider.js +13 -13
- package/dist/_chunks/motion-provider.js.map +1 -1
- package/dist/_chunks/popover.js +36 -36
- package/dist/_chunks/popover.js.map +1 -1
- package/dist/_chunks/primitives.js +489 -489
- package/dist/_chunks/primitives.js.map +1 -1
- package/dist/_chunks/rich-chat-input.js +1066 -1066
- package/dist/_chunks/rich-chat-input.js.map +1 -1
- package/dist/_chunks/shared.js +43 -43
- package/dist/_chunks/shared.js.map +1 -1
- package/dist/_chunks/text.js +432 -0
- package/dist/_chunks/text.js.map +1 -0
- package/dist/_chunks/tiptap.js +6053 -6187
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tree-view.js +97 -97
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/_chunks/use-calendar.js.map +1 -1
- package/dist/ai/ai-command-provider.d.ts.map +1 -1
- package/dist/ai/ai-command-provider.js.map +1 -1
- package/dist/ai/block-renderer.d.ts.map +1 -1
- package/dist/ai/block-renderer.js +43 -43
- package/dist/ai/block-renderer.js.map +1 -1
- package/dist/ai/blocks/block-table.d.ts.map +1 -1
- package/dist/ai/blocks/confirm.d.ts.map +1 -1
- package/dist/ai/blocks/divider.d.ts.map +1 -1
- package/dist/ai/blocks/error.d.ts.map +1 -1
- package/dist/ai/blocks/index.d.ts +5 -5
- package/dist/ai/blocks/index.d.ts.map +1 -1
- package/dist/ai/blocks/index.js +2 -2
- package/dist/ai/blocks/info.d.ts.map +1 -1
- package/dist/ai/blocks/loading.d.ts.map +1 -1
- package/dist/ai/blocks/stat-row.d.ts.map +1 -1
- package/dist/ai/blocks/success.d.ts.map +1 -1
- package/dist/ai/blocks/text.d.ts.map +1 -1
- package/dist/ai/command-bar.d.ts +0 -11
- package/dist/ai/command-bar.d.ts.map +1 -1
- package/dist/ai/command-bar.js +128 -128
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.d.ts +1 -1
- package/dist/ai/conversation.d.ts.map +1 -1
- package/dist/ai/conversation.js +76 -76
- package/dist/ai/conversation.js.map +1 -1
- package/dist/ai/devadoot-icon.d.ts +0 -12
- package/dist/ai/devadoot-icon.d.ts.map +1 -1
- package/dist/ai/index.d.ts +11 -11
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +44 -44
- package/dist/ai/index.js.map +1 -1
- package/dist/composed/activity-feed.d.ts.map +1 -1
- package/dist/composed/activity-feed.js +93 -93
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/avatar-group.d.ts.map +1 -1
- package/dist/composed/avatar-group.js +50 -50
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +40 -40
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.d.ts +0 -6
- package/dist/composed/command-palette.d.ts.map +1 -1
- package/dist/composed/command-palette.js +131 -131
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/confirm-dialog.d.ts.map +1 -1
- package/dist/composed/confirm-dialog.js.map +1 -1
- package/dist/composed/content-card.d.ts.map +1 -1
- package/dist/composed/content-card.js.map +1 -1
- package/dist/composed/date-picker/calendar-grid.d.ts.map +1 -1
- package/dist/composed/date-picker/date-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/date-range-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/date-time-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/index.d.ts +11 -11
- package/dist/composed/date-picker/index.d.ts.map +1 -1
- package/dist/composed/date-picker/index.js +1 -1
- package/dist/composed/date-picker/month-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/presets.d.ts.map +1 -1
- package/dist/composed/date-picker/time-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/year-picker.d.ts.map +1 -1
- package/dist/composed/deadline-indicator.d.ts.map +1 -1
- package/dist/composed/deadline-indicator.js +25 -25
- package/dist/composed/deadline-indicator.js.map +1 -1
- package/dist/composed/emoji-picker.d.ts.map +1 -1
- package/dist/composed/emoji-picker.js +37 -37
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/empty-state.d.ts.map +1 -1
- package/dist/composed/empty-state.js +21 -21
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/error-boundary.d.ts +1 -1
- package/dist/composed/error-boundary.d.ts.map +1 -1
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/extensions/emoji-node.d.ts.map +1 -1
- package/dist/composed/extensions/emoji-suggestion.d.ts.map +1 -1
- package/dist/composed/extensions/file-attachment.d.ts.map +1 -1
- package/dist/composed/extensions/mention-suggestion.d.ts +1 -1
- package/dist/composed/extensions/mention-suggestion.d.ts.map +1 -1
- package/dist/composed/extensions/slash-command.d.ts +1 -1
- package/dist/composed/extensions/slash-command.d.ts.map +1 -1
- package/dist/composed/file-preview/audio-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/document-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/embed-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/image-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/shared.d.ts.map +1 -1
- package/dist/composed/file-preview/video-preview.d.ts.map +1 -1
- package/dist/composed/file-preview.d.ts.map +1 -1
- package/dist/composed/filter-bar.d.ts +1 -1
- package/dist/composed/filter-bar.d.ts.map +1 -1
- package/dist/composed/filter-bar.js +54 -54
- package/dist/composed/filter-bar.js.map +1 -1
- package/dist/composed/form-section.d.ts.map +1 -1
- package/dist/composed/form-section.js +26 -26
- package/dist/composed/form-section.js.map +1 -1
- package/dist/composed/global-loading.d.ts.map +1 -1
- package/dist/composed/global-loading.js.map +1 -1
- package/dist/composed/index.d.ts +55 -55
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +17 -17
- package/dist/composed/inline-edit.d.ts.map +1 -1
- package/dist/composed/inline-edit.js.map +1 -1
- package/dist/composed/loading-skeleton.d.ts +1 -1
- package/dist/composed/loading-skeleton.d.ts.map +1 -1
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/markdown-viewer.d.ts.map +1 -1
- package/dist/composed/markdown-viewer.js +3 -3
- package/dist/composed/markdown-viewer.js.map +1 -1
- package/dist/composed/master-detail.d.ts.map +1 -1
- package/dist/composed/master-detail.js +42 -42
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/member-picker.d.ts.map +1 -1
- package/dist/composed/member-picker.js.map +1 -1
- package/dist/composed/multi-select-popover.d.ts.map +1 -1
- package/dist/composed/multi-select-popover.js +55 -55
- package/dist/composed/multi-select-popover.js.map +1 -1
- package/dist/composed/page-header.d.ts.map +1 -1
- package/dist/composed/page-header.js.map +1 -1
- package/dist/composed/page-skeletons.d.ts.map +1 -1
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/priority-indicator.d.ts.map +1 -1
- package/dist/composed/priority-indicator.js +34 -34
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/responsive-overlay.d.ts.map +1 -1
- package/dist/composed/responsive-overlay.js.map +1 -1
- package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/audio-player.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/audio-waveform.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/chat-toolbar.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/recording-overlay.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 +6 -6
- package/dist/composed/rich-chat-input.d.ts.map +1 -1
- package/dist/composed/rich-chat-input.js +1 -1
- package/dist/composed/rich-text-editor.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +25 -25
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/schedule-view.d.ts.map +1 -1
- package/dist/composed/schedule-view.js +53 -53
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/composed/simple-tooltip.d.ts.map +1 -1
- package/dist/composed/simple-tooltip.js.map +1 -1
- package/dist/composed/status-badge.d.ts +1 -1
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js +30 -30
- package/dist/composed/status-badge.js.map +1 -1
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/use-color-mode.js.map +1 -1
- package/dist/hooks/use-toast.d.ts +1 -1
- package/dist/hooks/use-toast.d.ts.map +1 -1
- package/dist/motion/index.d.ts +2 -2
- package/dist/motion/index.d.ts.map +1 -1
- package/dist/motion/index.js.map +1 -1
- package/dist/motion/motion-provider.d.ts +1 -1
- package/dist/motion/motion-provider.d.ts.map +1 -1
- package/dist/motion/primitives-index.d.ts +1 -1
- package/dist/motion/primitives-index.d.ts.map +1 -1
- package/dist/motion/primitives-index.js +40 -40
- package/dist/motion/primitives-index.js.map +1 -1
- package/dist/motion/primitives.d.ts +1 -1
- package/dist/motion/primitives.d.ts.map +1 -1
- package/dist/shell/app-command-palette.d.ts +0 -8
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js.map +1 -1
- package/dist/shell/bottom-navbar.d.ts +0 -6
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +62 -62
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/index.d.ts +8 -8
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +5 -5
- package/dist/shell/link-context.d.ts +1 -1
- package/dist/shell/link-context.d.ts.map +1 -1
- package/dist/shell/notification-center.d.ts +0 -6
- package/dist/shell/notification-center.d.ts.map +1 -1
- package/dist/shell/notification-center.js +54 -54
- package/dist/shell/notification-center.js.map +1 -1
- package/dist/shell/notification-preferences.d.ts +0 -6
- package/dist/shell/notification-preferences.d.ts.map +1 -1
- package/dist/shell/notification-preferences.js +22 -22
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/shell/sidebar.d.ts.map +1 -1
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.d.ts +0 -6
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/tailwind/index.cjs +15 -499
- package/dist/tailwind/preset.d.ts +21 -0
- package/dist/tailwind/preset.d.ts.map +1 -1
- package/dist/tailwind/preset.js +14 -489
- package/dist/tailwind/preset.js.map +1 -1
- package/dist/tokens/animations.css +17 -0
- package/dist/tokens/base.css +26 -0
- package/dist/tokens/index.css +22 -0
- package/dist/tokens/semantic.css +436 -464
- package/dist/tokens/shilp-sutra.css +41 -0
- package/dist/tokens/typography-semantic.css +48 -41
- package/dist/tokens/utilities.css +276 -0
- package/dist/tokens/variants.css +14 -0
- package/dist/ui/accordion.d.ts +2 -2
- package/dist/ui/accordion.d.ts.map +1 -1
- package/dist/ui/accordion.js +23 -23
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/alert-dialog.d.ts +2 -2
- package/dist/ui/alert-dialog.d.ts.map +1 -1
- package/dist/ui/alert-dialog.js +37 -37
- package/dist/ui/alert-dialog.js.map +1 -1
- package/dist/ui/alert.d.ts.map +1 -1
- package/dist/ui/alert.js +36 -36
- package/dist/ui/alert.js.map +1 -1
- package/dist/ui/aspect-ratio.d.ts +1 -1
- package/dist/ui/aspect-ratio.d.ts.map +1 -1
- package/dist/ui/aspect-ratio.js.map +1 -1
- package/dist/ui/autocomplete.d.ts +1 -1
- package/dist/ui/autocomplete.d.ts.map +1 -1
- package/dist/ui/autocomplete.js +27 -27
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/avatar.d.ts +2 -2
- package/dist/ui/avatar.d.ts.map +1 -1
- package/dist/ui/avatar.js +41 -41
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/badge-group.d.ts.map +1 -1
- package/dist/ui/badge-indicator.d.ts.map +1 -1
- package/dist/ui/badge-indicator.js +10 -10
- package/dist/ui/badge-indicator.js.map +1 -1
- package/dist/ui/badge.d.ts +2 -2
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +28 -28
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/breadcrumb.d.ts +1 -1
- package/dist/ui/breadcrumb.d.ts.map +1 -1
- package/dist/ui/breadcrumb.js.map +1 -1
- package/dist/ui/button-group.d.ts.map +1 -1
- package/dist/ui/button-group.js.map +1 -1
- package/dist/ui/button-processing.d.ts.map +1 -1
- package/dist/ui/button-processing.js +15 -15
- package/dist/ui/button-processing.js.map +1 -1
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +84 -84
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.d.ts +1 -1
- package/dist/ui/card.d.ts.map +1 -1
- package/dist/ui/card.js +28 -28
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/charts/_internal/axes.d.ts +1 -1
- package/dist/ui/charts/_internal/axes.d.ts.map +1 -1
- package/dist/ui/charts/_internal/grid-lines.d.ts.map +1 -1
- package/dist/ui/charts/_internal/legend.d.ts.map +1 -1
- package/dist/ui/charts/_internal/tooltip.d.ts +1 -1
- package/dist/ui/charts/_internal/tooltip.d.ts.map +1 -1
- package/dist/ui/charts/area-chart.d.ts.map +1 -1
- package/dist/ui/charts/bar-chart.d.ts +1 -1
- package/dist/ui/charts/bar-chart.d.ts.map +1 -1
- package/dist/ui/charts/chart-container.d.ts.map +1 -1
- package/dist/ui/charts/gauge-chart.d.ts.map +1 -1
- package/dist/ui/charts/index.d.ts +5 -5
- package/dist/ui/charts/index.d.ts.map +1 -1
- package/dist/ui/charts/index.js +618 -618
- package/dist/ui/charts/index.js.map +1 -1
- package/dist/ui/charts/line-chart.d.ts.map +1 -1
- package/dist/ui/charts/pie-chart.d.ts.map +1 -1
- package/dist/ui/charts/radar-chart.d.ts.map +1 -1
- package/dist/ui/charts/sparkline.d.ts.map +1 -1
- package/dist/ui/chat/date-separator.d.ts.map +1 -1
- package/dist/ui/chat/index.d.ts +4 -4
- package/dist/ui/chat/index.d.ts.map +1 -1
- package/dist/ui/chat/index.js +1 -1
- package/dist/ui/chat/message-input.d.ts.map +1 -1
- package/dist/ui/chat/message-list.d.ts.map +1 -1
- package/dist/ui/chat/message.d.ts +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/chat/typing-indicator.d.ts.map +1 -1
- package/dist/ui/chat/unread-separator.d.ts.map +1 -1
- package/dist/ui/checkbox.d.ts.map +1 -1
- package/dist/ui/checkbox.js +18 -18
- package/dist/ui/checkbox.js.map +1 -1
- package/dist/ui/code.d.ts.map +1 -1
- package/dist/ui/code.js.map +1 -1
- package/dist/ui/collapsible.d.ts +2 -2
- package/dist/ui/collapsible.d.ts.map +1 -1
- package/dist/ui/collapsible.js +10 -10
- package/dist/ui/collapsible.js.map +1 -1
- package/dist/ui/color-input.d.ts.map +1 -1
- package/dist/ui/color-input.js +85 -85
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/color-swatch.d.ts.map +1 -1
- package/dist/ui/color-swatch.js.map +1 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +58 -58
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/container.d.ts.map +1 -1
- package/dist/ui/container.js.map +1 -1
- package/dist/ui/context-menu.d.ts +2 -2
- package/dist/ui/context-menu.d.ts.map +1 -1
- package/dist/ui/context-menu.js +47 -47
- package/dist/ui/context-menu.js.map +1 -1
- package/dist/ui/data-table-body.d.ts +1 -1
- package/dist/ui/data-table-body.d.ts.map +1 -1
- package/dist/ui/data-table-body.js +43 -43
- package/dist/ui/data-table-body.js.map +1 -1
- package/dist/ui/data-table-bulk-actions.js.map +1 -1
- package/dist/ui/data-table-card.d.ts.map +1 -1
- package/dist/ui/data-table-card.js +7 -7
- package/dist/ui/data-table-card.js.map +1 -1
- package/dist/ui/data-table-context.d.ts +1 -1
- package/dist/ui/data-table-context.d.ts.map +1 -1
- package/dist/ui/data-table-context.js.map +1 -1
- package/dist/ui/data-table-header.js +38 -38
- package/dist/ui/data-table-header.js.map +1 -1
- package/dist/ui/data-table-pagination.js.map +1 -1
- package/dist/ui/data-table-toolbar.d.ts.map +1 -1
- package/dist/ui/data-table-toolbar.js.map +1 -1
- package/dist/ui/data-table.d.ts +2 -2
- package/dist/ui/data-table.d.ts.map +1 -1
- package/dist/ui/data-table.js +5 -5
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/devalok-grain.js +8 -8
- package/dist/ui/devalok-grain.js.map +1 -1
- package/dist/ui/dialog.d.ts +2 -2
- package/dist/ui/dialog.d.ts.map +1 -1
- package/dist/ui/dialog.js +41 -41
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dropdown-menu.d.ts +2 -2
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +46 -46
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/file-upload.d.ts.map +1 -1
- package/dist/ui/file-upload.js +54 -54
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/form.d.ts.map +1 -1
- package/dist/ui/form.js +17 -17
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/hover-card.d.ts +2 -2
- package/dist/ui/hover-card.d.ts.map +1 -1
- package/dist/ui/hover-card.js +19 -19
- package/dist/ui/hover-card.js.map +1 -1
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/icon-group.d.ts.map +1 -1
- package/dist/ui/icon-group.js +4 -4
- package/dist/ui/icon-group.js.map +1 -1
- package/dist/ui/icon.d.ts.map +1 -1
- package/dist/ui/icon.js +32 -32
- package/dist/ui/icon.js.map +1 -1
- package/dist/ui/index.d.ts +57 -57
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +27 -27
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/input-otp.d.ts +1 -1
- package/dist/ui/input-otp.d.ts.map +1 -1
- package/dist/ui/input-otp.js.map +1 -1
- package/dist/ui/input.d.ts.map +1 -1
- package/dist/ui/input.js +14 -14
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/label.d.ts +1 -1
- package/dist/ui/label.d.ts.map +1 -1
- package/dist/ui/label.js.map +1 -1
- package/dist/ui/lib/bottom-sheet.d.ts.map +1 -1
- package/dist/ui/lib/index.d.ts +4 -4
- package/dist/ui/lib/index.d.ts.map +1 -1
- package/dist/ui/lib/slot.d.ts +1 -1
- package/dist/ui/lib/slot.d.ts.map +1 -1
- package/dist/ui/lib/utils.d.ts.map +1 -1
- package/dist/ui/lib/utils.js.map +1 -1
- package/dist/ui/link.d.ts.map +1 -1
- package/dist/ui/link.js.map +1 -1
- package/dist/ui/menubar.d.ts +2 -2
- package/dist/ui/menubar.d.ts.map +1 -1
- package/dist/ui/menubar.js +64 -64
- package/dist/ui/menubar.js.map +1 -1
- package/dist/ui/navigation-menu.d.ts +2 -2
- package/dist/ui/navigation-menu.d.ts.map +1 -1
- package/dist/ui/navigation-menu.js +72 -72
- package/dist/ui/navigation-menu.js.map +1 -1
- package/dist/ui/number-input.d.ts.map +1 -1
- package/dist/ui/number-input.js.map +1 -1
- package/dist/ui/pagination.d.ts +1 -1
- package/dist/ui/pagination.d.ts.map +1 -1
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/popover.d.ts +2 -2
- package/dist/ui/popover.d.ts.map +1 -1
- package/dist/ui/progress-ring.d.ts +1 -1
- package/dist/ui/progress-ring.d.ts.map +1 -1
- package/dist/ui/progress-ring.js +33 -33
- package/dist/ui/progress-ring.js.map +1 -1
- package/dist/ui/progress.d.ts +2 -2
- package/dist/ui/progress.d.ts.map +1 -1
- package/dist/ui/progress.js +23 -23
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/radio.d.ts.map +1 -1
- package/dist/ui/radio.js +19 -19
- package/dist/ui/radio.js.map +1 -1
- package/dist/ui/search-input.d.ts.map +1 -1
- package/dist/ui/search-input.js +17 -17
- package/dist/ui/search-input.js.map +1 -1
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +19 -19
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/select.d.ts +2 -2
- package/dist/ui/select.d.ts.map +1 -1
- package/dist/ui/select.js +68 -68
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/separator.d.ts +1 -1
- package/dist/ui/separator.d.ts.map +1 -1
- package/dist/ui/separator.js.map +1 -1
- package/dist/ui/sheet.d.ts +2 -2
- package/dist/ui/sheet.d.ts.map +1 -1
- package/dist/ui/sheet.js +44 -44
- package/dist/ui/sheet.js.map +1 -1
- package/dist/ui/sidebar.d.ts +1 -1
- package/dist/ui/sidebar.d.ts.map +1 -1
- package/dist/ui/sidebar.js +156 -156
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/skeleton.d.ts +1 -1
- package/dist/ui/skeleton.d.ts.map +1 -1
- package/dist/ui/skeleton.js +2 -2
- package/dist/ui/skeleton.js.map +1 -1
- package/dist/ui/slider.d.ts +2 -2
- package/dist/ui/slider.d.ts.map +1 -1
- package/dist/ui/slider.js +5 -5
- package/dist/ui/slider.js.map +1 -1
- package/dist/ui/spinner.d.ts.map +1 -1
- package/dist/ui/spinner.js +21 -21
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/split-button.d.ts +1 -1
- package/dist/ui/split-button.d.ts.map +1 -1
- package/dist/ui/split-button.js +28 -28
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/stack.d.ts +1 -1
- package/dist/ui/stack.d.ts.map +1 -1
- package/dist/ui/stack.js.map +1 -1
- package/dist/ui/stat-card.d.ts.map +1 -1
- package/dist/ui/stat-card.js +73 -73
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/status-dot.d.ts.map +1 -1
- package/dist/ui/status-dot.js.map +1 -1
- package/dist/ui/stepper.d.ts +1 -1
- package/dist/ui/stepper.d.ts.map +1 -1
- package/dist/ui/stepper.js +48 -48
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/switch.d.ts +1 -1
- package/dist/ui/switch.d.ts.map +1 -1
- package/dist/ui/switch.js +15 -15
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/table.d.ts +1 -1
- package/dist/ui/table.d.ts.map +1 -1
- package/dist/ui/table.js.map +1 -1
- package/dist/ui/tabs.d.ts +2 -2
- package/dist/ui/tabs.d.ts.map +1 -1
- package/dist/ui/tabs.js +52 -52
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/text.d.ts +1 -1
- package/dist/ui/text.d.ts.map +1 -1
- package/dist/ui/text.js.map +1 -1
- package/dist/ui/textarea.d.ts.map +1 -1
- package/dist/ui/textarea.js +13 -13
- package/dist/ui/textarea.js.map +1 -1
- package/dist/ui/toast-registry.js.map +1 -1
- package/dist/ui/toast.d.ts +3 -3
- package/dist/ui/toast.d.ts.map +1 -1
- package/dist/ui/toast.js +164 -164
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toaster.d.ts.map +1 -1
- package/dist/ui/toaster.js +6 -6
- package/dist/ui/toaster.js.map +1 -1
- package/dist/ui/toggle-group.d.ts +1 -1
- package/dist/ui/toggle-group.d.ts.map +1 -1
- package/dist/ui/toggle-group.js.map +1 -1
- package/dist/ui/toggle.d.ts +1 -1
- package/dist/ui/toggle.d.ts.map +1 -1
- package/dist/ui/toggle.js +14 -14
- package/dist/ui/toggle.js.map +1 -1
- package/dist/ui/tooltip.d.ts +2 -2
- package/dist/ui/tooltip.d.ts.map +1 -1
- package/dist/ui/tooltip.js +26 -26
- package/dist/ui/tooltip.js.map +1 -1
- package/dist/ui/tree-view/index.d.ts +2 -2
- package/dist/ui/tree-view/index.d.ts.map +1 -1
- package/dist/ui/tree-view/index.js +1 -1
- package/dist/ui/tree-view/tree-view.d.ts +1 -1
- package/dist/ui/tree-view/tree-view.d.ts.map +1 -1
- package/dist/ui/visually-hidden.d.ts.map +1 -1
- package/dist/ui/visually-hidden.js.map +1 -1
- package/docs/components/_header.md +96 -0
- package/docs/rollback.md +179 -0
- package/llms-full.txt +97 -1
- package/llms.txt +24 -2
- package/package.json +296 -277
- package/dist/_chunks/framer.js +0 -5604
- package/dist/_chunks/framer.js.map +0 -1
- package/dist/_chunks/rolldown-runtime.js +0 -21
- package/dist/_chunks/sonner.js +0 -616
- package/dist/_chunks/sonner.js.map +0 -1
- package/dist/_chunks/stat-row.js +0 -432
- package/dist/_chunks/stat-row.js.map +0 -1
|
@@ -31,9 +31,99 @@ function l(e = {}) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
//#endregion
|
|
34
|
+
//#region src/ui/tree-view/tree-view.tsx
|
|
35
|
+
var u = r.createContext(null);
|
|
36
|
+
function d() {
|
|
37
|
+
let e = r.useContext(u);
|
|
38
|
+
if (!e) throw Error("TreeItem must be used within a <TreeView>");
|
|
39
|
+
return e;
|
|
40
|
+
}
|
|
41
|
+
function f(e, t = 0) {
|
|
42
|
+
return e.map((e) => /* @__PURE__ */ o(h, {
|
|
43
|
+
itemId: e.id,
|
|
44
|
+
label: e.label,
|
|
45
|
+
icon: e.icon,
|
|
46
|
+
disabled: e.disabled,
|
|
47
|
+
depth: t,
|
|
48
|
+
children: e.children && e.children.length > 0 ? f(e.children, t + 1) : void 0
|
|
49
|
+
}, e.id));
|
|
50
|
+
}
|
|
51
|
+
function p(e) {
|
|
52
|
+
return Array.from(e.querySelectorAll("[data-tree-item]")).filter((t) => {
|
|
53
|
+
let n = t.parentElement;
|
|
54
|
+
for (; n && n !== e;) {
|
|
55
|
+
if (n.getAttribute("role") === "group") {
|
|
56
|
+
let e = n.parentElement;
|
|
57
|
+
if (e && e.classList.contains("grid-rows-[0fr]")) return !1;
|
|
58
|
+
}
|
|
59
|
+
n = n.parentElement;
|
|
60
|
+
}
|
|
61
|
+
return !0;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
var m = r.forwardRef(({ items: t, defaultExpanded: n, defaultSelected: i, multiSelect: a = !1, checkboxes: s = !1, onSelect: c, onExpand: d, className: m, children: h, ...g }, _) => {
|
|
65
|
+
let v = l({
|
|
66
|
+
defaultExpanded: n,
|
|
67
|
+
defaultSelected: i,
|
|
68
|
+
multiSelect: a,
|
|
69
|
+
onSelect: c,
|
|
70
|
+
onExpand: d
|
|
71
|
+
}), y = r.useRef(null), b = _ ?? y, x = (e) => {
|
|
72
|
+
let t = b.current;
|
|
73
|
+
if (!t) return;
|
|
74
|
+
let n = p(t), r = n.findIndex((e) => e === document.activeElement);
|
|
75
|
+
switch (e.key) {
|
|
76
|
+
case "ArrowDown":
|
|
77
|
+
e.preventDefault(), n[r + 1]?.focus();
|
|
78
|
+
break;
|
|
79
|
+
case "ArrowUp":
|
|
80
|
+
e.preventDefault(), n[r - 1]?.focus();
|
|
81
|
+
break;
|
|
82
|
+
case "ArrowRight": {
|
|
83
|
+
let t = n[r];
|
|
84
|
+
if (t) {
|
|
85
|
+
let i = t.getAttribute("data-tree-item");
|
|
86
|
+
i && v.isExpanded(i) && (e.preventDefault(), n[r + 1]?.focus());
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case "ArrowLeft": {
|
|
91
|
+
let t = n[r];
|
|
92
|
+
if (t) {
|
|
93
|
+
let n = t.getAttribute("data-tree-item"), r = t.closest("[role=\"treeitem\"]")?.parentElement?.closest("[role=\"treeitem\"]");
|
|
94
|
+
n && !v.isExpanded(n) && r && (e.preventDefault(), r.querySelector("[data-tree-item]")?.focus());
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case "Home":
|
|
99
|
+
e.preventDefault(), n[0]?.focus();
|
|
100
|
+
break;
|
|
101
|
+
case "End":
|
|
102
|
+
e.preventDefault(), n[n.length - 1]?.focus();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}, S = r.useMemo(() => ({
|
|
106
|
+
tree: v,
|
|
107
|
+
checkboxes: s
|
|
108
|
+
}), [v, s]), C = t ? f(t) : h;
|
|
109
|
+
return /* @__PURE__ */ o(u.Provider, {
|
|
110
|
+
value: S,
|
|
111
|
+
children: /* @__PURE__ */ o("ul", {
|
|
112
|
+
ref: b,
|
|
113
|
+
role: "tree",
|
|
114
|
+
"aria-multiselectable": a || void 0,
|
|
115
|
+
onKeyDown: x,
|
|
116
|
+
className: e("m-0 list-none p-0", m),
|
|
117
|
+
...g,
|
|
118
|
+
children: C
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
m.displayName = "TreeView";
|
|
123
|
+
//#endregion
|
|
34
124
|
//#region src/ui/tree-view/tree-item.tsx
|
|
35
|
-
var
|
|
36
|
-
let v =
|
|
125
|
+
var h = r.forwardRef(({ itemId: i, label: a, icon: l, secondaryLabel: u, actions: f, disabled: p = !1, children: m, depth: h = 0, className: g }, _) => {
|
|
126
|
+
let v = d(), y = r.Children.count(m) > 0, b = v.tree.isExpanded(i), x = v.tree.isSelected(i), S = (e) => {
|
|
37
127
|
p || v.tree.select(i, e);
|
|
38
128
|
}, C = (e) => {
|
|
39
129
|
e.stopPropagation(), !p && v.tree.toggle(i);
|
|
@@ -82,7 +172,7 @@ var u = r.forwardRef(({ itemId: i, label: a, icon: l, secondaryLabel: u, actions
|
|
|
82
172
|
tabIndex: p ? -1 : 0,
|
|
83
173
|
onClick: S,
|
|
84
174
|
onKeyDown: w,
|
|
85
|
-
style: { paddingLeft: `calc(${h} * var(--spacing-05b) + var(--spacing-03))` },
|
|
175
|
+
style: { paddingLeft: `calc(${h} * var(--spacing-ds-05b) + var(--spacing-ds-03))` },
|
|
86
176
|
className: e("flex items-center gap-ds-02 py-ds-02 px-ds-02 rounded-ds-md cursor-pointer transition-colors duration-fast-01", "hover:bg-surface-raised", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9", x && "bg-accent-3 text-accent-11", p && "opacity-action-disabled cursor-not-allowed pointer-events-none", g),
|
|
87
177
|
children: [
|
|
88
178
|
y ? /* @__PURE__ */ o("button", {
|
|
@@ -123,11 +213,11 @@ var u = r.forwardRef(({ itemId: i, label: a, icon: l, secondaryLabel: u, actions
|
|
|
123
213
|
className: "ml-auto truncate text-ds-xs text-surface-fg-muted",
|
|
124
214
|
children: u
|
|
125
215
|
}),
|
|
126
|
-
|
|
216
|
+
f && /* @__PURE__ */ o("span", {
|
|
127
217
|
className: "ml-auto flex shrink-0 items-center gap-ds-01",
|
|
128
218
|
onClick: (e) => e.stopPropagation(),
|
|
129
219
|
role: "presentation",
|
|
130
|
-
children:
|
|
220
|
+
children: f
|
|
131
221
|
})
|
|
132
222
|
]
|
|
133
223
|
}), y && /* @__PURE__ */ o("div", {
|
|
@@ -141,96 +231,6 @@ var u = r.forwardRef(({ itemId: i, label: a, icon: l, secondaryLabel: u, actions
|
|
|
141
231
|
})]
|
|
142
232
|
});
|
|
143
233
|
});
|
|
144
|
-
|
|
145
|
-
//#endregion
|
|
146
|
-
//#region src/ui/tree-view/tree-view.tsx
|
|
147
|
-
var d = r.createContext(null);
|
|
148
|
-
function f() {
|
|
149
|
-
let e = r.useContext(d);
|
|
150
|
-
if (!e) throw Error("TreeItem must be used within a <TreeView>");
|
|
151
|
-
return e;
|
|
152
|
-
}
|
|
153
|
-
function p(e, t = 0) {
|
|
154
|
-
return e.map((e) => /* @__PURE__ */ o(u, {
|
|
155
|
-
itemId: e.id,
|
|
156
|
-
label: e.label,
|
|
157
|
-
icon: e.icon,
|
|
158
|
-
disabled: e.disabled,
|
|
159
|
-
depth: t,
|
|
160
|
-
children: e.children && e.children.length > 0 ? p(e.children, t + 1) : void 0
|
|
161
|
-
}, e.id));
|
|
162
|
-
}
|
|
163
|
-
function m(e) {
|
|
164
|
-
return Array.from(e.querySelectorAll("[data-tree-item]")).filter((t) => {
|
|
165
|
-
let n = t.parentElement;
|
|
166
|
-
for (; n && n !== e;) {
|
|
167
|
-
if (n.getAttribute("role") === "group") {
|
|
168
|
-
let e = n.parentElement;
|
|
169
|
-
if (e && e.classList.contains("grid-rows-[0fr]")) return !1;
|
|
170
|
-
}
|
|
171
|
-
n = n.parentElement;
|
|
172
|
-
}
|
|
173
|
-
return !0;
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
var h = r.forwardRef(({ items: t, defaultExpanded: n, defaultSelected: i, multiSelect: a = !1, checkboxes: s = !1, onSelect: c, onExpand: u, className: f, children: h, ...g }, _) => {
|
|
177
|
-
let v = l({
|
|
178
|
-
defaultExpanded: n,
|
|
179
|
-
defaultSelected: i,
|
|
180
|
-
multiSelect: a,
|
|
181
|
-
onSelect: c,
|
|
182
|
-
onExpand: u
|
|
183
|
-
}), y = r.useRef(null), b = _ ?? y, x = (e) => {
|
|
184
|
-
let t = b.current;
|
|
185
|
-
if (!t) return;
|
|
186
|
-
let n = m(t), r = n.findIndex((e) => e === document.activeElement);
|
|
187
|
-
switch (e.key) {
|
|
188
|
-
case "ArrowDown":
|
|
189
|
-
e.preventDefault(), n[r + 1]?.focus();
|
|
190
|
-
break;
|
|
191
|
-
case "ArrowUp":
|
|
192
|
-
e.preventDefault(), n[r - 1]?.focus();
|
|
193
|
-
break;
|
|
194
|
-
case "ArrowRight": {
|
|
195
|
-
let t = n[r];
|
|
196
|
-
if (t) {
|
|
197
|
-
let i = t.getAttribute("data-tree-item");
|
|
198
|
-
i && v.isExpanded(i) && (e.preventDefault(), n[r + 1]?.focus());
|
|
199
|
-
}
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
case "ArrowLeft": {
|
|
203
|
-
let t = n[r];
|
|
204
|
-
if (t) {
|
|
205
|
-
let n = t.getAttribute("data-tree-item"), r = t.closest("[role=\"treeitem\"]")?.parentElement?.closest("[role=\"treeitem\"]");
|
|
206
|
-
n && !v.isExpanded(n) && r && (e.preventDefault(), r.querySelector("[data-tree-item]")?.focus());
|
|
207
|
-
}
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
case "Home":
|
|
211
|
-
e.preventDefault(), n[0]?.focus();
|
|
212
|
-
break;
|
|
213
|
-
case "End":
|
|
214
|
-
e.preventDefault(), n[n.length - 1]?.focus();
|
|
215
|
-
break;
|
|
216
|
-
}
|
|
217
|
-
}, S = r.useMemo(() => ({
|
|
218
|
-
tree: v,
|
|
219
|
-
checkboxes: s
|
|
220
|
-
}), [v, s]), C = t ? p(t) : h;
|
|
221
|
-
return /* @__PURE__ */ o(d.Provider, {
|
|
222
|
-
value: S,
|
|
223
|
-
children: /* @__PURE__ */ o("ul", {
|
|
224
|
-
ref: b,
|
|
225
|
-
role: "tree",
|
|
226
|
-
"aria-multiselectable": a || void 0,
|
|
227
|
-
onKeyDown: x,
|
|
228
|
-
className: e("m-0 list-none p-0", f),
|
|
229
|
-
...g,
|
|
230
|
-
children: C
|
|
231
|
-
})
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
h.displayName = "TreeView";
|
|
234
|
+
h.displayName = "TreeItem";
|
|
235
235
|
//#endregion
|
|
236
|
-
export {
|
|
236
|
+
export { m as n, l as r, h as t };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view.js","names":[],"sources":["../../src/ui/tree-view/use-tree.ts","../../src/ui/tree-view/tree-item.tsx","../../src/ui/tree-view/tree-view.tsx"],"sourcesContent":["import { useState, useCallback } from 'react'\n\nexport interface TreeNode {\n id: string\n label: string\n icon?: React.ReactNode\n children?: TreeNode[]\n disabled?: boolean\n}\n\ninterface UseTreeOptions {\n defaultExpanded?: string[]\n defaultSelected?: string[]\n multiSelect?: boolean\n onSelect?: (selectedIds: string[]) => void\n onExpand?: (expandedIds: string[]) => void\n}\n\nexport function useTree(options: UseTreeOptions = {}) {\n const { defaultExpanded, defaultSelected, multiSelect, onSelect, onExpand } = options\n\n const [expanded, setExpanded] = useState<Set<string>>(\n new Set(defaultExpanded ?? []),\n )\n const [selected, setSelected] = useState<Set<string>>(\n new Set(defaultSelected ?? []),\n )\n\n const toggle = useCallback(\n (id: string) => {\n setExpanded((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n onExpand?.(Array.from(next))\n return next\n })\n },\n [onExpand],\n )\n\n const select = useCallback(\n (id: string, event?: React.MouseEvent) => {\n setSelected((prev) => {\n let next: Set<string>\n if (multiSelect && event?.ctrlKey) {\n next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n } else {\n next = new Set([id])\n }\n onSelect?.(Array.from(next))\n return next\n })\n },\n [multiSelect, onSelect],\n )\n\n return {\n expanded,\n selected,\n toggle,\n select,\n isExpanded: (id: string) => expanded.has(id),\n isSelected: (id: string) => selected.has(id),\n expandAll: (ids: string[]) => setExpanded(new Set(ids)),\n collapseAll: () => setExpanded(new Set()),\n }\n}\n","'use client'\n\nimport { IconChevronRight } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { cn } from '../lib/utils'\nimport { Icon } from '../icon'\nimport { Checkbox } from '../checkbox'\nimport { useTreeContext } from './tree-view'\n\nexport interface TreeItemProps {\n /** Unique identifier for this tree item */\n itemId: string\n /** Primary label content */\n label: React.ReactNode\n /** Optional icon rendered before the label */\n icon?: React.ReactNode\n /** Secondary label rendered after the primary label */\n secondaryLabel?: React.ReactNode\n /** Action buttons rendered at the end of the row */\n actions?: React.ReactNode\n /** Whether this item is disabled */\n disabled?: boolean\n /** Nested tree items */\n children?: React.ReactNode\n /** Depth level (used internally) */\n depth?: number\n /** Additional CSS class names */\n className?: string\n}\n\nconst TreeItem = React.forwardRef<HTMLLIElement, TreeItemProps>(\n (\n {\n itemId,\n label,\n icon,\n secondaryLabel,\n actions,\n disabled = false,\n children,\n depth = 0,\n className,\n },\n ref,\n ) => {\n const ctx = useTreeContext()\n const hasChildren = React.Children.count(children) > 0\n const isExpanded = ctx.tree.isExpanded(itemId)\n const isSelected = ctx.tree.isSelected(itemId)\n\n const handleRowClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return\n ctx.tree.select(itemId, e)\n }\n\n const handleChevronClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation()\n if (disabled) return\n ctx.tree.toggle(itemId)\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ctx.tree.select(itemId)\n }\n if (e.key === 'ArrowRight' && hasChildren && !isExpanded) {\n e.preventDefault()\n e.stopPropagation()\n ctx.tree.toggle(itemId)\n }\n if (e.key === 'ArrowLeft' && hasChildren && isExpanded) {\n e.preventDefault()\n e.stopPropagation()\n ctx.tree.toggle(itemId)\n }\n }\n\n // Compute indeterminate state for checkbox mode\n const checkboxState = React.useMemo(() => {\n if (!ctx.checkboxes || !hasChildren) {\n return { checked: isSelected, indeterminate: false }\n }\n // Collect all descendant IDs\n const descendants: string[] = []\n const collectIds = (nodes: React.ReactNode) => {\n React.Children.forEach(nodes, (child) => {\n if (React.isValidElement<TreeItemProps>(child) && child.props.itemId) {\n descendants.push(child.props.itemId)\n if (child.props.children) {\n collectIds(child.props.children)\n }\n }\n })\n }\n collectIds(children)\n const selectedCount = descendants.filter((id) =>\n ctx.tree.isSelected(id),\n ).length\n if (selectedCount === 0 && !isSelected) {\n return { checked: false, indeterminate: false }\n }\n if (selectedCount === descendants.length) {\n return { checked: true, indeterminate: false }\n }\n return { checked: false, indeterminate: true }\n }, [ctx.checkboxes, hasChildren, children, isSelected, ctx.tree])\n\n return (\n <li\n ref={ref}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={isSelected}\n aria-level={depth + 1}\n aria-disabled={disabled || undefined}\n className=\"list-none\"\n >\n {/* Row */}\n <div\n role=\"presentation\"\n data-tree-item={itemId}\n tabIndex={disabled ? -1 : 0}\n onClick={handleRowClick}\n onKeyDown={handleKeyDown}\n style={{ paddingLeft: `calc(${depth} * var(--spacing-05b) + var(--spacing-03))` }}\n className={cn(\n 'flex items-center gap-ds-02 py-ds-02 px-ds-02 rounded-ds-md cursor-pointer transition-colors duration-fast-01',\n 'hover:bg-surface-raised',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9',\n isSelected &&\n 'bg-accent-3 text-accent-11',\n disabled && 'opacity-action-disabled cursor-not-allowed pointer-events-none',\n className,\n )}\n >\n {/* Expand chevron */}\n {hasChildren ? (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n onClick={handleChevronClick}\n className=\"flex shrink-0 items-center justify-center p-0 border-0 bg-transparent cursor-pointer\"\n >\n <Icon\n icon={IconChevronRight}\n size=\"sm\"\n className={cn(\n 'transition-transform duration-moderate-02',\n isExpanded && 'rotate-90',\n )}\n />\n </button>\n ) : (\n <span className=\"inline-block w-4 shrink-0\" aria-hidden=\"true\" />\n )}\n\n {/* Checkbox (optional) */}\n {ctx.checkboxes && (\n <Checkbox\n checked={checkboxState.checked}\n indeterminate={checkboxState.indeterminate}\n disabled={disabled}\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n onCheckedChange={() => {\n if (!disabled) ctx.tree.select(itemId)\n }}\n className=\"shrink-0\"\n />\n )}\n\n {/* Icon */}\n {icon && (\n <span className=\"flex shrink-0 items-center text-surface-fg-subtle\">\n {icon}\n </span>\n )}\n\n {/* Label */}\n <span className=\"truncate text-ds-sm\">{label}</span>\n\n {/* Secondary label */}\n {secondaryLabel && (\n <span className=\"ml-auto truncate text-ds-xs text-surface-fg-muted\">\n {secondaryLabel}\n </span>\n )}\n\n {/* Actions */}\n {actions && (\n <span\n className=\"ml-auto flex shrink-0 items-center gap-ds-01\"\n onClick={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n {actions}\n </span>\n )}\n </div>\n\n {/* Children (collapsible) */}\n {hasChildren && (\n <div\n role=\"group\"\n className={cn(\n 'grid transition-[grid-template-rows] duration-moderate-02 ease-productive-standard',\n isExpanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',\n )}\n >\n <ul role=\"group\" className=\"overflow-hidden m-0 p-0\">\n {React.Children.map(children, (child) => {\n if (React.isValidElement<TreeItemProps>(child)) {\n return React.cloneElement(child, {\n depth: depth + 1,\n })\n }\n return child\n })}\n </ul>\n </div>\n )}\n </li>\n )\n },\n)\nTreeItem.displayName = 'TreeItem'\n\nexport { TreeItem }\n","'use client'\n\nimport * as React from 'react'\n\nimport { cn } from '../lib/utils'\nimport { useTree, type TreeNode } from './use-tree'\nimport { TreeItem } from './tree-item'\n\n// ─── Context ────────────────────────────────────────────────────────\ninterface TreeContextValue {\n tree: ReturnType<typeof useTree>\n checkboxes: boolean\n}\n\nconst TreeContext = React.createContext<TreeContextValue | null>(null)\n\nexport function useTreeContext() {\n const ctx = React.useContext(TreeContext)\n if (!ctx) {\n throw new Error('TreeItem must be used within a <TreeView>')\n }\n return ctx\n}\n\n// ─── Props ──────────────────────────────────────────────────────────\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLUListElement>, 'onSelect'> {\n /** Data-driven mode: pass items array */\n items?: TreeNode[]\n /** Initially expanded node IDs */\n defaultExpanded?: string[]\n /** Initially selected node IDs */\n defaultSelected?: string[]\n /** Enable multi-select */\n multiSelect?: boolean\n /** Show checkboxes before each item */\n checkboxes?: boolean\n /** Called when selection changes */\n onSelect?: (ids: string[]) => void\n /** Called when expansion changes */\n onExpand?: (ids: string[]) => void\n className?: string\n /** Declarative mode: render TreeItem children directly */\n children?: React.ReactNode\n}\n\n// ─── Render nodes recursively (data-driven mode) ───────────────────\nfunction renderNodes(nodes: TreeNode[], depth: number = 0): React.ReactNode {\n return nodes.map((node) => (\n <TreeItem\n key={node.id}\n itemId={node.id}\n label={node.label}\n icon={node.icon}\n disabled={node.disabled}\n depth={depth}\n >\n {node.children && node.children.length > 0\n ? renderNodes(node.children, depth + 1)\n : undefined}\n </TreeItem>\n ))\n}\n\n// ─── Helper: collect all visible item IDs ───────────────────────────\nfunction getVisibleItemElements(container: HTMLElement): HTMLElement[] {\n return Array.from(\n container.querySelectorAll<HTMLElement>('[data-tree-item]'),\n ).filter((el) => {\n // Items inside collapsed groups should not be focusable\n let parent = el.parentElement\n while (parent && parent !== container) {\n if (parent.getAttribute('role') === 'group') {\n const grid = parent.parentElement\n if (grid && grid.classList.contains('grid-rows-[0fr]')) {\n return false\n }\n }\n parent = parent.parentElement\n }\n return true\n })\n}\n\n// ─── Component ──────────────────────────────────────────────────────\nconst TreeView = React.forwardRef<HTMLUListElement, TreeViewProps>(\n (\n {\n items,\n defaultExpanded,\n defaultSelected,\n multiSelect = false,\n checkboxes = false,\n onSelect,\n onExpand,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const tree = useTree({\n defaultExpanded,\n defaultSelected,\n multiSelect,\n onSelect,\n onExpand,\n })\n\n const innerRef = React.useRef<HTMLUListElement>(null)\n const containerRef = (ref as React.RefObject<HTMLUListElement>) ?? innerRef\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLUListElement>) => {\n const container = containerRef.current\n if (!container) return\n\n const visibleItems = getVisibleItemElements(container)\n const currentIndex = visibleItems.findIndex(\n (el) => el === document.activeElement,\n )\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const next = visibleItems[currentIndex + 1]\n next?.focus()\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prev = visibleItems[currentIndex - 1]\n prev?.focus()\n break\n }\n case 'ArrowRight': {\n // Handled in TreeItem for expand; if already expanded, move to first child\n const current = visibleItems[currentIndex]\n if (current) {\n const itemId = current.getAttribute('data-tree-item')\n if (itemId && tree.isExpanded(itemId)) {\n e.preventDefault()\n const nextItem = visibleItems[currentIndex + 1]\n nextItem?.focus()\n }\n }\n break\n }\n case 'ArrowLeft': {\n // Handled in TreeItem for collapse; if already collapsed or leaf, move to parent\n const current = visibleItems[currentIndex]\n if (current) {\n const itemId = current.getAttribute('data-tree-item')\n const treeItem = current.closest('[role=\"treeitem\"]')\n const parentGroup = treeItem?.parentElement?.closest(\n '[role=\"treeitem\"]',\n )\n if (itemId && !tree.isExpanded(itemId) && parentGroup) {\n e.preventDefault()\n const parentRow = parentGroup.querySelector<HTMLElement>(\n '[data-tree-item]',\n )\n parentRow?.focus()\n }\n }\n break\n }\n case 'Home': {\n e.preventDefault()\n visibleItems[0]?.focus()\n break\n }\n case 'End': {\n e.preventDefault()\n visibleItems[visibleItems.length - 1]?.focus()\n break\n }\n }\n }\n\n const ctxValue = React.useMemo<TreeContextValue>(\n () => ({ tree, checkboxes }),\n [tree, checkboxes],\n )\n\n const content = items ? renderNodes(items) : children\n\n return (\n <TreeContext.Provider value={ctxValue}>\n <ul\n ref={containerRef}\n role=\"tree\"\n aria-multiselectable={multiSelect || undefined}\n onKeyDown={handleKeyDown}\n className={cn('m-0 list-none p-0', className)}\n {...props}\n >\n {content}\n </ul>\n </TreeContext.Provider>\n )\n },\n)\nTreeView.displayName = 'TreeView'\n\nexport { TreeView }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tree-view.js","names":[],"sources":["../../src/ui/tree-view/use-tree.ts","../../src/ui/tree-view/tree-view.tsx","../../src/ui/tree-view/tree-item.tsx"],"sourcesContent":["import { useCallback,useState } from 'react'\n\nexport interface TreeNode {\n id: string\n label: string\n icon?: React.ReactNode\n children?: TreeNode[]\n disabled?: boolean\n}\n\ninterface UseTreeOptions {\n defaultExpanded?: string[]\n defaultSelected?: string[]\n multiSelect?: boolean\n onSelect?: (selectedIds: string[]) => void\n onExpand?: (expandedIds: string[]) => void\n}\n\nexport function useTree(options: UseTreeOptions = {}) {\n const { defaultExpanded, defaultSelected, multiSelect, onSelect, onExpand } = options\n\n const [expanded, setExpanded] = useState<Set<string>>(\n new Set(defaultExpanded ?? []),\n )\n const [selected, setSelected] = useState<Set<string>>(\n new Set(defaultSelected ?? []),\n )\n\n const toggle = useCallback(\n (id: string) => {\n setExpanded((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n onExpand?.(Array.from(next))\n return next\n })\n },\n [onExpand],\n )\n\n const select = useCallback(\n (id: string, event?: React.MouseEvent) => {\n setSelected((prev) => {\n let next: Set<string>\n if (multiSelect && event?.ctrlKey) {\n next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n } else {\n next = new Set([id])\n }\n onSelect?.(Array.from(next))\n return next\n })\n },\n [multiSelect, onSelect],\n )\n\n return {\n expanded,\n selected,\n toggle,\n select,\n isExpanded: (id: string) => expanded.has(id),\n isSelected: (id: string) => selected.has(id),\n expandAll: (ids: string[]) => setExpanded(new Set(ids)),\n collapseAll: () => setExpanded(new Set()),\n }\n}\n","'use client'\n\nimport * as React from 'react'\n\nimport { cn } from '../lib/utils'\nimport { TreeItem } from './tree-item'\nimport { type TreeNode,useTree } from './use-tree'\n\n// ─── Context ────────────────────────────────────────────────────────\ninterface TreeContextValue {\n tree: ReturnType<typeof useTree>\n checkboxes: boolean\n}\n\nconst TreeContext = React.createContext<TreeContextValue | null>(null)\n\nexport function useTreeContext() {\n const ctx = React.useContext(TreeContext)\n if (!ctx) {\n throw new Error('TreeItem must be used within a <TreeView>')\n }\n return ctx\n}\n\n// ─── Props ──────────────────────────────────────────────────────────\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLUListElement>, 'onSelect'> {\n /** Data-driven mode: pass items array */\n items?: TreeNode[]\n /** Initially expanded node IDs */\n defaultExpanded?: string[]\n /** Initially selected node IDs */\n defaultSelected?: string[]\n /** Enable multi-select */\n multiSelect?: boolean\n /** Show checkboxes before each item */\n checkboxes?: boolean\n /** Called when selection changes */\n onSelect?: (ids: string[]) => void\n /** Called when expansion changes */\n onExpand?: (ids: string[]) => void\n className?: string\n /** Declarative mode: render TreeItem children directly */\n children?: React.ReactNode\n}\n\n// ─── Render nodes recursively (data-driven mode) ───────────────────\nfunction renderNodes(nodes: TreeNode[], depth: number = 0): React.ReactNode {\n return nodes.map((node) => (\n <TreeItem\n key={node.id}\n itemId={node.id}\n label={node.label}\n icon={node.icon}\n disabled={node.disabled}\n depth={depth}\n >\n {node.children && node.children.length > 0\n ? renderNodes(node.children, depth + 1)\n : undefined}\n </TreeItem>\n ))\n}\n\n// ─── Helper: collect all visible item IDs ───────────────────────────\nfunction getVisibleItemElements(container: HTMLElement): HTMLElement[] {\n return Array.from(\n container.querySelectorAll<HTMLElement>('[data-tree-item]'),\n ).filter((el) => {\n // Items inside collapsed groups should not be focusable\n let parent = el.parentElement\n while (parent && parent !== container) {\n if (parent.getAttribute('role') === 'group') {\n const grid = parent.parentElement\n if (grid && grid.classList.contains('grid-rows-[0fr]')) {\n return false\n }\n }\n parent = parent.parentElement\n }\n return true\n })\n}\n\n// ─── Component ──────────────────────────────────────────────────────\nconst TreeView = React.forwardRef<HTMLUListElement, TreeViewProps>(\n (\n {\n items,\n defaultExpanded,\n defaultSelected,\n multiSelect = false,\n checkboxes = false,\n onSelect,\n onExpand,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const tree = useTree({\n defaultExpanded,\n defaultSelected,\n multiSelect,\n onSelect,\n onExpand,\n })\n\n const innerRef = React.useRef<HTMLUListElement>(null)\n const containerRef = (ref as React.RefObject<HTMLUListElement>) ?? innerRef\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLUListElement>) => {\n const container = containerRef.current\n if (!container) return\n\n const visibleItems = getVisibleItemElements(container)\n const currentIndex = visibleItems.findIndex(\n (el) => el === document.activeElement,\n )\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const next = visibleItems[currentIndex + 1]\n next?.focus()\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prev = visibleItems[currentIndex - 1]\n prev?.focus()\n break\n }\n case 'ArrowRight': {\n // Handled in TreeItem for expand; if already expanded, move to first child\n const current = visibleItems[currentIndex]\n if (current) {\n const itemId = current.getAttribute('data-tree-item')\n if (itemId && tree.isExpanded(itemId)) {\n e.preventDefault()\n const nextItem = visibleItems[currentIndex + 1]\n nextItem?.focus()\n }\n }\n break\n }\n case 'ArrowLeft': {\n // Handled in TreeItem for collapse; if already collapsed or leaf, move to parent\n const current = visibleItems[currentIndex]\n if (current) {\n const itemId = current.getAttribute('data-tree-item')\n const treeItem = current.closest('[role=\"treeitem\"]')\n const parentGroup = treeItem?.parentElement?.closest(\n '[role=\"treeitem\"]',\n )\n if (itemId && !tree.isExpanded(itemId) && parentGroup) {\n e.preventDefault()\n const parentRow = parentGroup.querySelector<HTMLElement>(\n '[data-tree-item]',\n )\n parentRow?.focus()\n }\n }\n break\n }\n case 'Home': {\n e.preventDefault()\n visibleItems[0]?.focus()\n break\n }\n case 'End': {\n e.preventDefault()\n visibleItems[visibleItems.length - 1]?.focus()\n break\n }\n }\n }\n\n const ctxValue = React.useMemo<TreeContextValue>(\n () => ({ tree, checkboxes }),\n [tree, checkboxes],\n )\n\n const content = items ? renderNodes(items) : children\n\n return (\n <TreeContext.Provider value={ctxValue}>\n <ul\n ref={containerRef}\n role=\"tree\"\n aria-multiselectable={multiSelect || undefined}\n onKeyDown={handleKeyDown}\n className={cn('m-0 list-none p-0', className)}\n {...props}\n >\n {content}\n </ul>\n </TreeContext.Provider>\n )\n },\n)\nTreeView.displayName = 'TreeView'\n\nexport { TreeView }\n","'use client'\n\nimport { IconChevronRight } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Checkbox } from '../checkbox'\nimport { Icon } from '../icon'\nimport { cn } from '../lib/utils'\nimport { useTreeContext } from './tree-view'\n\nexport interface TreeItemProps {\n /** Unique identifier for this tree item */\n itemId: string\n /** Primary label content */\n label: React.ReactNode\n /** Optional icon rendered before the label */\n icon?: React.ReactNode\n /** Secondary label rendered after the primary label */\n secondaryLabel?: React.ReactNode\n /** Action buttons rendered at the end of the row */\n actions?: React.ReactNode\n /** Whether this item is disabled */\n disabled?: boolean\n /** Nested tree items */\n children?: React.ReactNode\n /** Depth level (used internally) */\n depth?: number\n /** Additional CSS class names */\n className?: string\n}\n\nconst TreeItem = React.forwardRef<HTMLLIElement, TreeItemProps>(\n (\n {\n itemId,\n label,\n icon,\n secondaryLabel,\n actions,\n disabled = false,\n children,\n depth = 0,\n className,\n },\n ref,\n ) => {\n const ctx = useTreeContext()\n const hasChildren = React.Children.count(children) > 0\n const isExpanded = ctx.tree.isExpanded(itemId)\n const isSelected = ctx.tree.isSelected(itemId)\n\n const handleRowClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return\n ctx.tree.select(itemId, e)\n }\n\n const handleChevronClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation()\n if (disabled) return\n ctx.tree.toggle(itemId)\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ctx.tree.select(itemId)\n }\n if (e.key === 'ArrowRight' && hasChildren && !isExpanded) {\n e.preventDefault()\n e.stopPropagation()\n ctx.tree.toggle(itemId)\n }\n if (e.key === 'ArrowLeft' && hasChildren && isExpanded) {\n e.preventDefault()\n e.stopPropagation()\n ctx.tree.toggle(itemId)\n }\n }\n\n // Compute indeterminate state for checkbox mode\n const checkboxState = React.useMemo(() => {\n if (!ctx.checkboxes || !hasChildren) {\n return { checked: isSelected, indeterminate: false }\n }\n // Collect all descendant IDs\n const descendants: string[] = []\n const collectIds = (nodes: React.ReactNode) => {\n React.Children.forEach(nodes, (child) => {\n if (React.isValidElement<TreeItemProps>(child) && child.props.itemId) {\n descendants.push(child.props.itemId)\n if (child.props.children) {\n collectIds(child.props.children)\n }\n }\n })\n }\n collectIds(children)\n const selectedCount = descendants.filter((id) =>\n ctx.tree.isSelected(id),\n ).length\n if (selectedCount === 0 && !isSelected) {\n return { checked: false, indeterminate: false }\n }\n if (selectedCount === descendants.length) {\n return { checked: true, indeterminate: false }\n }\n return { checked: false, indeterminate: true }\n }, [ctx.checkboxes, hasChildren, children, isSelected, ctx.tree])\n\n return (\n <li\n ref={ref}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={isSelected}\n aria-level={depth + 1}\n aria-disabled={disabled || undefined}\n className=\"list-none\"\n >\n {/* Row */}\n <div\n role=\"presentation\"\n data-tree-item={itemId}\n tabIndex={disabled ? -1 : 0}\n onClick={handleRowClick}\n onKeyDown={handleKeyDown}\n style={{ paddingLeft: `calc(${depth} * var(--spacing-ds-05b) + var(--spacing-ds-03))` }}\n className={cn(\n 'flex items-center gap-ds-02 py-ds-02 px-ds-02 rounded-ds-md cursor-pointer transition-colors duration-fast-01',\n 'hover:bg-surface-raised',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9',\n isSelected &&\n 'bg-accent-3 text-accent-11',\n disabled && 'opacity-action-disabled cursor-not-allowed pointer-events-none',\n className,\n )}\n >\n {/* Expand chevron */}\n {hasChildren ? (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n onClick={handleChevronClick}\n className=\"flex shrink-0 items-center justify-center p-0 border-0 bg-transparent cursor-pointer\"\n >\n <Icon\n icon={IconChevronRight}\n size=\"sm\"\n className={cn(\n 'transition-transform duration-moderate-02',\n isExpanded && 'rotate-90',\n )}\n />\n </button>\n ) : (\n <span className=\"inline-block w-4 shrink-0\" aria-hidden=\"true\" />\n )}\n\n {/* Checkbox (optional) */}\n {ctx.checkboxes && (\n <Checkbox\n checked={checkboxState.checked}\n indeterminate={checkboxState.indeterminate}\n disabled={disabled}\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n onCheckedChange={() => {\n if (!disabled) ctx.tree.select(itemId)\n }}\n className=\"shrink-0\"\n />\n )}\n\n {/* Icon */}\n {icon && (\n <span className=\"flex shrink-0 items-center text-surface-fg-subtle\">\n {icon}\n </span>\n )}\n\n {/* Label */}\n <span className=\"truncate text-ds-sm\">{label}</span>\n\n {/* Secondary label */}\n {secondaryLabel && (\n <span className=\"ml-auto truncate text-ds-xs text-surface-fg-muted\">\n {secondaryLabel}\n </span>\n )}\n\n {/* Actions */}\n {actions && (\n <span\n className=\"ml-auto flex shrink-0 items-center gap-ds-01\"\n onClick={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n {actions}\n </span>\n )}\n </div>\n\n {/* Children (collapsible) */}\n {hasChildren && (\n <div\n role=\"group\"\n className={cn(\n 'grid transition-[grid-template-rows] duration-moderate-02 ease-productive-standard',\n isExpanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',\n )}\n >\n <ul role=\"group\" className=\"overflow-hidden m-0 p-0\">\n {React.Children.map(children, (child) => {\n if (React.isValidElement<TreeItemProps>(child)) {\n return React.cloneElement(child, {\n depth: depth + 1,\n })\n }\n return child\n })}\n </ul>\n </div>\n )}\n </li>\n )\n },\n)\nTreeItem.displayName = 'TreeItem'\n\nexport { TreeItem }\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-calendar.js","names":[],"sources":["../../src/composed/date-picker/calendar-grid.tsx","../../src/composed/date-picker/use-calendar.ts"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {\n format,\n startOfMonth,\n endOfMonth,\n startOfWeek,\n endOfWeek,\n addDays,\n addMonths,\n subMonths,\n isSameMonth,\n isSameDay,\n isWithinInterval,\n isBefore,\n isAfter,\n startOfDay,\n lastDayOfMonth,\n} from 'date-fns'\nimport { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'\nimport { Icon } from '../../ui/icon'\nimport { cn } from '../../ui/lib/utils'\n\nconst WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\n\nexport interface CalendarEvent {\n date: Date\n color?: string\n label?: string\n}\n\nexport interface CalendarGridProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n currentMonth: Date\n selected?: Date | null\n rangeStart?: Date | null\n rangeEnd?: Date | null\n hoverDate?: Date | null\n onSelect: (date: Date) => void\n onHover?: (date: Date | null) => void\n onMonthChange: (date: Date) => void\n onHeaderClick?: () => void\n disabledDates?: (date: Date) => boolean\n minDate?: Date\n maxDate?: Date\n /** Hide the previous-month navigation arrow */\n hidePrevNav?: boolean\n /** Hide the next-month navigation arrow */\n hideNextNav?: boolean\n /** Events to display as dot indicators on dates */\n events?: CalendarEvent[]\n}\n\nexport const CalendarGrid = React.forwardRef<HTMLDivElement, CalendarGridProps>(\n function CalendarGrid({\n currentMonth,\n selected,\n rangeStart,\n rangeEnd,\n hoverDate,\n onSelect,\n onHover,\n onMonthChange,\n onHeaderClick,\n disabledDates,\n minDate,\n maxDate,\n hidePrevNav,\n hideNextNav,\n events,\n className,\n ...props\n}, forwardedRef) {\n const gridRef = React.useRef<HTMLDivElement>(null)\n\n const eventsByDate = React.useMemo(() => {\n const map = new Map<string, CalendarEvent[]>()\n if (!events) return map\n for (const evt of events) {\n const key = format(evt.date, 'yyyy-MM-dd')\n const arr = map.get(key) ?? []\n arr.push(evt)\n map.set(key, arr)\n }\n return map\n }, [events])\n\n const monthStart = startOfMonth(currentMonth)\n const monthEnd = endOfMonth(currentMonth)\n const calendarStart = startOfWeek(monthStart)\n const calendarEnd = endOfWeek(monthEnd)\n\n const days: Date[] = []\n let day = calendarStart\n while (day <= calendarEnd) {\n days.push(day)\n day = addDays(day, 1)\n }\n\n const isDateDisabled = (date: Date): boolean => {\n if (disabledDates?.(date)) return true\n if (minDate && isBefore(date, startOfDay(minDate))) return true\n if (maxDate && isAfter(date, startOfDay(maxDate))) return true\n return false\n }\n\n const isInRange = (date: Date) => {\n if (rangeStart && rangeEnd) {\n const start = isBefore(rangeStart, rangeEnd) ? rangeStart : rangeEnd\n const end = isAfter(rangeEnd, rangeStart) ? rangeEnd : rangeStart\n return isWithinInterval(date, { start, end })\n }\n if (rangeStart && hoverDate) {\n const start = isBefore(rangeStart, hoverDate) ? rangeStart : hoverDate\n const end = isAfter(hoverDate, rangeStart) ? hoverDate : rangeStart\n return isWithinInterval(date, { start, end })\n }\n return false\n }\n\n const isRangeEdge = (date: Date) => {\n if (rangeStart && isSameDay(date, rangeStart)) return true\n if (rangeEnd && isSameDay(date, rangeEnd)) return true\n return false\n }\n\n const focusDate = (target: Date) => {\n if (!gridRef.current) return\n const dateStr = format(target, 'yyyy-MM-dd')\n const btn = gridRef.current.querySelector<HTMLButtonElement>(\n `[data-date=\"${dateStr}\"]`,\n )\n if (btn) {\n btn.focus()\n } else {\n // Date is in a different month — navigate there and focus after render\n onMonthChange(startOfMonth(target))\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const target = e.target as HTMLElement\n const dateStr = target.getAttribute('data-date')\n if (!dateStr) return\n\n const current = new Date(dateStr + 'T00:00:00')\n let next: Date | null = null\n\n switch (e.key) {\n case 'ArrowLeft':\n next = addDays(current, -1)\n break\n case 'ArrowRight':\n next = addDays(current, 1)\n break\n case 'ArrowUp':\n next = addDays(current, -7)\n break\n case 'ArrowDown':\n next = addDays(current, 7)\n break\n case 'Home':\n next = startOfMonth(current)\n break\n case 'End':\n next = lastDayOfMonth(current)\n break\n case 'Enter':\n case ' ': {\n e.preventDefault()\n if (!isDateDisabled(current) && isSameMonth(current, currentMonth)) {\n onSelect(current)\n }\n return\n }\n default:\n return\n }\n\n if (next) {\n e.preventDefault()\n focusDate(next)\n }\n }\n\n return (\n <div ref={forwardedRef} {...props} className={cn(\"w-[252px]\", className)}>\n <div className=\"flex items-center justify-between px-ds-02 pb-ds-04\">\n {hidePrevNav ? (\n <span className=\"h-ds-xs-plus w-ds-xs-plus\" />\n ) : (\n <button\n type=\"button\"\n onClick={() => onMonthChange(subMonths(currentMonth, 1))}\n className=\"inline-flex h-ds-xs-plus w-ds-xs-plus items-center justify-center rounded-ds-md text-surface-fg-subtle transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9\"\n aria-label=\"Previous month\"\n >\n <Icon icon={IconChevronLeft} size=\"sm\" stroke=\"light\" />\n </button>\n )}\n <button\n type=\"button\"\n onClick={onHeaderClick}\n className={cn(\n 'text-ds-md font-semibold text-surface-fg',\n onHeaderClick &&\n 'cursor-pointer rounded-ds-md px-ds-02 transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover',\n )}\n aria-label=\"Switch to month/year view\"\n >\n {format(currentMonth, 'MMMM yyyy')}\n </button>\n {hideNextNav ? (\n <span className=\"h-ds-xs-plus w-ds-xs-plus\" />\n ) : (\n <button\n type=\"button\"\n onClick={() => onMonthChange(addMonths(currentMonth, 1))}\n className=\"inline-flex h-ds-xs-plus w-ds-xs-plus items-center justify-center rounded-ds-md text-surface-fg-subtle transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9\"\n aria-label=\"Next month\"\n >\n <Icon icon={IconChevronRight} size=\"sm\" stroke=\"light\" />\n </button>\n )}\n </div>\n\n <div\n ref={gridRef}\n className=\"grid grid-cols-7 gap-0\"\n role=\"grid\"\n tabIndex={0}\n aria-label=\"Calendar\"\n onKeyDown={handleKeyDown}\n >\n {WEEKDAYS.map((wd) => (\n <div\n key={wd}\n role=\"columnheader\"\n className=\"flex h-ds-sm items-center justify-center text-ds-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\"\n >\n {wd}\n </div>\n ))}\n\n {days.map((d, i) => {\n const inMonth = isSameMonth(d, currentMonth)\n const disabled = isDateDisabled(d)\n const isSelected = selected && isSameDay(d, selected)\n const inRange = isInRange(d)\n const edge = isRangeEdge(d)\n const isToday = isSameDay(d, new Date())\n const dateKey = format(d, 'yyyy-MM-dd')\n const dayEvents = eventsByDate.get(dateKey) ?? []\n\n return (\n <button\n key={i}\n type=\"button\"\n role=\"gridcell\"\n data-date={dateKey}\n tabIndex={inMonth && !disabled ? 0 : -1}\n disabled={!inMonth || disabled}\n onClick={() => {\n if (inMonth && !disabled) onSelect(d)\n }}\n onMouseEnter={() => onHover?.(d)}\n onMouseLeave={() => onHover?.(null)}\n aria-label={format(d, 'EEEE, MMMM d, yyyy')}\n aria-selected={isSelected || edge || undefined}\n aria-disabled={!inMonth || disabled || undefined}\n className={cn(\n 'relative flex h-ds-sm w-ds-sm-plus items-center justify-center rounded-ds-md text-ds-md font-body transition-colors duration-fast-01 ease-productive-standard',\n !inMonth && 'pointer-events-none opacity-0',\n inMonth && disabled && 'opacity-action-disabled pointer-events-none cursor-not-allowed',\n inMonth && !disabled && !isSelected && !edge && !inRange &&\n 'text-surface-fg hover:bg-surface-raised-hover',\n inRange && !edge &&\n 'rounded-ds-none bg-surface-raised-hover text-surface-fg',\n (isSelected || edge) &&\n 'bg-accent-9 text-accent-fg hover:bg-accent-10',\n isToday && !isSelected && !edge && !disabled &&\n 'font-semibold text-accent-11',\n )}\n >\n {format(d, 'd')}\n {dayEvents.length > 0 && (\n <span className=\"flex gap-px justify-center absolute bottom-[2px] left-0 right-0\">\n {dayEvents.slice(0, 3).map((evt, idx) => (\n <span\n key={idx}\n data-event-dot\n className=\"h-[4px] w-[4px] rounded-ds-full\"\n style={{ backgroundColor: evt.color ?? 'var(--color-accent-9)' }}\n />\n ))}\n </span>\n )}\n </button>\n )\n })}\n </div>\n </div>\n )\n},\n)\n\nCalendarGrid.displayName = 'CalendarGrid'\n","'use client'\n\nimport { useState } from 'react'\nimport { subMonths, addMonths, setMonth, setYear } from 'date-fns'\n\nexport function useCalendar(initialMonth?: Date) {\n const [currentMonth, setCurrentMonth] = useState(initialMonth ?? new Date())\n\n const goToPreviousMonth = () => setCurrentMonth((prev) => subMonths(prev, 1))\n const goToNextMonth = () => setCurrentMonth((prev) => addMonths(prev, 1))\n const goToMonth = (month: number) =>\n setCurrentMonth((prev) => setMonth(prev, month))\n const goToYear = (year: number) =>\n setCurrentMonth((prev) => setYear(prev, year))\n\n return {\n currentMonth,\n setCurrentMonth,\n goToPreviousMonth,\n goToNextMonth,\n goToMonth,\n goToYear,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-calendar.js","names":[],"sources":["../../src/composed/date-picker/calendar-grid.tsx","../../src/composed/date-picker/use-calendar.ts"],"sourcesContent":["'use client'\n\nimport { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'\nimport {\n addDays,\n addMonths,\n endOfMonth,\n endOfWeek,\n format,\n isAfter,\n isBefore,\n isSameDay,\n isSameMonth,\n isWithinInterval,\n lastDayOfMonth,\n startOfDay,\n startOfMonth,\n startOfWeek,\n subMonths,\n} from 'date-fns'\nimport * as React from 'react'\n\nimport { Icon } from '../../ui/icon'\nimport { cn } from '../../ui/lib/utils'\n\nconst WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\n\nexport interface CalendarEvent {\n date: Date\n color?: string\n label?: string\n}\n\nexport interface CalendarGridProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n currentMonth: Date\n selected?: Date | null\n rangeStart?: Date | null\n rangeEnd?: Date | null\n hoverDate?: Date | null\n onSelect: (date: Date) => void\n onHover?: (date: Date | null) => void\n onMonthChange: (date: Date) => void\n onHeaderClick?: () => void\n disabledDates?: (date: Date) => boolean\n minDate?: Date\n maxDate?: Date\n /** Hide the previous-month navigation arrow */\n hidePrevNav?: boolean\n /** Hide the next-month navigation arrow */\n hideNextNav?: boolean\n /** Events to display as dot indicators on dates */\n events?: CalendarEvent[]\n}\n\nexport const CalendarGrid = React.forwardRef<HTMLDivElement, CalendarGridProps>(\n function CalendarGrid({\n currentMonth,\n selected,\n rangeStart,\n rangeEnd,\n hoverDate,\n onSelect,\n onHover,\n onMonthChange,\n onHeaderClick,\n disabledDates,\n minDate,\n maxDate,\n hidePrevNav,\n hideNextNav,\n events,\n className,\n ...props\n}, forwardedRef) {\n const gridRef = React.useRef<HTMLDivElement>(null)\n\n const eventsByDate = React.useMemo(() => {\n const map = new Map<string, CalendarEvent[]>()\n if (!events) return map\n for (const evt of events) {\n const key = format(evt.date, 'yyyy-MM-dd')\n const arr = map.get(key) ?? []\n arr.push(evt)\n map.set(key, arr)\n }\n return map\n }, [events])\n\n const monthStart = startOfMonth(currentMonth)\n const monthEnd = endOfMonth(currentMonth)\n const calendarStart = startOfWeek(monthStart)\n const calendarEnd = endOfWeek(monthEnd)\n\n const days: Date[] = []\n let day = calendarStart\n while (day <= calendarEnd) {\n days.push(day)\n day = addDays(day, 1)\n }\n\n const isDateDisabled = (date: Date): boolean => {\n if (disabledDates?.(date)) return true\n if (minDate && isBefore(date, startOfDay(minDate))) return true\n if (maxDate && isAfter(date, startOfDay(maxDate))) return true\n return false\n }\n\n const isInRange = (date: Date) => {\n if (rangeStart && rangeEnd) {\n const start = isBefore(rangeStart, rangeEnd) ? rangeStart : rangeEnd\n const end = isAfter(rangeEnd, rangeStart) ? rangeEnd : rangeStart\n return isWithinInterval(date, { start, end })\n }\n if (rangeStart && hoverDate) {\n const start = isBefore(rangeStart, hoverDate) ? rangeStart : hoverDate\n const end = isAfter(hoverDate, rangeStart) ? hoverDate : rangeStart\n return isWithinInterval(date, { start, end })\n }\n return false\n }\n\n const isRangeEdge = (date: Date) => {\n if (rangeStart && isSameDay(date, rangeStart)) return true\n if (rangeEnd && isSameDay(date, rangeEnd)) return true\n return false\n }\n\n const focusDate = (target: Date) => {\n if (!gridRef.current) return\n const dateStr = format(target, 'yyyy-MM-dd')\n const btn = gridRef.current.querySelector<HTMLButtonElement>(\n `[data-date=\"${dateStr}\"]`,\n )\n if (btn) {\n btn.focus()\n } else {\n // Date is in a different month — navigate there and focus after render\n onMonthChange(startOfMonth(target))\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const target = e.target as HTMLElement\n const dateStr = target.getAttribute('data-date')\n if (!dateStr) return\n\n const current = new Date(dateStr + 'T00:00:00')\n let next: Date | null = null\n\n switch (e.key) {\n case 'ArrowLeft':\n next = addDays(current, -1)\n break\n case 'ArrowRight':\n next = addDays(current, 1)\n break\n case 'ArrowUp':\n next = addDays(current, -7)\n break\n case 'ArrowDown':\n next = addDays(current, 7)\n break\n case 'Home':\n next = startOfMonth(current)\n break\n case 'End':\n next = lastDayOfMonth(current)\n break\n case 'Enter':\n case ' ': {\n e.preventDefault()\n if (!isDateDisabled(current) && isSameMonth(current, currentMonth)) {\n onSelect(current)\n }\n return\n }\n default:\n return\n }\n\n if (next) {\n e.preventDefault()\n focusDate(next)\n }\n }\n\n return (\n <div ref={forwardedRef} {...props} className={cn(\"w-[252px]\", className)}>\n <div className=\"flex items-center justify-between px-ds-02 pb-ds-04\">\n {hidePrevNav ? (\n <span className=\"h-ds-xs-plus w-ds-xs-plus\" />\n ) : (\n <button\n type=\"button\"\n onClick={() => onMonthChange(subMonths(currentMonth, 1))}\n className=\"inline-flex h-ds-xs-plus w-ds-xs-plus items-center justify-center rounded-ds-md text-surface-fg-subtle transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9\"\n aria-label=\"Previous month\"\n >\n <Icon icon={IconChevronLeft} size=\"sm\" stroke=\"light\" />\n </button>\n )}\n <button\n type=\"button\"\n onClick={onHeaderClick}\n className={cn(\n 'text-ds-md font-semibold text-surface-fg',\n onHeaderClick &&\n 'cursor-pointer rounded-ds-md px-ds-02 transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover',\n )}\n aria-label=\"Switch to month/year view\"\n >\n {format(currentMonth, 'MMMM yyyy')}\n </button>\n {hideNextNav ? (\n <span className=\"h-ds-xs-plus w-ds-xs-plus\" />\n ) : (\n <button\n type=\"button\"\n onClick={() => onMonthChange(addMonths(currentMonth, 1))}\n className=\"inline-flex h-ds-xs-plus w-ds-xs-plus items-center justify-center rounded-ds-md text-surface-fg-subtle transition-colors duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9\"\n aria-label=\"Next month\"\n >\n <Icon icon={IconChevronRight} size=\"sm\" stroke=\"light\" />\n </button>\n )}\n </div>\n\n <div\n ref={gridRef}\n className=\"grid grid-cols-7 gap-0\"\n role=\"grid\"\n tabIndex={0}\n aria-label=\"Calendar\"\n onKeyDown={handleKeyDown}\n >\n {WEEKDAYS.map((wd) => (\n <div\n key={wd}\n role=\"columnheader\"\n className=\"flex h-ds-sm items-center justify-center text-ds-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\"\n >\n {wd}\n </div>\n ))}\n\n {days.map((d, i) => {\n const inMonth = isSameMonth(d, currentMonth)\n const disabled = isDateDisabled(d)\n const isSelected = selected && isSameDay(d, selected)\n const inRange = isInRange(d)\n const edge = isRangeEdge(d)\n const isToday = isSameDay(d, new Date())\n const dateKey = format(d, 'yyyy-MM-dd')\n const dayEvents = eventsByDate.get(dateKey) ?? []\n\n return (\n <button\n key={i}\n type=\"button\"\n role=\"gridcell\"\n data-date={dateKey}\n tabIndex={inMonth && !disabled ? 0 : -1}\n disabled={!inMonth || disabled}\n onClick={() => {\n if (inMonth && !disabled) onSelect(d)\n }}\n onMouseEnter={() => onHover?.(d)}\n onMouseLeave={() => onHover?.(null)}\n aria-label={format(d, 'EEEE, MMMM d, yyyy')}\n aria-selected={isSelected || edge || undefined}\n aria-disabled={!inMonth || disabled || undefined}\n className={cn(\n 'relative flex h-ds-sm w-ds-sm-plus items-center justify-center rounded-ds-md text-ds-md font-body transition-colors duration-fast-01 ease-productive-standard',\n !inMonth && 'pointer-events-none opacity-0',\n inMonth && disabled && 'opacity-action-disabled pointer-events-none cursor-not-allowed',\n inMonth && !disabled && !isSelected && !edge && !inRange &&\n 'text-surface-fg hover:bg-surface-raised-hover',\n inRange && !edge &&\n 'rounded-ds-none bg-surface-raised-hover text-surface-fg',\n (isSelected || edge) &&\n 'bg-accent-9 text-accent-fg hover:bg-accent-10',\n isToday && !isSelected && !edge && !disabled &&\n 'font-semibold text-accent-11',\n )}\n >\n {format(d, 'd')}\n {dayEvents.length > 0 && (\n <span className=\"flex gap-px justify-center absolute bottom-[2px] left-0 right-0\">\n {dayEvents.slice(0, 3).map((evt, idx) => (\n <span\n key={idx}\n data-event-dot\n className=\"h-[4px] w-[4px] rounded-ds-full\"\n style={{ backgroundColor: evt.color ?? 'var(--color-accent-9)' }}\n />\n ))}\n </span>\n )}\n </button>\n )\n })}\n </div>\n </div>\n )\n},\n)\n\nCalendarGrid.displayName = 'CalendarGrid'\n","'use client'\n\nimport { addMonths, setMonth, setYear,subMonths } from 'date-fns'\nimport { useState } from 'react'\n\nexport function useCalendar(initialMonth?: Date) {\n const [currentMonth, setCurrentMonth] = useState(initialMonth ?? new Date())\n\n const goToPreviousMonth = () => setCurrentMonth((prev) => subMonths(prev, 1))\n const goToNextMonth = () => setCurrentMonth((prev) => addMonths(prev, 1))\n const goToMonth = (month: number) =>\n setCurrentMonth((prev) => setMonth(prev, month))\n const goToYear = (year: number) =>\n setCurrentMonth((prev) => setYear(prev, year))\n\n return {\n currentMonth,\n setCurrentMonth,\n goToPreviousMonth,\n goToNextMonth,\n goToMonth,\n goToYear,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-command-provider.d.ts","sourceRoot":"","sources":["../../src/ai/ai-command-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"ai-command-provider.d.ts","sourceRoot":"","sources":["../../src/ai/ai-command-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC3E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,KAAK,IAAI,CAAA;IAC1E,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAA;CACjD;AAID,wBAAgB,YAAY,IAAI,gBAAgB,GAAG,IAAI,CAEtD;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC5E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,KAAK,IAAI,CAAA;IAC1E,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAA;CACjD;AAID,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,sBAAsB,2CAQpG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-command-provider.js","names":[],"sources":["../../src/ai/ai-command-provider.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport type { BlockComponentProps } from './types'\n\nexport interface AICommandContext {\n customBlocks: Record<string, React.ComponentType<BlockComponentProps<any>>>\n onAction?: (actionId: string, type: 'confirm' | 'cancel' | 'undo') => void\n agent?: { name: string; icon?: React.ReactNode }\n}\n\nconst AICommandCtx = React.createContext<AICommandContext | null>(null)\n\nexport function useAICommand(): AICommandContext | null {\n return React.useContext(AICommandCtx)\n}\n\nexport interface AICommandProviderProps {\n children: React.ReactNode\n customBlocks?: Record<string, React.ComponentType<BlockComponentProps<any>>>\n onAction?: (actionId: string, type: 'confirm' | 'cancel' | 'undo') => void\n agent?: { name: string; icon?: React.ReactNode }\n}\n\nconst EMPTY_BLOCKS: Record<string, React.ComponentType<BlockComponentProps<any>>> = {}\n\nexport function AICommandProvider({ children, customBlocks, onAction, agent }: AICommandProviderProps) {\n const blocks = customBlocks ?? EMPTY_BLOCKS\n const value = React.useMemo<AICommandContext>(\n () => ({ customBlocks: blocks, onAction, agent }),\n
|
|
1
|
+
{"version":3,"file":"ai-command-provider.js","names":[],"sources":["../../src/ai/ai-command-provider.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\n\nimport type { BlockComponentProps } from './types'\n\nexport interface AICommandContext {\n customBlocks: Record<string, React.ComponentType<BlockComponentProps<any>>>\n onAction?: (actionId: string, type: 'confirm' | 'cancel' | 'undo') => void\n agent?: { name: string; icon?: React.ReactNode }\n}\n\nconst AICommandCtx = React.createContext<AICommandContext | null>(null)\n\nexport function useAICommand(): AICommandContext | null {\n return React.useContext(AICommandCtx)\n}\n\nexport interface AICommandProviderProps {\n children: React.ReactNode\n customBlocks?: Record<string, React.ComponentType<BlockComponentProps<any>>>\n onAction?: (actionId: string, type: 'confirm' | 'cancel' | 'undo') => void\n agent?: { name: string; icon?: React.ReactNode }\n}\n\nconst EMPTY_BLOCKS: Record<string, React.ComponentType<BlockComponentProps<any>>> = {}\n\nexport function AICommandProvider({ children, customBlocks, onAction, agent }: AICommandProviderProps) {\n const blocks = customBlocks ?? EMPTY_BLOCKS\n const value = React.useMemo<AICommandContext>(\n () => ({ customBlocks: blocks, onAction, agent }),\n \n [blocks, onAction, agent],\n )\n return <AICommandCtx.Provider value={value}>{children}</AICommandCtx.Provider>\n}\n"],"mappings":";;;;AAYA,IAAM,IAAe,EAAM,cAAuC,KAAK;AAEvE,SAAgB,IAAwC;AACtD,QAAO,EAAM,WAAW,EAAa;;AAUvC,IAAM,IAA8E,EAAE;AAEtF,SAAgB,EAAkB,EAAE,aAAU,iBAAc,aAAU,YAAiC;CACrG,IAAM,IAAS,KAAgB,GACzB,IAAQ,EAAM,eACX;EAAE,cAAc;EAAQ;EAAU;EAAO,GAEhD;EAAC;EAAQ;EAAU;EAAM,CAC1B;AACD,QAAO,kBAAC,EAAa,UAAd;EAA8B;EAAQ;EAAiC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-renderer.d.ts","sourceRoot":"","sources":["../../src/ai/block-renderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"block-renderer.d.ts","sourceRoot":"","sources":["../../src/ai/block-renderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAiB9B,OAAO,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAwBzD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,KAAK,IAAI,CAAA;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,QAAA,MAAM,aAAa,2FA2DjB,CAAA;AAGF,OAAO,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
2
|
+
import { springs as e } from "../ui/lib/motion.js";
|
|
3
|
+
import { cn as t } from "../ui/lib/utils.js";
|
|
4
|
+
import { Alert as n } from "../ui/alert.js";
|
|
5
|
+
import { n as r } from "../_chunks/motion-provider.js";
|
|
6
|
+
import { useAICommand as i } from "./ai-command-provider.js";
|
|
7
|
+
import { a, c as o, i as s, l as c, n as l, o as u, r as d, s as f, t as p } from "../_chunks/text.js";
|
|
8
|
+
import * as m from "react";
|
|
9
|
+
import { jsx as h } from "react/jsx-runtime";
|
|
10
|
+
import { motion as g } from "framer-motion";
|
|
11
11
|
//#region src/ai/block-renderer.tsx
|
|
12
12
|
var _ = {
|
|
13
|
-
text:
|
|
14
|
-
table:
|
|
15
|
-
confirm:
|
|
16
|
-
success:
|
|
17
|
-
error:
|
|
18
|
-
info:
|
|
19
|
-
loading:
|
|
20
|
-
divider:
|
|
21
|
-
stat_row:
|
|
13
|
+
text: p,
|
|
14
|
+
table: c,
|
|
15
|
+
confirm: o,
|
|
16
|
+
success: l,
|
|
17
|
+
error: u,
|
|
18
|
+
info: a,
|
|
19
|
+
loading: s,
|
|
20
|
+
divider: f,
|
|
21
|
+
stat_row: d
|
|
22
22
|
};
|
|
23
23
|
function v({ data: e, type: t }) {
|
|
24
|
-
return /* @__PURE__ */
|
|
24
|
+
return /* @__PURE__ */ h(n, {
|
|
25
25
|
color: "info",
|
|
26
26
|
variant: "subtle",
|
|
27
27
|
title: `Unknown block type: ${t}`,
|
|
28
|
-
children: /* @__PURE__ */
|
|
28
|
+
children: /* @__PURE__ */ h("pre", {
|
|
29
29
|
className: "mt-2 text-ds-xs whitespace-pre-wrap",
|
|
30
30
|
children: JSON.stringify(e, null, 2)
|
|
31
31
|
})
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
-
var y =
|
|
35
|
-
let
|
|
36
|
-
...
|
|
37
|
-
...
|
|
38
|
-
}), [
|
|
39
|
-
return /* @__PURE__ */
|
|
40
|
-
ref:
|
|
41
|
-
className:
|
|
42
|
-
children:
|
|
43
|
-
let
|
|
44
|
-
data:
|
|
45
|
-
blockId:
|
|
46
|
-
confidence:
|
|
47
|
-
onAction:
|
|
48
|
-
},
|
|
49
|
-
data:
|
|
50
|
-
type:
|
|
51
|
-
}),
|
|
52
|
-
return
|
|
34
|
+
var y = m.forwardRef(({ blocks: n, onAction: a, customBlocks: o, staggerDelay: s = 50, className: c }, l) => {
|
|
35
|
+
let u = i(), { reducedMotion: d } = r(), f = m.useMemo(() => ({
|
|
36
|
+
...u?.customBlocks ?? {},
|
|
37
|
+
...o
|
|
38
|
+
}), [u?.customBlocks, o]), p = a ?? u?.onAction;
|
|
39
|
+
return /* @__PURE__ */ h("div", {
|
|
40
|
+
ref: l,
|
|
41
|
+
className: t("flex flex-col gap-ds-04", c),
|
|
42
|
+
children: n.map((t, n) => {
|
|
43
|
+
let r = f[t.type] ?? _[t.type] ?? null, i = {
|
|
44
|
+
data: t.data,
|
|
45
|
+
blockId: t.id,
|
|
46
|
+
confidence: t.confidence,
|
|
47
|
+
onAction: p
|
|
48
|
+
}, a = r ? /* @__PURE__ */ h(r, { ...i }) : /* @__PURE__ */ h(v, {
|
|
49
|
+
data: t.data,
|
|
50
|
+
type: t.type
|
|
51
|
+
}), o = t.id ?? `${t.type}-${n}`;
|
|
52
|
+
return d ? /* @__PURE__ */ h("div", { children: a }, o) : /* @__PURE__ */ h(g.div, {
|
|
53
53
|
initial: {
|
|
54
54
|
opacity: 0,
|
|
55
55
|
y: 12
|
|
@@ -59,11 +59,11 @@ var y = h.forwardRef(({ blocks: r, onAction: o, customBlocks: s, staggerDelay: c
|
|
|
59
59
|
y: 0
|
|
60
60
|
},
|
|
61
61
|
transition: {
|
|
62
|
-
...
|
|
63
|
-
delay:
|
|
62
|
+
...e.responsive,
|
|
63
|
+
delay: s / 1e3 * n
|
|
64
64
|
},
|
|
65
|
-
children:
|
|
66
|
-
},
|
|
65
|
+
children: a
|
|
66
|
+
}, o);
|
|
67
67
|
})
|
|
68
68
|
});
|
|
69
69
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-renderer.js","names":[],"sources":["../../src/ai/block-renderer.tsx"],"sourcesContent":["'use client'\n\nimport
|
|
1
|
+
{"version":3,"file":"block-renderer.js","names":[],"sources":["../../src/ai/block-renderer.tsx"],"sourcesContent":["'use client'\n\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useMotion } from '../motion/motion-provider'\nimport { Alert } from '../ui/alert'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport { useAICommand } from './ai-command-provider'\nimport { BlockTable } from './blocks/block-table'\nimport { ConfirmBlock } from './blocks/confirm'\nimport { DividerBlock } from './blocks/divider'\nimport { ErrorBlock } from './blocks/error'\nimport { InfoBlock } from './blocks/info'\nimport { LoadingBlock } from './blocks/loading'\nimport { StatRowBlock } from './blocks/stat-row'\nimport { SuccessBlock } from './blocks/success'\n// Import all built-in blocks\nimport { TextBlock } from './blocks/text'\nimport type { Block, BlockComponentProps } from './types'\n\nconst BUILT_IN_BLOCKS: Record<string, React.ComponentType<BlockComponentProps<any>>> = {\n text: TextBlock,\n table: BlockTable,\n confirm: ConfirmBlock,\n success: SuccessBlock,\n error: ErrorBlock,\n info: InfoBlock,\n loading: LoadingBlock,\n divider: DividerBlock,\n stat_row: StatRowBlock,\n}\n\nfunction FallbackBlock({ data, type }: { data: Record<string, unknown>; type: string }) {\n return (\n <Alert color=\"info\" variant=\"subtle\" title={`Unknown block type: ${type}`}>\n <pre className=\"mt-2 text-ds-xs whitespace-pre-wrap\">\n {JSON.stringify(data, null, 2)}\n </pre>\n </Alert>\n )\n}\n\nexport interface BlockRendererProps {\n blocks: Block[]\n onAction?: (actionId: string, type: 'confirm' | 'cancel' | 'undo') => void\n customBlocks?: Record<string, React.ComponentType<BlockComponentProps<any>>>\n staggerDelay?: number\n className?: string\n}\n\nconst BlockRenderer = React.forwardRef<HTMLDivElement, BlockRendererProps>(({\n blocks,\n onAction,\n customBlocks,\n staggerDelay = 50,\n className,\n}, ref) => {\n const ctx = useAICommand()\n const { reducedMotion } = useMotion()\n\n // Merge custom blocks: prop wins over context\n const mergedCustomBlocks = React.useMemo(() => {\n const contextBlocks = ctx?.customBlocks ?? {}\n return { ...contextBlocks, ...customBlocks }\n }, [ctx?.customBlocks, customBlocks])\n\n // Resolve onAction: prop wins over context\n const resolvedOnAction = onAction ?? ctx?.onAction\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-ds-04', className)}>\n {blocks.map((block, index) => {\n const Component =\n mergedCustomBlocks[block.type] ??\n BUILT_IN_BLOCKS[block.type] ??\n null\n\n const blockProps: BlockComponentProps<any> = {\n data: block.data,\n blockId: block.id,\n confidence: block.confidence,\n onAction: resolvedOnAction,\n }\n\n const content = Component ? (\n <Component {...blockProps} />\n ) : (\n <FallbackBlock data={block.data} type={block.type} />\n )\n\n const key = block.id ?? `${block.type}-${index}`\n\n if (reducedMotion) {\n return <div key={key}>{content}</div>\n }\n\n return (\n <motion.div\n key={key}\n initial={{ opacity: 0, y: 12 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ ...springs.responsive, delay: index * (staggerDelay / 1000) }}\n >\n {content}\n </motion.div>\n )\n })}\n </div>\n )\n})\nBlockRenderer.displayName = 'BlockRenderer'\n\nexport { BlockRenderer }\n"],"mappings":";;;;;;;;;;;AAsBA,IAAM,IAAiF;CACrF,MAAM;CACN,OAAO;CACP,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACT,SAAS;CACT,UAAU;CACX;AAED,SAAS,EAAc,EAAE,SAAM,WAAyD;AACtF,QACE,kBAAC,GAAD;EAAO,OAAM;EAAO,SAAQ;EAAS,OAAO,uBAAuB;YACjE,kBAAC,OAAD;GAAK,WAAU;aACZ,KAAK,UAAU,GAAM,MAAM,EAAE;GAC1B,CAAA;EACA,CAAA;;AAYZ,IAAM,IAAgB,EAAM,YAAgD,EAC1E,WACA,aACA,iBACA,kBAAe,IACf,gBACC,MAAQ;CACT,IAAM,IAAM,GAAc,EACpB,EAAE,qBAAkB,GAAW,EAG/B,IAAqB,EAAM,eAExB;EAAE,GADa,GAAK,gBAAgB,EAAE;EAClB,GAAG;EAAc,GAC3C,CAAC,GAAK,cAAc,EAAa,CAAC,EAG/B,IAAmB,KAAY,GAAK;AAE1C,QACE,kBAAC,OAAD;EAAU;EAAK,WAAW,EAAG,2BAA2B,EAAU;YAC/D,EAAO,KAAK,GAAO,MAAU;GAC5B,IAAM,IACJ,EAAmB,EAAM,SACzB,EAAgB,EAAM,SACtB,MAEI,IAAuC;IAC3C,MAAM,EAAM;IACZ,SAAS,EAAM;IACf,YAAY,EAAM;IAClB,UAAU;IACX,EAEK,IAAU,IACd,kBAAC,GAAD,EAAW,GAAI,GAAc,CAAA,GAE7B,kBAAC,GAAD;IAAe,MAAM,EAAM;IAAM,MAAM,EAAM;IAAQ,CAAA,EAGjD,IAAM,EAAM,MAAM,GAAG,EAAM,KAAK,GAAG;AAMzC,UAJI,IACK,kBAAC,OAAD,EAAA,UAAgB,GAAc,EAApB,EAAoB,GAIrC,kBAAC,EAAO,KAAR;IAEE,SAAS;KAAE,SAAS;KAAG,GAAG;KAAI;IAC9B,SAAS;KAAE,SAAS;KAAG,GAAG;KAAG;IAC7B,YAAY;KAAE,GAAG,EAAQ;KAAY,OAAgB,IAAe,MAAxB;KAA+B;cAE1E;IACU,EANN,EAMM;IAEf;EACE,CAAA;EAER;AACF,EAAc,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-table.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/block-table.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"block-table.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/block-table.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAe9B,OAAO,KAAK,EAAE,mBAAmB,EAAmB,cAAc,EAAE,MAAM,UAAU,CAAA;AAiDpF,QAAA,MAAM,UAAU,oDAGb,mBAAmB,CAAC,cAAc,CAAC,6CA+HpC,CAAA;AAIF,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/confirm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/confirm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAS9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAErE,QAAA,MAAM,YAAY,8DAIf,mBAAmB,CAAC,gBAAgB,CAAC,6CAqDtC,CAAA;AAIF,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"divider.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/divider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"divider.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/divider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEnD,QAAA,MAAM,YAAY,qCACR,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,6CAkBlD,CAAA;AAIF,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/error.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/error.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAEnE,QAAA,MAAM,UAAU,oDAGb,mBAAmB,CAAC,cAAc,CAAC,6CAmBpC,CAAA;AAIF,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export {
|
|
2
|
+
export { BlockTable } from './block-table';
|
|
3
|
+
export { ConfirmBlock } from './confirm';
|
|
3
4
|
export { DividerBlock } from './divider';
|
|
4
|
-
export { InfoBlock } from './info';
|
|
5
5
|
export { ErrorBlock } from './error';
|
|
6
|
-
export {
|
|
6
|
+
export { InfoBlock } from './info';
|
|
7
7
|
export { LoadingBlock } from './loading';
|
|
8
|
-
export { ConfirmBlock } from './confirm';
|
|
9
|
-
export { BlockTable } from './block-table';
|
|
10
8
|
export { StatRowBlock } from './stat-row';
|
|
9
|
+
export { SuccessBlock } from './success';
|
|
10
|
+
export { TextBlock } from './text';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/blocks/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA"}
|