@devalok/shilp-sutra 0.49.3 → 0.49.4
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/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/block-shell.js.map +1 -1
- package/dist/_chunks/chart-container.js.map +1 -1
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/colors.js.map +1 -1
- package/dist/_chunks/document-preview.js.map +1 -1
- package/dist/_chunks/emoji-suggestion.js.map +1 -1
- package/dist/_chunks/emoji.js +2 -2
- package/dist/_chunks/emoji.js.map +1 -1
- package/dist/_chunks/field-state.js.map +1 -1
- package/dist/_chunks/grid-lines.js.map +1 -1
- package/dist/_chunks/image-preview.js.map +1 -1
- package/dist/_chunks/keybinding.js.map +1 -1
- package/dist/_chunks/link-context.js.map +1 -1
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/motion-provider.js.map +1 -1
- package/dist/_chunks/normalize-icon.js.map +1 -1
- package/dist/_chunks/oauth-button.js.map +1 -1
- package/dist/_chunks/popover.js.map +1 -1
- package/dist/_chunks/primitives.js +1123 -1153
- package/dist/_chunks/primitives.js.map +1 -1
- package/dist/_chunks/shared.js.map +1 -1
- package/dist/_chunks/success.js.map +1 -1
- package/dist/_chunks/tiptap.js +4283 -3460
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tooltip.js.map +1 -1
- package/dist/_chunks/tree-view.js +1 -1
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/_chunks/use-calendar.js.map +1 -1
- package/dist/_chunks/use-controllable-open.js.map +1 -1
- package/dist/_chunks/vendor-client.js +86 -59
- package/dist/_chunks/vendor-client.js.map +1 -1
- package/dist/_chunks/vendor-utils.js +555 -513
- package/dist/_chunks/vendor-utils.js.map +1 -1
- package/dist/ai/ai-command-provider.d.ts +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.js.map +1 -1
- package/dist/ai/blocks/block-shell.d.ts +1 -1
- package/dist/ai/blocks/block-shell.d.ts.map +1 -1
- package/dist/ai/blocks/block-table.d.ts +1 -1
- package/dist/ai/blocks/block-table.d.ts.map +1 -1
- package/dist/ai/blocks/confirm.d.ts +1 -1
- package/dist/ai/blocks/confirm.d.ts.map +1 -1
- package/dist/ai/blocks/divider.d.ts +1 -1
- package/dist/ai/blocks/divider.d.ts.map +1 -1
- package/dist/ai/blocks/error.d.ts +1 -1
- package/dist/ai/blocks/error.d.ts.map +1 -1
- package/dist/ai/blocks/error.js.map +1 -1
- package/dist/ai/blocks/info.d.ts +1 -1
- package/dist/ai/blocks/info.d.ts.map +1 -1
- package/dist/ai/blocks/loading.d.ts +1 -1
- package/dist/ai/blocks/loading.d.ts.map +1 -1
- package/dist/ai/blocks/stat-row.d.ts +1 -1
- package/dist/ai/blocks/stat-row.d.ts.map +1 -1
- package/dist/ai/blocks/success.d.ts +1 -1
- package/dist/ai/blocks/success.d.ts.map +1 -1
- package/dist/ai/blocks/text.d.ts +1 -1
- package/dist/ai/blocks/text.d.ts.map +1 -1
- package/dist/ai/blocks/text.js.map +1 -1
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.js.map +1 -1
- package/dist/ai/devadoot-icon.d.ts +1 -1
- package/dist/ai/devadoot-icon.d.ts.map +1 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/confirm-dialog.js.map +1 -1
- package/dist/composed/content-card.js.map +1 -1
- package/dist/composed/date-picker/index.js.map +1 -1
- package/dist/composed/deadline-indicator.js.map +1 -1
- package/dist/composed/emoji-picker.d.ts +2 -2
- package/dist/composed/emoji-picker.d.ts.map +1 -1
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/error-boundary.d.ts +1 -1
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/extensions/emoji-node.js.map +1 -1
- package/dist/composed/file-preview/audio-preview.d.ts +2 -1
- package/dist/composed/file-preview/audio-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/document-preview.d.ts +2 -1
- package/dist/composed/file-preview/document-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/embed-preview.d.ts +2 -1
- package/dist/composed/file-preview/embed-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/image-preview.d.ts +2 -1
- package/dist/composed/file-preview/image-preview.d.ts.map +1 -1
- package/dist/composed/file-preview/shared.d.ts +5 -5
- package/dist/composed/file-preview/shared.d.ts.map +1 -1
- package/dist/composed/file-preview/video-preview.d.ts +2 -1
- package/dist/composed/file-preview/video-preview.d.ts.map +1 -1
- package/dist/composed/file-preview.d.ts +1 -1
- package/dist/composed/file-preview.d.ts.map +1 -1
- package/dist/composed/file-preview.js.map +1 -1
- package/dist/composed/filter-bar.d.ts +2 -2
- package/dist/composed/filter-bar.d.ts.map +1 -1
- package/dist/composed/filter-bar.js.map +1 -1
- package/dist/composed/form-section.js.map +1 -1
- package/dist/composed/global-loading.js.map +1 -1
- package/dist/composed/inline-edit.js.map +1 -1
- package/dist/composed/lib/string-utils.js.map +1 -1
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/markdown-viewer.js.map +1 -1
- package/dist/composed/master-detail.d.ts +3 -3
- package/dist/composed/master-detail.d.ts.map +1 -1
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/member-picker.js.map +1 -1
- package/dist/composed/multi-select-popover.js.map +1 -1
- package/dist/composed/page-header.js.map +1 -1
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/responsive-modal.js +8 -4
- package/dist/composed/responsive-modal.js.map +1 -1
- package/dist/composed/rich-chat-input/attachment-strip.d.ts +2 -1
- package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/chat-toolbar.d.ts +17 -17
- package/dist/composed/rich-chat-input/chat-toolbar.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/recording-overlay.d.ts +2 -1
- package/dist/composed/rich-chat-input/recording-overlay.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/reply-banner.d.ts +2 -1
- package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
- package/dist/composed/rich-chat-input/schedule-send.d.ts +4 -3
- package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
- package/dist/composed/rich-chat-input.js +2 -1
- package/dist/composed/rich-chat-input.js.map +1 -1
- package/dist/composed/rich-text-editor.js +2 -1
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/composed/simple-tooltip.js.map +1 -1
- package/dist/composed/status-badge.js.map +1 -1
- package/dist/hooks/use-color-mode.js +2 -1
- package/dist/hooks/use-color-mode.js.map +1 -1
- package/dist/hooks/use-mobile.js.map +1 -1
- package/dist/hooks/use-touch-device.js.map +1 -1
- package/dist/hooks/use-viewport-height.js.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.js.map +1 -1
- package/dist/shell/app-command-palette.js.map +1 -1
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/command-registry.d.ts +1 -1
- package/dist/shell/command-registry.d.ts.map +1 -1
- package/dist/shell/command-registry.js.map +1 -1
- package/dist/shell/notification-center.js.map +1 -1
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/alert-dialog.js.map +1 -1
- package/dist/ui/alert.js.map +1 -1
- package/dist/ui/aspect-ratio.js.map +1 -1
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/avatar.d.ts +1 -1
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/badge-group.d.ts +1 -1
- package/dist/ui/badge-group.d.ts.map +1 -1
- package/dist/ui/badge-indicator.d.ts +1 -1
- package/dist/ui/badge-indicator.d.ts.map +1 -1
- package/dist/ui/badge-indicator.js.map +1 -1
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/breadcrumb.d.ts +2 -2
- package/dist/ui/breadcrumb.js.map +1 -1
- package/dist/ui/button-group.js.map +1 -1
- package/dist/ui/button-processing.d.ts +2 -1
- package/dist/ui/button-processing.d.ts.map +1 -1
- package/dist/ui/button-processing.js.map +1 -1
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.js +1 -1
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/charts/_internal/axes.d.ts +2 -1
- package/dist/ui/charts/_internal/axes.d.ts.map +1 -1
- package/dist/ui/charts/_internal/grid-lines.d.ts +2 -1
- package/dist/ui/charts/_internal/grid-lines.d.ts.map +1 -1
- package/dist/ui/charts/_internal/legend.d.ts +2 -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.js.map +1 -1
- package/dist/ui/charts/bar-chart.js.map +1 -1
- package/dist/ui/charts/gauge-chart.js.map +1 -1
- package/dist/ui/charts/line-chart.js.map +1 -1
- package/dist/ui/charts/pie-chart.js.map +1 -1
- package/dist/ui/charts/radar-chart.js.map +1 -1
- package/dist/ui/charts/sparkline.js +2 -2
- package/dist/ui/charts/sparkline.js.map +1 -1
- package/dist/ui/chat/date-separator.d.ts +2 -1
- package/dist/ui/chat/date-separator.d.ts.map +1 -1
- package/dist/ui/chat/message.d.ts +8 -8
- package/dist/ui/chat/message.d.ts.map +1 -1
- package/dist/ui/chat/typing-indicator.d.ts +2 -1
- package/dist/ui/chat/typing-indicator.d.ts.map +1 -1
- package/dist/ui/chat/unread-separator.d.ts +2 -1
- package/dist/ui/chat/unread-separator.d.ts.map +1 -1
- package/dist/ui/checkbox.js.map +1 -1
- package/dist/ui/code.js.map +1 -1
- package/dist/ui/collapsible.js.map +1 -1
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/color-swatch.js.map +1 -1
- package/dist/ui/combobox.js +15 -6
- package/dist/ui/combobox.js.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.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 +1 -1
- package/dist/ui/data-table-body.js.map +1 -1
- package/dist/ui/data-table-bulk-actions.d.ts +2 -1
- package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
- package/dist/ui/data-table-bulk-actions.js.map +1 -1
- package/dist/ui/data-table-card.d.ts +1 -1
- package/dist/ui/data-table-card.d.ts.map +1 -1
- 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.d.ts +2 -1
- package/dist/ui/data-table-header.d.ts.map +1 -1
- package/dist/ui/data-table-header.js.map +1 -1
- package/dist/ui/data-table-pagination.d.ts +2 -1
- package/dist/ui/data-table-pagination.d.ts.map +1 -1
- package/dist/ui/data-table-pagination.js.map +1 -1
- package/dist/ui/data-table-toolbar.d.ts +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 +1 -1
- package/dist/ui/data-table.d.ts.map +1 -1
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/devalok-grain.d.ts +2 -1
- package/dist/ui/devalok-grain.d.ts.map +1 -1
- package/dist/ui/devalok-grain.js.map +1 -1
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dot.js +1 -1
- package/dist/ui/dot.js.map +1 -1
- package/dist/ui/dropdown-menu.d.ts +1 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/hover-card.js.map +1 -1
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/icon-context.d.ts +1 -1
- package/dist/ui/icon-context.d.ts.map +1 -1
- package/dist/ui/icon-context.js.map +1 -1
- package/dist/ui/icon-group.js.map +1 -1
- package/dist/ui/icon.js.map +1 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/input-otp.js.map +1 -1
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/label.js.map +1 -1
- package/dist/ui/lib/bottom-sheet.d.ts +1 -1
- package/dist/ui/lib/bottom-sheet.d.ts.map +1 -1
- package/dist/ui/lib/date-utils.js.map +1 -1
- package/dist/ui/lib/link-context.d.ts +1 -1
- package/dist/ui/lib/link-context.d.ts.map +1 -1
- package/dist/ui/lib/motion.js.map +1 -1
- package/dist/ui/lib/utils.js.map +1 -1
- package/dist/ui/link.js.map +1 -1
- package/dist/ui/menubar.d.ts +1 -1
- package/dist/ui/menubar.js.map +1 -1
- package/dist/ui/navigation-menu.js +14 -9
- package/dist/ui/navigation-menu.js.map +1 -1
- package/dist/ui/number-input.js.map +1 -1
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/progress-ring.js.map +1 -1
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/radio.js.map +1 -1
- package/dist/ui/search-input.js.map +1 -1
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/separator.js.map +1 -1
- package/dist/ui/sheet.js.map +1 -1
- package/dist/ui/sidebar.js +1 -1
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/skeleton.js.map +1 -1
- package/dist/ui/slider.js.map +1 -1
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/stack.js.map +1 -1
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/stat-flash.d.ts +2 -1
- package/dist/ui/stat-flash.d.ts.map +1 -1
- package/dist/ui/stat-flash.js +1 -1
- package/dist/ui/stat-flash.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 +1 -1
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/surface.js.map +1 -1
- package/dist/ui/switch.d.ts +1 -1
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/table-row-link.js.map +1 -1
- package/dist/ui/table.js.map +1 -1
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/text.js.map +1 -1
- package/dist/ui/textarea.js.map +1 -1
- package/dist/ui/toast-registry.js.map +1 -1
- package/dist/ui/toast.d.ts +4 -4
- package/dist/ui/toast.d.ts.map +1 -1
- package/dist/ui/toast.js +5 -3
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toaster.js.map +1 -1
- package/dist/ui/toggle-group.js.map +1 -1
- package/dist/ui/toggle.js.map +1 -1
- package/dist/ui/tooltip.js.map +1 -1
- package/dist/ui/truncated-text.js.map +1 -1
- package/dist/ui/visually-hidden.js.map +1 -1
- package/llms.txt +1 -1
- package/mcp-manifest.json +1 -1
- package/package.json +21 -21
- package/skill/SKILL.md +1 -1
- package/skill/references/components.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-bulk-actions.js","names":[],"sources":["../../src/ui/data-table-bulk-actions.tsx"],"sourcesContent":["'use client'\n\nimport { IconX } from '@tabler/icons-react'\nimport { type Table } from '@tanstack/react-table'\nimport React from 'react'\n\nimport { Button } from './button'\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\n/** Bulk action definition for the floating action bar */\nexport interface BulkAction<TData> {\n label: string\n onClick: (selectedRows: TData[]) => void\n color?: 'accent' | 'error'\n disabled?: boolean\n}\n\n/**\n * Floating action bar shown when rows are selected.\n * Internal — not exported to consumers.\n */\nexport function DataTableBulkActions<TData>({\n table,\n selectedRows,\n bulkActions,\n}: {\n table: Table<TData>\n selectedRows: TData[]\n bulkActions: BulkAction<TData>[]\n}) {\n return (\n <div\n className={cn(\n 'fixed bottom-6 left-1/2 -translate-x-1/2 z-sticky',\n 'flex items-center gap-ds-04 px-ds-05 py-ds-03',\n 'rounded-overlay bg-surface-overlay shadow-floating',\n 'animate-in slide-in-from-bottom-2',\n )}\n role=\"toolbar\"\n aria-label=\"Bulk actions\"\n >\n <span className=\"text-ds-sm font-medium text-surface-fg whitespace-nowrap\">\n {selectedRows.length} selected\n </span>\n <div className=\"h-5 w-px bg-surface-border\" aria-hidden=\"true\" />\n {bulkActions.map((action) => (\n <Button\n key={action.label}\n size=\"sm\"\n variant={action.color === 'error' ? 'solid' : 'outline'}\n color={action.color === 'error' ? 'error' : undefined}\n disabled={action.disabled}\n onClick={() => action.onClick(selectedRows)}\n >\n {action.label}\n </Button>\n ))}\n <button\n type=\"button\"\n onClick={() => table.resetRowSelection()}\n aria-label=\"Clear selection\"\n className={cn(\n 'flex items-center justify-center p-ds-01',\n 'rounded-control-inner hover:bg-surface-raised transition-colors',\n 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n <Icon icon={IconX} size=\"sm\" />\n </button>\n </div>\n )\n}\n"],"mappings":";;;;;;;;AAsBA,SAAgB,EAA4B,EAC1C,UACA,iBACA,kBAKC;
|
|
1
|
+
{"version":3,"file":"data-table-bulk-actions.js","names":[],"sources":["../../src/ui/data-table-bulk-actions.tsx"],"sourcesContent":["'use client'\n\nimport { IconX } from '@tabler/icons-react'\nimport { type Table } from '@tanstack/react-table'\nimport React from 'react'\n\nimport { Button } from './button'\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\n/** Bulk action definition for the floating action bar */\nexport interface BulkAction<TData> {\n label: string\n onClick: (selectedRows: TData[]) => void\n color?: 'accent' | 'error'\n disabled?: boolean\n}\n\n/**\n * Floating action bar shown when rows are selected.\n * Internal — not exported to consumers.\n */\nexport function DataTableBulkActions<TData>({\n table,\n selectedRows,\n bulkActions,\n}: {\n table: Table<TData>\n selectedRows: TData[]\n bulkActions: BulkAction<TData>[]\n}) {\n return (\n <div\n className={cn(\n 'fixed bottom-6 left-1/2 -translate-x-1/2 z-sticky',\n 'flex items-center gap-ds-04 px-ds-05 py-ds-03',\n 'rounded-overlay bg-surface-overlay shadow-floating',\n 'animate-in slide-in-from-bottom-2',\n )}\n role=\"toolbar\"\n aria-label=\"Bulk actions\"\n >\n <span className=\"text-ds-sm font-medium text-surface-fg whitespace-nowrap\">\n {selectedRows.length} selected\n </span>\n <div className=\"h-5 w-px bg-surface-border\" aria-hidden=\"true\" />\n {bulkActions.map((action) => (\n <Button\n key={action.label}\n size=\"sm\"\n variant={action.color === 'error' ? 'solid' : 'outline'}\n color={action.color === 'error' ? 'error' : undefined}\n disabled={action.disabled}\n onClick={() => action.onClick(selectedRows)}\n >\n {action.label}\n </Button>\n ))}\n <button\n type=\"button\"\n onClick={() => table.resetRowSelection()}\n aria-label=\"Clear selection\"\n className={cn(\n 'flex items-center justify-center p-ds-01',\n 'rounded-control-inner hover:bg-surface-raised transition-colors',\n 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n <Icon icon={IconX} size=\"sm\" />\n </button>\n </div>\n )\n}\n"],"mappings":";;;;;;;;AAsBA,SAAgB,EAA4B,EAC1C,UACA,iBACA,kBAKC;CACD,OACE,kBAAC,OAAD;EACE,WAAW,EACT,qDACA,iDACA,sDACA,mCACF;EACA,MAAK;EACL,cAAW;YARb;GAUE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACG,EAAa,QAAO,WACjB;;GACN,kBAAC,OAAD;IAAK,WAAU;IAA6B,eAAY;GAAQ,CAAA;GAC/D,EAAY,KAAK,MAChB,kBAAC,GAAD;IAEE,MAAK;IACL,SAAS,EAAO,UAAU,UAAU,UAAU;IAC9C,OAAO,EAAO,UAAU,UAAU,UAAU,KAAA;IAC5C,UAAU,EAAO;IACjB,eAAe,EAAO,QAAQ,CAAY;cAEzC,EAAO;GACF,GARD,EAAO,KAQN,CACT;GACD,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAM,kBAAkB;IACvC,cAAW;IACX,WAAW,EACT,4CACA,mEACA,6CACF;cAEA,kBAAC,GAAD;KAAM,MAAM;KAAO,MAAK;IAAM,CAAA;GACxB,CAAA;EACL;;AAET"}
|
|
@@ -5,5 +5,5 @@ export declare function DataTableCards<TData>({ loading, skeletonRowCount, noRes
|
|
|
5
5
|
skeletonRowCount: number;
|
|
6
6
|
noResultsText?: string;
|
|
7
7
|
emptyState?: React.ReactNode;
|
|
8
|
-
}):
|
|
8
|
+
}): React.JSX.Element;
|
|
9
9
|
//# sourceMappingURL=data-table-card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-card.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-card.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAazB,wBAAgB,cAAc,CAAC,KAAK,EAAE,EACpC,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,UAAU,GACX,EAAE;IACD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B,
|
|
1
|
+
{"version":3,"file":"data-table-card.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-card.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAazB,wBAAgB,cAAc,CAAC,KAAK,EAAE,EACpC,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,UAAU,GACX,EAAE;IACD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B,qBAkHA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-card.js","names":[],"sources":["../../src/ui/data-table-card.tsx"],"sourcesContent":["'use client'\n\nimport { flexRender } from '@tanstack/react-table'\nimport React from 'react'\n\nimport { Card, CardContent } from './card'\nimport { Checkbox } from './checkbox'\nimport { useDataTableContext } from './data-table-context'\nimport { cn } from './lib/utils'\nimport { Skeleton } from './skeleton'\n\n// ── DataTableCards ─────────────────────────────────────────────\n// Renders rows as vertically stacked cards for small (< sm) viewports.\n// Consumes the same TanStack Table instance from context — sorting,\n// filtering, pagination, and selection all work identically.\n\nexport function DataTableCards<TData>({\n loading,\n skeletonRowCount,\n noResultsText,\n emptyState,\n}: {\n loading?: boolean\n skeletonRowCount: number\n noResultsText?: string\n emptyState?: React.ReactNode\n}) {\n const { table, selectable } = useDataTableContext<TData>()\n const rows = table.getRowModel().rows\n\n // Loading skeleton\n if (loading) {\n return (\n <div className=\"flex flex-col gap-ds-03\">\n {Array.from({ length: skeletonRowCount }, (_, i) => (\n <Card key={`card-skeleton-${i}`} size=\"sm\" variant=\"outline\">\n <CardContent>\n <Skeleton variant=\"text\" className=\"mb-ds-03 h-5 w-2/3\" animation=\"pulse\" />\n <div className=\"flex flex-col gap-ds-02\">\n <Skeleton variant=\"text\" className=\"h-4 w-full\" animation=\"pulse\" />\n <Skeleton variant=\"text\" className=\"h-4 w-3/4\" animation=\"pulse\" />\n <Skeleton variant=\"text\" className=\"h-4 w-1/2\" animation=\"pulse\" />\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )\n }\n\n // Empty state\n if (!rows.length) {\n return (\n <div className={cn('py-ds-07 text-center', !emptyState && 'text-surface-fg-subtle')}>\n {emptyState || noResultsText || 'No results.'}\n </div>\n )\n }\n\n return (\n <div className=\"flex flex-col gap-ds-03\" role=\"list\">\n {rows.map((row) => {\n const cells = row.getVisibleCells()\n // Skip internal columns (_select, _expand) for card content\n const contentCells = cells.filter(\n (cell) => cell.column.id !== '_select' && cell.column.id !== '_expand',\n )\n const primaryCell = contentCells[0]\n const restCells = contentCells.slice(1)\n const isSelected = row.getIsSelected()\n\n return (\n <Card\n key={row.id}\n role=\"listitem\"\n size=\"sm\"\n // outline, not default — a phone screen of stacked shadow cards\n // accumulates lift (make-kit dense-list rule).\n variant=\"outline\"\n className={cn(isSelected && 'ring-2 ring-accent-9')}\n >\n {/* Header row: primary field + optional selection checkbox */}\n <CardContent className=\"flex items-start justify-between gap-ds-03\">\n <div className=\"min-w-0 flex-1 font-medium text-surface-fg\">\n {primaryCell &&\n flexRender(primaryCell.column.columnDef.cell, primaryCell.getContext())}\n </div>\n {selectable && (\n <Checkbox\n size=\"sm\"\n checked={isSelected}\n disabled={!row.getCanSelect()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n className=\"shrink-0\"\n />\n )}\n </CardContent>\n\n {/* Label-value pairs for remaining columns, behind a full-width rule */}\n {restCells.length > 0 && (\n <>\n <div aria-hidden=\"true\" className=\"h-px w-full bg-surface-border-subtle\" />\n <CardContent className=\"flex flex-col gap-ds-01\">\n {restCells.map((cell) => {\n // Respect hideBelow column meta — skip hidden columns\n const meta = cell.column.columnDef.meta as\n | { hideBelow?: string }\n | undefined\n // In card mode on mobile, hideBelow='sm' columns are still useful\n // since we're showing all data in a card layout. Only skip if\n // the column is explicitly hidden via visibility toggle.\n if (meta?.hideBelow === 'md' || meta?.hideBelow === 'lg') {\n // These would normally be hidden at this breakpoint in table\n // mode too, so skip them in cards for consistency\n }\n\n // Derive header label text\n const header =\n typeof cell.column.columnDef.header === 'string'\n ? cell.column.columnDef.header\n : cell.column.id\n\n return (\n <div key={cell.id} className=\"flex justify-between gap-ds-03 text-ds-sm\">\n <span className=\"shrink-0 text-surface-fg-muted\">{header}</span>\n <span className=\"min-w-0 text-right text-surface-fg\">\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </span>\n </div>\n )\n })}\n </CardContent>\n </>\n )}\n </Card>\n )\n })}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAgB,EAAsB,EACpC,YACA,qBACA,kBACA,iBAMC;CACD,IAAM,EAAE,UAAO,kBAAe,
|
|
1
|
+
{"version":3,"file":"data-table-card.js","names":[],"sources":["../../src/ui/data-table-card.tsx"],"sourcesContent":["'use client'\n\nimport { flexRender } from '@tanstack/react-table'\nimport React from 'react'\n\nimport { Card, CardContent } from './card'\nimport { Checkbox } from './checkbox'\nimport { useDataTableContext } from './data-table-context'\nimport { cn } from './lib/utils'\nimport { Skeleton } from './skeleton'\n\n// ── DataTableCards ─────────────────────────────────────────────\n// Renders rows as vertically stacked cards for small (< sm) viewports.\n// Consumes the same TanStack Table instance from context — sorting,\n// filtering, pagination, and selection all work identically.\n\nexport function DataTableCards<TData>({\n loading,\n skeletonRowCount,\n noResultsText,\n emptyState,\n}: {\n loading?: boolean\n skeletonRowCount: number\n noResultsText?: string\n emptyState?: React.ReactNode\n}) {\n const { table, selectable } = useDataTableContext<TData>()\n const rows = table.getRowModel().rows\n\n // Loading skeleton\n if (loading) {\n return (\n <div className=\"flex flex-col gap-ds-03\">\n {Array.from({ length: skeletonRowCount }, (_, i) => (\n <Card key={`card-skeleton-${i}`} size=\"sm\" variant=\"outline\">\n <CardContent>\n <Skeleton variant=\"text\" className=\"mb-ds-03 h-5 w-2/3\" animation=\"pulse\" />\n <div className=\"flex flex-col gap-ds-02\">\n <Skeleton variant=\"text\" className=\"h-4 w-full\" animation=\"pulse\" />\n <Skeleton variant=\"text\" className=\"h-4 w-3/4\" animation=\"pulse\" />\n <Skeleton variant=\"text\" className=\"h-4 w-1/2\" animation=\"pulse\" />\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )\n }\n\n // Empty state\n if (!rows.length) {\n return (\n <div className={cn('py-ds-07 text-center', !emptyState && 'text-surface-fg-subtle')}>\n {emptyState || noResultsText || 'No results.'}\n </div>\n )\n }\n\n return (\n <div className=\"flex flex-col gap-ds-03\" role=\"list\">\n {rows.map((row) => {\n const cells = row.getVisibleCells()\n // Skip internal columns (_select, _expand) for card content\n const contentCells = cells.filter(\n (cell) => cell.column.id !== '_select' && cell.column.id !== '_expand',\n )\n const primaryCell = contentCells[0]\n const restCells = contentCells.slice(1)\n const isSelected = row.getIsSelected()\n\n return (\n <Card\n key={row.id}\n role=\"listitem\"\n size=\"sm\"\n // outline, not default — a phone screen of stacked shadow cards\n // accumulates lift (make-kit dense-list rule).\n variant=\"outline\"\n className={cn(isSelected && 'ring-2 ring-accent-9')}\n >\n {/* Header row: primary field + optional selection checkbox */}\n <CardContent className=\"flex items-start justify-between gap-ds-03\">\n <div className=\"min-w-0 flex-1 font-medium text-surface-fg\">\n {primaryCell &&\n flexRender(primaryCell.column.columnDef.cell, primaryCell.getContext())}\n </div>\n {selectable && (\n <Checkbox\n size=\"sm\"\n checked={isSelected}\n disabled={!row.getCanSelect()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n className=\"shrink-0\"\n />\n )}\n </CardContent>\n\n {/* Label-value pairs for remaining columns, behind a full-width rule */}\n {restCells.length > 0 && (\n <>\n <div aria-hidden=\"true\" className=\"h-px w-full bg-surface-border-subtle\" />\n <CardContent className=\"flex flex-col gap-ds-01\">\n {restCells.map((cell) => {\n // Respect hideBelow column meta — skip hidden columns\n const meta = cell.column.columnDef.meta as\n | { hideBelow?: string }\n | undefined\n // In card mode on mobile, hideBelow='sm' columns are still useful\n // since we're showing all data in a card layout. Only skip if\n // the column is explicitly hidden via visibility toggle.\n if (meta?.hideBelow === 'md' || meta?.hideBelow === 'lg') {\n // These would normally be hidden at this breakpoint in table\n // mode too, so skip them in cards for consistency\n }\n\n // Derive header label text\n const header =\n typeof cell.column.columnDef.header === 'string'\n ? cell.column.columnDef.header\n : cell.column.id\n\n return (\n <div key={cell.id} className=\"flex justify-between gap-ds-03 text-ds-sm\">\n <span className=\"shrink-0 text-surface-fg-muted\">{header}</span>\n <span className=\"min-w-0 text-right text-surface-fg\">\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </span>\n </div>\n )\n })}\n </CardContent>\n </>\n )}\n </Card>\n )\n })}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAgB,EAAsB,EACpC,YACA,qBACA,kBACA,iBAMC;CACD,IAAM,EAAE,UAAO,kBAAe,EAA2B,GACnD,IAAO,EAAM,YAAY,CAAC,CAAC;CA+BjC,OA5BI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,KAAK,EAAE,QAAQ,EAAiB,IAAI,GAAG,MAC5C,kBAAC,GAAD;GAAiC,MAAK;GAAK,SAAQ;aACjD,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;IAAU,SAAQ;IAAO,WAAU;IAAqB,WAAU;GAAS,CAAA,GAC3E,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAU,SAAQ;MAAO,WAAU;MAAa,WAAU;KAAS,CAAA;KACnE,kBAAC,GAAD;MAAU,SAAQ;MAAO,WAAU;MAAY,WAAU;KAAS,CAAA;KAClE,kBAAC,GAAD;MAAU,SAAQ;MAAO,WAAU;MAAY,WAAU;KAAS,CAAA;IAC/D;KACM,EAAA,CAAA;EACT,GATK,iBAAiB,GAStB,CACP;CACE,CAAA,IAKJ,EAAK,SASR,kBAAC,OAAD;EAAK,WAAU;EAA0B,MAAK;YAC3C,EAAK,KAAK,MAAQ;GAGjB,IAAM,IAFQ,EAAI,gBAEG,CAAA,CAAM,QACxB,MAAS,EAAK,OAAO,OAAO,aAAa,EAAK,OAAO,OAAO,SAC/D,GACM,IAAc,EAAa,IAC3B,IAAY,EAAa,MAAM,CAAC,GAChC,IAAa,EAAI,cAAc;GAErC,OACE,kBAAC,GAAD;IAEE,MAAK;IACL,MAAK;IAGL,SAAQ;IACR,WAAW,EAAG,KAAc,sBAAsB;cAPpD,CAUE,kBAAC,GAAD;KAAa,WAAU;eAAvB,CACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,KACC,EAAW,EAAY,OAAO,UAAU,MAAM,EAAY,WAAW,CAAC;KACrE,CAAA,GACJ,KACC,kBAAC,GAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU,CAAC,EAAI,aAAa;MAC5B,kBAAkB,MAAM,EAAI,eAAe,CAAC,CAAC,CAAC;MAC9C,cAAW;MACX,WAAU;KACX,CAAA,CAEQ;QAGZ,EAAU,SAAS,KAClB,kBAAA,GAAA,EAAA,UAAA,CACA,kBAAC,OAAD;KAAK,eAAY;KAAO,WAAU;IAAwC,CAAA,GAC1E,kBAAC,GAAD;KAAa,WAAU;eACpB,EAAU,KAAK,MAAS;MAEvB,IAAM,IAAO,EAAK,OAAO,UAAU;MAiBnC,OAXI,GAAM,cAAc,QAAQ,GAAM,WAYpC,kBAAC,OAAD;OAAmB,WAAU;iBAA7B,CACE,kBAAC,QAAD;QAAM,WAAU;kBANlB,OAAO,EAAK,OAAO,UAAU,UAAW,WACpC,EAAK,OAAO,UAAU,SACtB,EAAK,OAAO;OAIiD,CAAA,GAC/D,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAW,EAAK,OAAO,UAAU,MAAM,EAAK,WAAW,CAAC;OACrD,CAAA,CACH;SALK,EAAK,EAKV;KAET,CAAC;IACU,CAAA,CACX,EAAA,CAAA,CAEA;MA9DC,EAAI,EA8DL;EAEV,CAAC;CACE,CAAA,IArFH,kBAAC,OAAD;EAAK,WAAW,EAAG,wBAAwB,CAAC,KAAc,wBAAwB;YAC/E,KAAc,KAAiB;CAC7B,CAAA;AAqFX"}
|
|
@@ -46,7 +46,7 @@ export interface DataTableContextValue<TData = unknown> {
|
|
|
46
46
|
export declare function DataTableProvider<TData>({ children, value, }: {
|
|
47
47
|
children: React.ReactNode;
|
|
48
48
|
value: DataTableContextValue<TData>;
|
|
49
|
-
}):
|
|
49
|
+
}): React.JSX.Element;
|
|
50
50
|
export declare function useDataTableContext<TData = unknown>(): DataTableContextValue<TData>;
|
|
51
51
|
/** Compute sticky positioning styles for pinned columns */
|
|
52
52
|
export declare function getPinnedCellStyle(columnId: string, columnPinningState: ColumnPinningState): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-context.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA;AAIvE,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAS3E;AAED,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,4DACwB,CAAA;AAIzD,MAAM,WAAW,qBAAqB,CAAC,KAAK,GAAG,OAAO;IACpD,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACnB,yDAAyD;IACzD,UAAU,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC/C,kDAAkD;IAClD,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,iCAAiC;IACjC,QAAQ,EAAE,OAAO,CAAA;IACjB,6CAA6C;IAC7C,UAAU,EAAE,OAAO,CAAA;IACnB,wCAAwC;IACxC,QAAQ,EAAE,OAAO,CAAA;IACjB,uCAAuC;IACvC,UAAU,EAAE,OAAO,CAAA;IACnB,uCAAuC;IACvC,WAAW,EAAE,OAAO,CAAA;IACpB,uCAAuC;IACvC,UAAU,EAAE,OAAO,CAAA;IACnB,uBAAuB;IACvB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5B,2BAA2B;IAC3B,WAAW,EAAE,WAAW,CAAA;IACxB,uBAAuB;IACvB,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAA;IAC3C,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACzE,+CAA+C;IAC/C,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,KAAK,CAAC,SAAS,CAAA;IAChD,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;CAClC;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,EACvC,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAA;CACpC,
|
|
1
|
+
{"version":3,"file":"data-table-context.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA;AAIvE,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAS3E;AAED,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,4DACwB,CAAA;AAIzD,MAAM,WAAW,qBAAqB,CAAC,KAAK,GAAG,OAAO;IACpD,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACnB,yDAAyD;IACzD,UAAU,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC/C,kDAAkD;IAClD,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,iCAAiC;IACjC,QAAQ,EAAE,OAAO,CAAA;IACjB,6CAA6C;IAC7C,UAAU,EAAE,OAAO,CAAA;IACnB,wCAAwC;IACxC,QAAQ,EAAE,OAAO,CAAA;IACjB,uCAAuC;IACvC,UAAU,EAAE,OAAO,CAAA;IACnB,uCAAuC;IACvC,WAAW,EAAE,OAAO,CAAA;IACpB,uCAAuC;IACvC,UAAU,EAAE,OAAO,CAAA;IACnB,uBAAuB;IACvB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5B,2BAA2B;IAC3B,WAAW,EAAE,WAAW,CAAA;IACxB,uBAAuB;IACvB,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAA;IAC3C,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACzE,+CAA+C;IAC/C,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,KAAK,CAAC,SAAS,CAAA;IAChD,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;CAClC;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,EACvC,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAA;CACpC,qBAMA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAG,OAAO,KAGnC,qBAAqB,CAAC,KAAK,CAAC,CAC3C;AAID,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,kBAAkB;;WASZ,KAAK,CAAC,aAAa;EAU9C;AAED,uCAAuC;AACvC,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAClB,OAAO,CAYT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-context.js","names":[],"sources":["../../src/ui/data-table-context.tsx"],"sourcesContent":["'use client'\n\nimport { type ColumnPinningState, type Table } from '@tanstack/react-table'\nimport React from 'react'\n\n// ── Shared types ────────────────────────────────────────────────\n\n/** Editing state: which cell is currently in edit mode */\nexport type EditingCell = { rowIndex: number; columnId: string } | null\n\n// ── Utility functions ───────────────────────────────────────────\n\nexport function getColumnMetaClasses(meta?: Record<string, unknown>): string {\n if (!meta) return ''\n const classes: string[] = []\n if (meta.align === 'right') classes.push('text-right tabular-nums')\n if (meta.align === 'center') classes.push('text-center')\n if (meta.hideBelow === 'sm') classes.push('hidden sm:table-cell')\n if (meta.hideBelow === 'md') classes.push('hidden md:table-cell')\n if (meta.hideBelow === 'lg') classes.push('hidden lg:table-cell')\n return classes.join(' ')\n}\n\n/** Interactive element selectors for row click filtering */\nexport const INTERACTIVE_SELECTOR =\n 'button, a, input, select, textarea, [role=\"checkbox\"]'\n\n// ── Context ─────────────────────────────────────────────────────\n\nexport interface DataTableContextValue<TData = unknown> {\n table: Table<TData>\n /** All assembled columns (including _select, _expand) */\n allColumns: { id?: string; header?: unknown }[]\n /** Column pinning state for sticky positioning */\n columnPinningState: ColumnPinningState\n /** Whether sorting is enabled */\n sortable: boolean\n /** Whether per-column filters are enabled */\n filterable: boolean\n /** Whether inline editing is enabled */\n editable: boolean\n /** Whether row expansion is enabled */\n expandable: boolean\n /** Whether virtual rows are enabled */\n virtualRows: boolean\n /** Whether row selection is enabled */\n selectable: boolean\n /** Mobile view mode */\n mobileView: 'card' | 'table'\n /** Current editing cell */\n editingCell: EditingCell\n /** Set editing cell */\n setEditingCell: (cell: EditingCell) => void\n /** Callback when a cell value is edited */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void\n /** Render function for expanded row content */\n renderExpanded?: (row: TData) => React.ReactNode\n /** Row click handler */\n onRowClick?: (row: TData) => void\n}\n\nconst DataTableContext = React.createContext<DataTableContextValue | null>(null)\n\nexport function DataTableProvider<TData>({\n children,\n value,\n}: {\n children: React.ReactNode\n value: DataTableContextValue<TData>\n}) {\n return (\n <DataTableContext.Provider value={value as DataTableContextValue}>\n {children}\n </DataTableContext.Provider>\n )\n}\n\nexport function useDataTableContext<TData = unknown>() {\n const ctx = React.useContext(DataTableContext)\n if (!ctx) throw new Error('useDataTableContext must be used within DataTableProvider')\n return ctx as DataTableContextValue<TData>\n}\n\n// ── Shared helpers ──────────────────────────────────────────────\n\n/** Compute sticky positioning styles for pinned columns */\nexport function getPinnedCellStyle(\n columnId: string,\n columnPinningState: ColumnPinningState,\n) {\n const { left = [], right = [] } = columnPinningState\n const leftIndex = left.indexOf(columnId)\n const rightIndex = right.indexOf(columnId)\n\n if (leftIndex !== -1) {\n return {\n className: 'sticky bg-surface-base z-raised',\n style: { left: 0 } as React.CSSProperties,\n }\n }\n if (rightIndex !== -1) {\n return {\n className: 'sticky bg-surface-base z-raised',\n style: { right: 0 } as React.CSSProperties,\n }\n }\n return { className: '', style: {} as React.CSSProperties }\n}\n\n/** Check if a column allows editing */\nexport function isColumnEditable<TData>(\n columnId: string,\n editable: boolean,\n table: Table<TData>,\n): boolean {\n if (!editable) return false\n // Internal columns are never editable\n if (columnId === '_select' || columnId === '_expand') return false\n const col = table.getColumn(columnId)\n if (!col) return false\n const meta = col.columnDef.meta as\n | { enableEditing?: boolean }\n | undefined\n // Editable by default unless explicitly disabled\n if (meta?.enableEditing === false) return false\n return true\n}\n"],"mappings":";;;;AAYA,SAAgB,EAAqB,GAAwC;
|
|
1
|
+
{"version":3,"file":"data-table-context.js","names":[],"sources":["../../src/ui/data-table-context.tsx"],"sourcesContent":["'use client'\n\nimport { type ColumnPinningState, type Table } from '@tanstack/react-table'\nimport React from 'react'\n\n// ── Shared types ────────────────────────────────────────────────\n\n/** Editing state: which cell is currently in edit mode */\nexport type EditingCell = { rowIndex: number; columnId: string } | null\n\n// ── Utility functions ───────────────────────────────────────────\n\nexport function getColumnMetaClasses(meta?: Record<string, unknown>): string {\n if (!meta) return ''\n const classes: string[] = []\n if (meta.align === 'right') classes.push('text-right tabular-nums')\n if (meta.align === 'center') classes.push('text-center')\n if (meta.hideBelow === 'sm') classes.push('hidden sm:table-cell')\n if (meta.hideBelow === 'md') classes.push('hidden md:table-cell')\n if (meta.hideBelow === 'lg') classes.push('hidden lg:table-cell')\n return classes.join(' ')\n}\n\n/** Interactive element selectors for row click filtering */\nexport const INTERACTIVE_SELECTOR =\n 'button, a, input, select, textarea, [role=\"checkbox\"]'\n\n// ── Context ─────────────────────────────────────────────────────\n\nexport interface DataTableContextValue<TData = unknown> {\n table: Table<TData>\n /** All assembled columns (including _select, _expand) */\n allColumns: { id?: string; header?: unknown }[]\n /** Column pinning state for sticky positioning */\n columnPinningState: ColumnPinningState\n /** Whether sorting is enabled */\n sortable: boolean\n /** Whether per-column filters are enabled */\n filterable: boolean\n /** Whether inline editing is enabled */\n editable: boolean\n /** Whether row expansion is enabled */\n expandable: boolean\n /** Whether virtual rows are enabled */\n virtualRows: boolean\n /** Whether row selection is enabled */\n selectable: boolean\n /** Mobile view mode */\n mobileView: 'card' | 'table'\n /** Current editing cell */\n editingCell: EditingCell\n /** Set editing cell */\n setEditingCell: (cell: EditingCell) => void\n /** Callback when a cell value is edited */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void\n /** Render function for expanded row content */\n renderExpanded?: (row: TData) => React.ReactNode\n /** Row click handler */\n onRowClick?: (row: TData) => void\n}\n\nconst DataTableContext = React.createContext<DataTableContextValue | null>(null)\n\nexport function DataTableProvider<TData>({\n children,\n value,\n}: {\n children: React.ReactNode\n value: DataTableContextValue<TData>\n}) {\n return (\n <DataTableContext.Provider value={value as DataTableContextValue}>\n {children}\n </DataTableContext.Provider>\n )\n}\n\nexport function useDataTableContext<TData = unknown>() {\n const ctx = React.useContext(DataTableContext)\n if (!ctx) throw new Error('useDataTableContext must be used within DataTableProvider')\n return ctx as DataTableContextValue<TData>\n}\n\n// ── Shared helpers ──────────────────────────────────────────────\n\n/** Compute sticky positioning styles for pinned columns */\nexport function getPinnedCellStyle(\n columnId: string,\n columnPinningState: ColumnPinningState,\n) {\n const { left = [], right = [] } = columnPinningState\n const leftIndex = left.indexOf(columnId)\n const rightIndex = right.indexOf(columnId)\n\n if (leftIndex !== -1) {\n return {\n className: 'sticky bg-surface-base z-raised',\n style: { left: 0 } as React.CSSProperties,\n }\n }\n if (rightIndex !== -1) {\n return {\n className: 'sticky bg-surface-base z-raised',\n style: { right: 0 } as React.CSSProperties,\n }\n }\n return { className: '', style: {} as React.CSSProperties }\n}\n\n/** Check if a column allows editing */\nexport function isColumnEditable<TData>(\n columnId: string,\n editable: boolean,\n table: Table<TData>,\n): boolean {\n if (!editable) return false\n // Internal columns are never editable\n if (columnId === '_select' || columnId === '_expand') return false\n const col = table.getColumn(columnId)\n if (!col) return false\n const meta = col.columnDef.meta as\n | { enableEditing?: boolean }\n | undefined\n // Editable by default unless explicitly disabled\n if (meta?.enableEditing === false) return false\n return true\n}\n"],"mappings":";;;;AAYA,SAAgB,EAAqB,GAAwC;CAC3E,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAoB,CAAC;CAM3B,OALI,EAAK,UAAU,WAAS,EAAQ,KAAK,yBAAyB,GAC9D,EAAK,UAAU,YAAU,EAAQ,KAAK,aAAa,GACnD,EAAK,cAAc,QAAM,EAAQ,KAAK,sBAAsB,GAC5D,EAAK,cAAc,QAAM,EAAQ,KAAK,sBAAsB,GAC5D,EAAK,cAAc,QAAM,EAAQ,KAAK,sBAAsB,GACzD,EAAQ,KAAK,GAAG;AACzB;AAGA,IAAa,IACX,2DAoCI,IAAmB,EAAM,cAA4C,IAAI;AAE/E,SAAgB,EAAyB,EACvC,aACA,YAIC;CACD,OACE,kBAAC,EAAiB,UAAlB;EAAkC;EAC/B;CACwB,CAAA;AAE/B;AAEA,SAAgB,IAAuC;CACrD,IAAM,IAAM,EAAM,WAAW,CAAgB;CAC7C,IAAI,CAAC,GAAK,MAAU,MAAM,2DAA2D;CACrF,OAAO;AACT;AAKA,SAAgB,EACd,GACA,GACA;CACA,IAAM,EAAE,UAAO,CAAC,GAAG,WAAQ,CAAC,MAAM,GAC5B,IAAY,EAAK,QAAQ,CAAQ,GACjC,IAAa,EAAM,QAAQ,CAAQ;CAczC,OAZI,MAAc,KAMd,MAAe,KAMZ;EAAE,WAAW;EAAI,OAAO,CAAC;CAAyB,IALhD;EACL,WAAW;EACX,OAAO,EAAE,OAAO,EAAE;CACpB,IATO;EACL,WAAW;EACX,OAAO,EAAE,MAAM,EAAE;CACnB;AASJ;AAGA,SAAgB,EACd,GACA,GACA,GACS;CAGT,IAFI,CAAC,KAED,MAAa,aAAa,MAAa,WAAW,OAAO;CAC7D,IAAM,IAAM,EAAM,UAAU,CAAQ;CAOpC,OADA,EALI,CAAC,KACQ,EAAI,UAAU,MAIjB,kBAAkB;AAE9B"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { default as React } from 'react';
|
|
2
3
|
/**
|
|
3
4
|
* Renders the `<TableHeader>` block including sortable column headers
|
|
4
5
|
* and optional per-column filter inputs. Internal — not exported to consumers.
|
|
5
6
|
*/
|
|
6
7
|
declare function DataTableHeaderImpl({ stickyHeader }: {
|
|
7
8
|
stickyHeader?: boolean;
|
|
8
|
-
}):
|
|
9
|
+
}): React.JSX.Element;
|
|
9
10
|
export { DataTableHeaderImpl as DataTableHeader };
|
|
10
11
|
//# sourceMappingURL=data-table-header.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-header.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-header.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"data-table-header.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-header.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,MAAM,OAAO,CAAA;AAYzB;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,EAAE,YAAY,EAAE,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,qBAwJxE;AAED,OAAO,EAAE,mBAAmB,IAAI,eAAe,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-header.js","names":[],"sources":["../../src/ui/data-table-header.tsx"],"sourcesContent":["'use client'\n\nimport {\n IconArrowDown,\n IconArrowsSort,\n IconArrowUp,\n} from '@tabler/icons-react'\nimport { flexRender } from '@tanstack/react-table'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport React from 'react'\n\nimport {\n getColumnMetaClasses,\n getPinnedCellStyle,\n useDataTableContext,\n} from './data-table-context'\nimport { Icon } from './icon'\nimport { springs } from './lib/motion'\nimport { cn } from './lib/utils'\nimport { TableHead, TableHeader, TableRow } from './table'\n\n/**\n * Renders the `<TableHeader>` block including sortable column headers\n * and optional per-column filter inputs. Internal — not exported to consumers.\n */\nfunction DataTableHeaderImpl({ stickyHeader }: { stickyHeader?: boolean }) {\n const { table, sortable, filterable, columnPinningState } =\n useDataTableContext()\n\n return (\n <TableHeader\n className={cn(\n // surface-raised, not base — the table lives on a card; a base-colored\n // sticky bar would read as a grey stripe over the white surface.\n stickyHeader && 'sticky top-0 z-10 bg-surface-raised',\n )}\n >\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n const canSort = sortable && header.column.getCanSort()\n const sorted = header.column.getIsSorted()\n const pinned = getPinnedCellStyle(\n header.column.id,\n columnPinningState,\n )\n\n return (\n <TableHead\n key={header.id}\n className={cn(\n pinned.className,\n getColumnMetaClasses(\n header.column.columnDef.meta as Record<string, unknown>,\n ),\n )}\n style={pinned.style}\n aria-sort={\n canSort\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n {header.isPlaceholder ? null : canSort ? (\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-ds-01 font-medium',\n 'cursor-pointer select-none',\n '-ml-ds-01 rounded-control-inner px-ds-01 py-ds-01',\n 'hover:bg-surface-raised-hover transition-colors',\n )}\n onClick={header.column.getToggleSortingHandler()}\n aria-label={`Sort by ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id}`}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n <AnimatePresence mode=\"wait\" initial={false}>\n {sorted === 'asc' ? (\n <motion.span\n key=\"asc\"\n initial={{ opacity: 0, rotate: 90 }}\n animate={{ opacity: 1, rotate: 0 }}\n exit={{ opacity: 0, rotate: -90 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowUp}\n size=\"sm\"\n className=\"text-surface-fg-muted\"\n />\n </motion.span>\n ) : sorted === 'desc' ? (\n <motion.span\n key=\"desc\"\n initial={{ opacity: 0, rotate: -90 }}\n animate={{ opacity: 1, rotate: 0 }}\n exit={{ opacity: 0, rotate: 90 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowDown}\n size=\"sm\"\n className=\"text-surface-fg-muted\"\n />\n </motion.span>\n ) : (\n <motion.span\n key=\"unsorted\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowsSort}\n size=\"sm\"\n className=\"text-surface-fg-subtle\"\n />\n </motion.span>\n )}\n </AnimatePresence>\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </TableHead>\n )\n })}\n </TableRow>\n ))}\n\n {/* Column filter row */}\n {filterable &&\n table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={`${headerGroup.id}-filters`}>\n {headerGroup.headers.map((header) => (\n <TableHead key={`${header.id}-filter`} className=\"py-ds-01\">\n {header.isPlaceholder ||\n header.column.columnDef.enableColumnFilter === false ? null : (\n <input\n type=\"text\"\n value={\n (header.column.getFilterValue() as string) ?? ''\n }\n onChange={(e) =>\n header.column.setFilterValue(e.target.value)\n }\n placeholder={`Filter ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : ''}...`}\n aria-label={`Filter ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id}`}\n className={cn(\n 'h-ds-xs-plus w-full rounded-control',\n 'border border-surface-border-strong bg-surface-raised-hover',\n 'px-ds-02 text-ds-sm',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden focus:border-accent-7',\n )}\n />\n )}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n )\n}\n\nexport { DataTableHeaderImpl as DataTableHeader }\n"],"mappings":";;;;;;;;;;;;AAyBA,SAAS,EAAoB,EAAE,mBAA4C;CACzE,IAAM,EAAE,UAAO,aAAU,eAAY,0BACnC,
|
|
1
|
+
{"version":3,"file":"data-table-header.js","names":[],"sources":["../../src/ui/data-table-header.tsx"],"sourcesContent":["'use client'\n\nimport {\n IconArrowDown,\n IconArrowsSort,\n IconArrowUp,\n} from '@tabler/icons-react'\nimport { flexRender } from '@tanstack/react-table'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport React from 'react'\n\nimport {\n getColumnMetaClasses,\n getPinnedCellStyle,\n useDataTableContext,\n} from './data-table-context'\nimport { Icon } from './icon'\nimport { springs } from './lib/motion'\nimport { cn } from './lib/utils'\nimport { TableHead, TableHeader, TableRow } from './table'\n\n/**\n * Renders the `<TableHeader>` block including sortable column headers\n * and optional per-column filter inputs. Internal — not exported to consumers.\n */\nfunction DataTableHeaderImpl({ stickyHeader }: { stickyHeader?: boolean }) {\n const { table, sortable, filterable, columnPinningState } =\n useDataTableContext()\n\n return (\n <TableHeader\n className={cn(\n // surface-raised, not base — the table lives on a card; a base-colored\n // sticky bar would read as a grey stripe over the white surface.\n stickyHeader && 'sticky top-0 z-10 bg-surface-raised',\n )}\n >\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n const canSort = sortable && header.column.getCanSort()\n const sorted = header.column.getIsSorted()\n const pinned = getPinnedCellStyle(\n header.column.id,\n columnPinningState,\n )\n\n return (\n <TableHead\n key={header.id}\n className={cn(\n pinned.className,\n getColumnMetaClasses(\n header.column.columnDef.meta as Record<string, unknown>,\n ),\n )}\n style={pinned.style}\n aria-sort={\n canSort\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n {header.isPlaceholder ? null : canSort ? (\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-ds-01 font-medium',\n 'cursor-pointer select-none',\n '-ml-ds-01 rounded-control-inner px-ds-01 py-ds-01',\n 'hover:bg-surface-raised-hover transition-colors',\n )}\n onClick={header.column.getToggleSortingHandler()}\n aria-label={`Sort by ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id}`}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n <AnimatePresence mode=\"wait\" initial={false}>\n {sorted === 'asc' ? (\n <motion.span\n key=\"asc\"\n initial={{ opacity: 0, rotate: 90 }}\n animate={{ opacity: 1, rotate: 0 }}\n exit={{ opacity: 0, rotate: -90 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowUp}\n size=\"sm\"\n className=\"text-surface-fg-muted\"\n />\n </motion.span>\n ) : sorted === 'desc' ? (\n <motion.span\n key=\"desc\"\n initial={{ opacity: 0, rotate: -90 }}\n animate={{ opacity: 1, rotate: 0 }}\n exit={{ opacity: 0, rotate: 90 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowDown}\n size=\"sm\"\n className=\"text-surface-fg-muted\"\n />\n </motion.span>\n ) : (\n <motion.span\n key=\"unsorted\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon\n icon={IconArrowsSort}\n size=\"sm\"\n className=\"text-surface-fg-subtle\"\n />\n </motion.span>\n )}\n </AnimatePresence>\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </TableHead>\n )\n })}\n </TableRow>\n ))}\n\n {/* Column filter row */}\n {filterable &&\n table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={`${headerGroup.id}-filters`}>\n {headerGroup.headers.map((header) => (\n <TableHead key={`${header.id}-filter`} className=\"py-ds-01\">\n {header.isPlaceholder ||\n header.column.columnDef.enableColumnFilter === false ? null : (\n <input\n type=\"text\"\n value={\n (header.column.getFilterValue() as string) ?? ''\n }\n onChange={(e) =>\n header.column.setFilterValue(e.target.value)\n }\n placeholder={`Filter ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : ''}...`}\n aria-label={`Filter ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id}`}\n className={cn(\n 'h-ds-xs-plus w-full rounded-control',\n 'border border-surface-border-strong bg-surface-raised-hover',\n 'px-ds-02 text-ds-sm',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden focus:border-accent-7',\n )}\n />\n )}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n )\n}\n\nexport { DataTableHeaderImpl as DataTableHeader }\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Table } from '@tanstack/react-table';
|
|
3
|
+
import { default as React } from 'react';
|
|
3
4
|
/**
|
|
4
5
|
* Pagination controls: page size selector, prev/next buttons, page info.
|
|
5
6
|
* Internal — not exported to consumers.
|
|
@@ -9,5 +10,5 @@ export declare function DataTablePagination<TData>({ table, totalRowCount, useSe
|
|
|
9
10
|
totalRowCount: number;
|
|
10
11
|
useServerPagination: boolean;
|
|
11
12
|
pageSizeOptions?: number[];
|
|
12
|
-
}):
|
|
13
|
+
}): React.JSX.Element;
|
|
13
14
|
//# sourceMappingURL=data-table-pagination.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-pagination.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-pagination.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"data-table-pagination.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-pagination.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,EACzC,KAAK,EACL,aAAa,EACb,mBAAmB,EACnB,eAAe,GAChB,EAAE;IACD,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B,qBAwEA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-pagination.js","names":[],"sources":["../../src/ui/data-table-pagination.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'\nimport { type Table } from '@tanstack/react-table'\nimport React from 'react'\n\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\n/**\n * Pagination controls: page size selector, prev/next buttons, page info.\n * Internal — not exported to consumers.\n */\nexport function DataTablePagination<TData>({\n table,\n totalRowCount,\n useServerPagination,\n pageSizeOptions,\n}: {\n table: Table<TData>\n totalRowCount: number\n useServerPagination: boolean\n pageSizeOptions?: number[]\n}) {\n return (\n <div className=\"flex items-center justify-between px-ds-03 py-ds-04 border-t border-surface-border\">\n <span className=\"text-ds-sm text-surface-fg-muted\">\n {totalRowCount} total rows\n </span>\n <div className=\"flex items-center gap-ds-03\">\n {/* Page size selector */}\n {!useServerPagination && (\n <select\n value={table.getState().pagination.pageSize}\n onChange={(e) => {\n table.setPageSize(Number(e.target.value))\n }}\n aria-label=\"Rows per page\"\n className={cn(\n 'h-ds-sm rounded-control',\n 'border border-surface-border-strong bg-surface-raised-hover',\n 'px-ds-03 text-ds-sm',\n 'text-surface-fg',\n )}\n >\n {(pageSizeOptions ?? [10, 20, 50, 100]).map((size) => (\n <option key={size} value={size}>\n {size} rows\n </option>\n ))}\n </select>\n )}\n\n {/* Previous page button */}\n <button\n type=\"button\"\n disabled={!table.getCanPreviousPage()}\n onClick={() => table.previousPage()}\n aria-label=\"Previous page\"\n className={cn(\n 'h-ds-sm w-ds-sm flex items-center justify-center',\n 'rounded-control border border-surface-border-strong',\n 'enabled:hover:bg-surface-raised',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n 'transition-colors',\n )}\n >\n <Icon icon={IconChevronLeft} size=\"sm\" />\n </button>\n\n {/* Page info */}\n <span className=\"text-ds-sm text-surface-fg-muted\">\n Page {table.getState().pagination.pageIndex + 1} of{' '}\n {table.getPageCount()}\n </span>\n\n {/* Next page button */}\n <button\n type=\"button\"\n disabled={!table.getCanNextPage()}\n onClick={() => table.nextPage()}\n aria-label=\"Next page\"\n className={cn(\n 'h-ds-sm w-ds-sm flex items-center justify-center',\n 'rounded-control border border-surface-border-strong',\n 'enabled:hover:bg-surface-raised',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n 'transition-colors',\n )}\n >\n <Icon icon={IconChevronRight} size=\"sm\" />\n </button>\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,EAA2B,EACzC,UACA,kBACA,wBACA,sBAMC;
|
|
1
|
+
{"version":3,"file":"data-table-pagination.js","names":[],"sources":["../../src/ui/data-table-pagination.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'\nimport { type Table } from '@tanstack/react-table'\nimport React from 'react'\n\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\n/**\n * Pagination controls: page size selector, prev/next buttons, page info.\n * Internal — not exported to consumers.\n */\nexport function DataTablePagination<TData>({\n table,\n totalRowCount,\n useServerPagination,\n pageSizeOptions,\n}: {\n table: Table<TData>\n totalRowCount: number\n useServerPagination: boolean\n pageSizeOptions?: number[]\n}) {\n return (\n <div className=\"flex items-center justify-between px-ds-03 py-ds-04 border-t border-surface-border\">\n <span className=\"text-ds-sm text-surface-fg-muted\">\n {totalRowCount} total rows\n </span>\n <div className=\"flex items-center gap-ds-03\">\n {/* Page size selector */}\n {!useServerPagination && (\n <select\n value={table.getState().pagination.pageSize}\n onChange={(e) => {\n table.setPageSize(Number(e.target.value))\n }}\n aria-label=\"Rows per page\"\n className={cn(\n 'h-ds-sm rounded-control',\n 'border border-surface-border-strong bg-surface-raised-hover',\n 'px-ds-03 text-ds-sm',\n 'text-surface-fg',\n )}\n >\n {(pageSizeOptions ?? [10, 20, 50, 100]).map((size) => (\n <option key={size} value={size}>\n {size} rows\n </option>\n ))}\n </select>\n )}\n\n {/* Previous page button */}\n <button\n type=\"button\"\n disabled={!table.getCanPreviousPage()}\n onClick={() => table.previousPage()}\n aria-label=\"Previous page\"\n className={cn(\n 'h-ds-sm w-ds-sm flex items-center justify-center',\n 'rounded-control border border-surface-border-strong',\n 'enabled:hover:bg-surface-raised',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n 'transition-colors',\n )}\n >\n <Icon icon={IconChevronLeft} size=\"sm\" />\n </button>\n\n {/* Page info */}\n <span className=\"text-ds-sm text-surface-fg-muted\">\n Page {table.getState().pagination.pageIndex + 1} of{' '}\n {table.getPageCount()}\n </span>\n\n {/* Next page button */}\n <button\n type=\"button\"\n disabled={!table.getCanNextPage()}\n onClick={() => table.nextPage()}\n aria-label=\"Next page\"\n className={cn(\n 'h-ds-sm w-ds-sm flex items-center justify-center',\n 'rounded-control border border-surface-border-strong',\n 'enabled:hover:bg-surface-raised',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n 'transition-colors',\n )}\n >\n <Icon icon={IconChevronRight} size=\"sm\" />\n </button>\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,EAA2B,EACzC,UACA,kBACA,wBACA,sBAMC;CACD,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACG,GAAc,aACX;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEG,CAAC,KACA,kBAAC,UAAD;KACE,OAAO,EAAM,SAAS,CAAC,CAAC,WAAW;KACnC,WAAW,MAAM;MACf,EAAM,YAAY,OAAO,EAAE,OAAO,KAAK,CAAC;KAC1C;KACA,cAAW;KACX,WAAW,EACT,2BACA,+DACA,uBACA,iBACF;gBAEE,KAAmB;MAAC;MAAI;MAAI;MAAI;KAAG,EAAA,CAAG,KAAK,MAC3C,kBAAC,UAAD;MAAmB,OAAO;gBAA1B,CACG,GAAK,OACA;QAFK,CAEL,CACT;IACK,CAAA;IAIV,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,CAAC,EAAM,mBAAmB;KACpC,eAAe,EAAM,aAAa;KAClC,cAAW;KACX,WAAW,EACT,oDACA,uDACA,mCACA,gEACA,mBACF;eAEA,kBAAC,GAAD;MAAM,MAAM;MAAiB,MAAK;KAAM,CAAA;IAClC,CAAA;IAGR,kBAAC,QAAD;KAAM,WAAU;eAAhB;MAAmD;MAC3C,EAAM,SAAS,CAAC,CAAC,WAAW,YAAY;MAAE;MAAI;MACnD,EAAM,aAAa;KAChB;;IAGN,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,CAAC,EAAM,eAAe;KAChC,eAAe,EAAM,SAAS;KAC9B,cAAW;KACX,WAAW,EACT,oDACA,uDACA,mCACA,gEACA,mBACF;eAEA,kBAAC,GAAD;MAAM,MAAM;MAAkB,MAAK;KAAM,CAAA;IACnC,CAAA;GACL;IACF;;AAET"}
|
|
@@ -11,7 +11,7 @@ export interface DataTableToolbarProps<TData> extends Omit<React.HTMLAttributes<
|
|
|
11
11
|
onDensityChange: (density: Density) => void;
|
|
12
12
|
enableExport?: boolean;
|
|
13
13
|
}
|
|
14
|
-
export declare function DataTableToolbar<TData>({ table, globalFilter, globalFilterValue, onGlobalFilterChange, density, onDensityChange, enableExport, className, ...props }: DataTableToolbarProps<TData>):
|
|
14
|
+
export declare function DataTableToolbar<TData>({ table, globalFilter, globalFilterValue, onGlobalFilterChange, density, onDensityChange, enableExport, className, ...props }: DataTableToolbarProps<TData>): React.JSX.Element;
|
|
15
15
|
export declare namespace DataTableToolbar {
|
|
16
16
|
var displayName: string;
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-toolbar.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-toolbar.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAc9B,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;AAc5D,MAAM,WAAW,qBAAqB,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC1G,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;IACzB,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAyCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,EACtC,KAAK,EACL,YAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,OAAO,EACP,eAAe,EACf,YAAmB,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,qBAAqB,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"data-table-toolbar.d.ts","sourceRoot":"","sources":["../../src/ui/data-table-toolbar.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAc9B,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;AAc5D,MAAM,WAAW,qBAAqB,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC1G,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;IACzB,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAyCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,EACtC,KAAK,EACL,YAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,OAAO,EACP,eAAe,EACf,YAAmB,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,qBAAqB,CAAC,KAAK,CAAC,qBA8F9B;yBAxGe,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-toolbar.js","names":[],"sources":["../../src/ui/data-table-toolbar.tsx"],"sourcesContent":["'use client'\n\nimport {\n IconColumns3,\n IconDownload,\n IconSearch,\n IconTextResize,\n} from '@tabler/icons-react'\nimport { type Table } from '@tanstack/react-table'\nimport * as React from 'react'\n\nimport { Button } from './button'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './dropdown-menu'\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\nexport type Density = 'compact' | 'standard' | 'comfortable'\n\nconst densityLabels: Record<Density, string> = {\n compact: 'Compact',\n standard: 'Standard',\n comfortable: 'Comfortable',\n}\n\nconst densityCycle: Record<Density, Density> = {\n compact: 'standard',\n standard: 'comfortable',\n comfortable: 'compact',\n}\n\nexport interface DataTableToolbarProps<TData> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n table: Table<TData>\n globalFilter?: boolean\n globalFilterValue: string\n onGlobalFilterChange: (value: string) => void\n density: Density\n onDensityChange: (density: Density) => void\n enableExport?: boolean\n}\n\nconst toolbarIconClass = 'text-surface-fg-subtle'\n\nfunction exportToCsv<TData>(table: Table<TData>) {\n const headers = table\n .getAllLeafColumns()\n .filter((col) => col.getIsVisible() && col.id !== '_select')\n .map((col) => {\n const header = col.columnDef.header\n return typeof header === 'string' ? header : col.id\n })\n\n const rows = table.getFilteredRowModel().rows.map((row) =>\n table\n .getAllLeafColumns()\n .filter((col) => col.getIsVisible() && col.id !== '_select')\n .map((col) => {\n const value = row.getValue(col.id)\n const str = String(value ?? '')\n // Escape CSV: wrap in quotes if it contains comma, quote, or newline\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`\n }\n return str\n }),\n )\n\n const csvContent = [headers.join(','), ...rows.map((r) => r.join(','))].join(\n '\\n',\n )\n\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = 'table-export.csv'\n link.click()\n URL.revokeObjectURL(url)\n}\n\nexport function DataTableToolbar<TData>({\n table,\n globalFilter = false,\n globalFilterValue,\n onGlobalFilterChange,\n density,\n onDensityChange,\n enableExport = true,\n className,\n ...props\n}: DataTableToolbarProps<TData>) {\n const toggleableColumns = table\n .getAllColumns()\n .filter((col) => col.getCanHide() && col.id !== '_select')\n\n return (\n <div className={cn('flex items-center gap-ds-03 pb-ds-04', className)} {...props}>\n {/* Global search */}\n {globalFilter && (\n <div className=\"flex flex-1 items-center gap-ds-02\">\n <Icon icon={IconSearch} size=\"sm\" className={toolbarIconClass} />\n <input\n type=\"text\"\n value={globalFilterValue}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n placeholder=\"Search all columns...\"\n aria-label=\"Search all columns\"\n className={cn(\n 'flex-1 bg-transparent text-ds-md',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden',\n 'h-ds-sm',\n )}\n />\n </div>\n )}\n\n <div className=\"ml-auto flex items-center gap-ds-03\">\n {/* Column visibility dropdown */}\n {toggleableColumns.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n aria-label=\"Toggle column visibility\"\n >\n <Icon icon={IconColumns3} size=\"sm\" className={toolbarIconClass} />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-40\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {toggleableColumns.map((column) => {\n const headerDef = column.columnDef.header\n const label =\n typeof headerDef === 'string' ? headerDef : column.id\n return (\n <DropdownMenuCheckboxItem\n key={column.id}\n checked={column.getIsVisible()}\n onCheckedChange={(value) =>\n column.toggleVisibility(!!value)\n }\n >\n {label}\n </DropdownMenuCheckboxItem>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Density toggle */}\n <Button\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n onClick={() => onDensityChange(densityCycle[density])}\n aria-label={`Table density: ${densityLabels[density]}. Click to change.`}\n title={`Density: ${densityLabels[density]}`}\n >\n <Icon icon={IconTextResize} size=\"sm\" className={toolbarIconClass} />\n {densityLabels[density]}\n </Button>\n\n {/* CSV Export */}\n {enableExport && (\n <Button\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n onClick={() => exportToCsv(table)}\n aria-label=\"Export table as CSV\"\n >\n <Icon icon={IconDownload} size=\"sm\" className={toolbarIconClass} />\n Export\n </Button>\n )}\n </div>\n </div>\n )\n}\nDataTableToolbar.displayName = 'DataTableToolbar'\n"],"mappings":";;;;;;;;;AAyBA,IAAM,IAAyC;CAC7C,SAAS;CACT,UAAU;CACV,aAAa;
|
|
1
|
+
{"version":3,"file":"data-table-toolbar.js","names":[],"sources":["../../src/ui/data-table-toolbar.tsx"],"sourcesContent":["'use client'\n\nimport {\n IconColumns3,\n IconDownload,\n IconSearch,\n IconTextResize,\n} from '@tabler/icons-react'\nimport { type Table } from '@tanstack/react-table'\nimport * as React from 'react'\n\nimport { Button } from './button'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './dropdown-menu'\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\n\nexport type Density = 'compact' | 'standard' | 'comfortable'\n\nconst densityLabels: Record<Density, string> = {\n compact: 'Compact',\n standard: 'Standard',\n comfortable: 'Comfortable',\n}\n\nconst densityCycle: Record<Density, Density> = {\n compact: 'standard',\n standard: 'comfortable',\n comfortable: 'compact',\n}\n\nexport interface DataTableToolbarProps<TData> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n table: Table<TData>\n globalFilter?: boolean\n globalFilterValue: string\n onGlobalFilterChange: (value: string) => void\n density: Density\n onDensityChange: (density: Density) => void\n enableExport?: boolean\n}\n\nconst toolbarIconClass = 'text-surface-fg-subtle'\n\nfunction exportToCsv<TData>(table: Table<TData>) {\n const headers = table\n .getAllLeafColumns()\n .filter((col) => col.getIsVisible() && col.id !== '_select')\n .map((col) => {\n const header = col.columnDef.header\n return typeof header === 'string' ? header : col.id\n })\n\n const rows = table.getFilteredRowModel().rows.map((row) =>\n table\n .getAllLeafColumns()\n .filter((col) => col.getIsVisible() && col.id !== '_select')\n .map((col) => {\n const value = row.getValue(col.id)\n const str = String(value ?? '')\n // Escape CSV: wrap in quotes if it contains comma, quote, or newline\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`\n }\n return str\n }),\n )\n\n const csvContent = [headers.join(','), ...rows.map((r) => r.join(','))].join(\n '\\n',\n )\n\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = 'table-export.csv'\n link.click()\n URL.revokeObjectURL(url)\n}\n\nexport function DataTableToolbar<TData>({\n table,\n globalFilter = false,\n globalFilterValue,\n onGlobalFilterChange,\n density,\n onDensityChange,\n enableExport = true,\n className,\n ...props\n}: DataTableToolbarProps<TData>) {\n const toggleableColumns = table\n .getAllColumns()\n .filter((col) => col.getCanHide() && col.id !== '_select')\n\n return (\n <div className={cn('flex items-center gap-ds-03 pb-ds-04', className)} {...props}>\n {/* Global search */}\n {globalFilter && (\n <div className=\"flex flex-1 items-center gap-ds-02\">\n <Icon icon={IconSearch} size=\"sm\" className={toolbarIconClass} />\n <input\n type=\"text\"\n value={globalFilterValue}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n placeholder=\"Search all columns...\"\n aria-label=\"Search all columns\"\n className={cn(\n 'flex-1 bg-transparent text-ds-md',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden',\n 'h-ds-sm',\n )}\n />\n </div>\n )}\n\n <div className=\"ml-auto flex items-center gap-ds-03\">\n {/* Column visibility dropdown */}\n {toggleableColumns.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n aria-label=\"Toggle column visibility\"\n >\n <Icon icon={IconColumns3} size=\"sm\" className={toolbarIconClass} />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-40\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {toggleableColumns.map((column) => {\n const headerDef = column.columnDef.header\n const label =\n typeof headerDef === 'string' ? headerDef : column.id\n return (\n <DropdownMenuCheckboxItem\n key={column.id}\n checked={column.getIsVisible()}\n onCheckedChange={(value) =>\n column.toggleVisibility(!!value)\n }\n >\n {label}\n </DropdownMenuCheckboxItem>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Density toggle */}\n <Button\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n onClick={() => onDensityChange(densityCycle[density])}\n aria-label={`Table density: ${densityLabels[density]}. Click to change.`}\n title={`Density: ${densityLabels[density]}`}\n >\n <Icon icon={IconTextResize} size=\"sm\" className={toolbarIconClass} />\n {densityLabels[density]}\n </Button>\n\n {/* CSV Export */}\n {enableExport && (\n <Button\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n onClick={() => exportToCsv(table)}\n aria-label=\"Export table as CSV\"\n >\n <Icon icon={IconDownload} size=\"sm\" className={toolbarIconClass} />\n Export\n </Button>\n )}\n </div>\n </div>\n )\n}\nDataTableToolbar.displayName = 'DataTableToolbar'\n"],"mappings":"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"}
|
package/dist/ui/data-table.d.ts
CHANGED
|
@@ -147,7 +147,7 @@ export interface DataTableProps<TData, TValue> {
|
|
|
147
147
|
/** Render rows as stacked cards on small screens (below sm breakpoint). Default 'table'. */
|
|
148
148
|
mobileView?: 'card' | 'table';
|
|
149
149
|
}
|
|
150
|
-
export declare function DataTable<TData, TValue>({ columns, data, className, noResultsText, sortable, filterable, globalFilter, paginated, pageSize: initialPageSize, pageSizeOptions, selectable, onSelectionChange, toolbar, density: initialDensity, columnPinning: initialColumnPinning, editable, onCellEdit, expandable, renderExpanded, virtualRows, virtualRowHeight, maxHeight, onSort, emptyState, loading, selectedIds, selectableFilter, getRowId: getRowIdProp, pagination: serverPagination, singleExpand, stickyHeader, onRowClick, bulkActions, mobileView, }: DataTableProps<TData, TValue>):
|
|
150
|
+
export declare function DataTable<TData, TValue>({ columns, data, className, noResultsText, sortable, filterable, globalFilter, paginated, pageSize: initialPageSize, pageSizeOptions, selectable, onSelectionChange, toolbar, density: initialDensity, columnPinning: initialColumnPinning, editable, onCellEdit, expandable, renderExpanded, virtualRows, virtualRowHeight, maxHeight, onSort, emptyState, loading, selectedIds, selectableFilter, getRowId: getRowIdProp, pagination: serverPagination, singleExpand, stickyHeader, onRowClick, bulkActions, mobileView, }: DataTableProps<TData, TValue>): React.JSX.Element;
|
|
151
151
|
export declare namespace DataTable {
|
|
152
152
|
var displayName: string;
|
|
153
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/ui/data-table.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/ui/data-table.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table.js","names":[],"sources":["../../src/ui/data-table.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronRight, IconSearch } from '@tabler/icons-react'\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnPinningState,\n type ExpandedState,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type PaginationState,\n type Row,\n type RowData,\n type RowSelectionState,\n type SortingState,\n type TableState,\n type Updater,\n useReactTable,\n type VisibilityState,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { Checkbox } from './checkbox'\nimport { DataTableBody } from './data-table-body'\nimport { type BulkAction,DataTableBulkActions } from './data-table-bulk-actions'\nimport { DataTableCards } from './data-table-card'\nimport {\n DataTableProvider,\n type EditingCell,\n} from './data-table-context'\nimport { DataTableHeader } from './data-table-header'\nimport { DataTablePagination } from './data-table-pagination'\nimport { DataTableToolbar, type Density } from './data-table-toolbar'\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\nimport { Table } from './table'\n\n// Re-export public types so consumers' imports don't break\nexport type { BulkAction } from './data-table-bulk-actions'\n\ndeclare module '@tanstack/react-table' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface ColumnMeta<TData extends RowData, TValue> {\n align?: 'left' | 'center' | 'right'\n hideBelow?: 'sm' | 'md' | 'lg'\n }\n}\n\n/**\n * Props for DataTable — a feature-rich TanStack Table wrapper supporting sorting, filtering,\n * pagination, row selection, inline editing, row expansion, column pinning, and virtualization.\n *\n * All features are opt-in via boolean flags. The component manages its own internal state for\n * sorting, filtering, pagination, and selection — just pass `columns` and `data`.\n *\n * **Feature flags:** `sortable` | `filterable` | `globalFilter` | `paginated` | `selectable` |\n * `toolbar` | `editable` | `expandable` | `virtualRows`\n *\n * **Columns:** Use TanStack Table's `ColumnDef<TData, TValue>` type. Set\n * `meta: { enableEditing: false }` on a column to disable cell editing for that column.\n *\n * @example\n * // Minimal read-only table:\n * const columns: ColumnDef<User, string>[] = [\n * { accessorKey: 'name', header: 'Name' },\n * { accessorKey: 'email', header: 'Email' },\n * ]\n * <DataTable columns={columns} data={users} />\n *\n * @example\n * // Full-featured admin table with sorting, pagination, and selection:\n * <DataTable\n * columns={projectColumns}\n * data={projects}\n * sortable\n * paginated\n * pageSize={20}\n * selectable\n * onSelectionChange={(rows) => setSelectedProjects(rows)}\n * toolbar\n * />\n *\n * @example\n * // Virtualized table for large datasets (10k+ rows):\n * <DataTable\n * columns={logColumns}\n * data={allLogs}\n * virtualRows\n * virtualRowHeight={40}\n * maxHeight={500}\n * />\n *\n * @example\n * // Table with expandable rows for nested detail:\n * <DataTable\n * columns={orderColumns}\n * data={orders}\n * expandable\n * renderExpanded={(order) => <OrderLineItems items={order.lineItems} />}\n * />\n * // These are just a few ways — feel free to combine props creatively!\n */\n/**\n * A full-featured data table built on TanStack Table with sorting, filtering,\n * pagination, row selection, inline cell editing, expandable rows, column pinning,\n * a toolbar with density/export controls, and optional row virtualization.\n */\nexport interface DataTableProps<TData, TValue> {\n /** Column definitions passed to TanStack Table. */\n columns: ColumnDef<TData, TValue>[]\n /** Row data */\n data: TData[]\n /** Additional class name for the wrapper div */\n className?: string\n /** Text shown when the table has no rows */\n noResultsText?: string\n /** Enable column sorting (click headers to sort) */\n sortable?: boolean\n /** Enable per-column filter inputs below headers */\n filterable?: boolean\n /** Enable a global search input above the table */\n globalFilter?: boolean\n /** Enable pagination controls below the table */\n paginated?: boolean\n /** Number of rows per page when paginated (default 10) */\n pageSize?: number\n /** Options for the page size selector dropdown (default [10, 20, 50, 100]) */\n pageSizeOptions?: number[]\n /** Enable row selection with checkboxes */\n selectable?: boolean\n /** Callback when row selection changes */\n onSelectionChange?: (selectedRows: TData[]) => void\n /** Show toolbar above the table with column visibility, density, and export controls */\n toolbar?: boolean\n /** Row density — controls cell vertical padding */\n density?: Density\n /** Initial column pinning configuration */\n columnPinning?: { left?: string[]; right?: string[] }\n\n // --- Cell Editing ---\n /** Enable inline cell editing (double-click to edit) */\n editable?: boolean\n /** Callback when a cell value is edited */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void\n\n // --- Row Expansion ---\n /** Enable expandable rows with detail panels */\n expandable?: boolean\n /** Render function for expanded row content */\n renderExpanded?: (row: TData) => React.ReactNode\n\n // --- Virtualization ---\n /** Enable row virtualization for large datasets */\n virtualRows?: boolean\n /** Height of each virtual row in pixels (default 48) */\n virtualRowHeight?: number\n /** Maximum height of the scrollable container in pixels (default 600) */\n maxHeight?: number\n\n // --- Server-side sorting ---\n /** Callback for server-side sorting. When provided, sorting is manual (no client-side sort). */\n onSort?: (key: string, direction: 'asc' | 'desc' | false) => void\n\n // --- Empty state ---\n /** Custom ReactNode to render when data is empty (replaces noResultsText) */\n emptyState?: React.ReactNode\n\n // --- Loading ---\n /** Show shimmer skeleton rows instead of data */\n loading?: boolean\n\n // --- Controlled selection ---\n /** Controlled set of selected row IDs — syncs internal selection state */\n selectedIds?: Set<string>\n /** Per-row filter to determine if a row is selectable */\n selectableFilter?: (row: TData) => boolean\n /** Custom row ID getter */\n getRowId?: (row: TData) => string\n\n // --- Server-side pagination ---\n /** Server-side pagination config. When provided, pagination is manual. */\n pagination?: {\n page: number\n pageSize: number\n total: number\n onPageChange: (page: number) => void\n }\n\n // --- Single-expand mode ---\n /** When true, only one row can be expanded at a time */\n singleExpand?: boolean\n\n // --- Sticky header ---\n /** When true, the table header sticks to the top on scroll */\n stickyHeader?: boolean\n\n // --- Row click ---\n /** Callback when a row is clicked (not fired from interactive elements) */\n onRowClick?: (row: TData) => void\n\n // --- Bulk actions ---\n /** Actions shown in a floating bar when rows are selected */\n bulkActions?: BulkAction<TData>[]\n\n // --- Mobile view ---\n /** Render rows as stacked cards on small screens (below sm breakpoint). Default 'table'. */\n mobileView?: 'card' | 'table'\n}\n\nexport function DataTable<TData, TValue>({\n columns,\n data,\n className,\n noResultsText,\n sortable = false,\n filterable = false,\n globalFilter = false,\n paginated = false,\n pageSize: initialPageSize,\n pageSizeOptions,\n selectable = false,\n onSelectionChange,\n toolbar = false,\n density: initialDensity = 'standard',\n columnPinning: initialColumnPinning,\n editable = false,\n onCellEdit,\n expandable = false,\n renderExpanded,\n virtualRows = false,\n virtualRowHeight = 48,\n maxHeight = 600,\n onSort,\n emptyState,\n loading = false,\n selectedIds,\n selectableFilter,\n getRowId: getRowIdProp,\n pagination: serverPagination,\n singleExpand = false,\n stickyHeader = false,\n onRowClick,\n bulkActions,\n mobileView = 'table',\n}: DataTableProps<TData, TValue>) {\n // Detect below-sm viewport (640px) for card mode — separate from useIsMobile (768px)\n const [isBelowSm, setIsBelowSm] = useState(false)\n useEffect(() => {\n const mql = window.matchMedia('(max-width: 639px)')\n const onChange = () => setIsBelowSm(mql.matches)\n mql.addEventListener('change', onChange)\n setIsBelowSm(mql.matches)\n return () => mql.removeEventListener('change', onChange)\n }, [])\n\n const showCards = mobileView === 'card' && isBelowSm\n\n const [sorting, setSorting] = useState<SortingState>([])\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n const [globalFilterValue, setGlobalFilterValue] = useState('')\n const [paginationState, setPaginationState] = useState<PaginationState>({\n pageIndex: serverPagination ? serverPagination.page - 1 : 0,\n pageSize: serverPagination?.pageSize ?? initialPageSize ?? 10,\n })\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n const [columnPinningState, setColumnPinningState] =\n useState<ColumnPinningState>({\n left: initialColumnPinning?.left ?? [],\n right: initialColumnPinning?.right ?? [],\n })\n const [density, setDensity] = useState<Density>(initialDensity)\n const [editingCell, setEditingCell] = useState<EditingCell>(null)\n const [expanded, setExpanded] = useState<ExpandedState>({})\n\n // Ref for the virtual scroll container\n const scrollContainerRef = useRef<HTMLDivElement>(null)\n\n // Guard to prevent onSelectionChange firing when syncing from selectedIds prop\n const isSyncingFromPropRef = useRef(false)\n\n // Sync controlled selectedIds to internal rowSelection\n useEffect(() => {\n if (selectedIds) {\n isSyncingFromPropRef.current = true\n const newSelection: RowSelectionState = {}\n selectedIds.forEach((id) => {\n newSelection[id] = true\n })\n setRowSelection(newSelection)\n }\n }, [selectedIds])\n\n // Sync server pagination page to internal state\n useEffect(() => {\n if (serverPagination) {\n setPaginationState((prev) => ({\n ...prev,\n pageIndex: serverPagination.page - 1,\n pageSize: serverPagination.pageSize,\n }))\n }\n }, [serverPagination?.page, serverPagination?.pageSize]) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Server-side sorting handler\n const handleSortingChange = useCallback(\n (updater: Updater<SortingState>) => {\n setSorting((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (onSort) {\n if (next.length === 0 && prev.length > 0) {\n // Sorting cleared\n onSort(prev[0].id, false)\n } else if (next.length > 0) {\n onSort(next[0].id, next[0].desc ? 'desc' : 'asc')\n }\n }\n return next\n })\n },\n [onSort],\n )\n\n // Single-expand handler\n const handleExpandedChange = useCallback(\n (updater: Updater<ExpandedState>) => {\n setExpanded((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (!singleExpand) return next\n // If next is boolean true (expand all), just use it\n if (next === true) return next\n if (typeof next !== 'object') return next\n // Determine which row was just toggled on\n const prevKeys = typeof prev === 'object' ? Object.keys(prev).filter((k) => (prev as Record<string, boolean>)[k]) : []\n const nextKeys = Object.keys(next).filter((k) => (next as Record<string, boolean>)[k])\n // Find newly expanded row\n const newlyExpanded = nextKeys.filter((k) => !prevKeys.includes(k))\n if (newlyExpanded.length > 0) {\n // Keep only the most recently expanded row\n return { [newlyExpanded[newlyExpanded.length - 1]]: true } as ExpandedState\n }\n // If no new rows, means a row was collapsed — return as-is\n return next\n })\n },\n [singleExpand],\n )\n\n // Stable ref for server pagination callback to avoid useCallback invalidation\n const onPageChangeRef = useRef(serverPagination?.onPageChange)\n useEffect(() => {\n onPageChangeRef.current = serverPagination?.onPageChange\n }, [serverPagination?.onPageChange])\n\n // Server-side pagination handler\n const handlePaginationChange = useCallback(\n (updater: Updater<PaginationState>) => {\n setPaginationState((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (onPageChangeRef.current) {\n // Only call onPageChange if the page actually changed\n if (next.pageIndex !== prev.pageIndex) {\n onPageChangeRef.current(next.pageIndex + 1)\n }\n }\n return next\n })\n },\n [],\n )\n\n // Checkbox column prepended when selectable is enabled\n const selectColumn: ColumnDef<TData, unknown> = {\n id: '_select',\n header: ({ table: t }) => (\n <Checkbox\n size=\"sm\"\n checked={t.getIsAllPageRowsSelected()}\n indeterminate={t.getIsSomePageRowsSelected()}\n onCheckedChange={(v) => t.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all rows\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n size=\"sm\"\n checked={row.getIsSelected()}\n disabled={!row.getCanSelect()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n />\n ),\n enableSorting: false,\n enableColumnFilter: false,\n enableHiding: false,\n }\n\n // Expand toggle column — aria-expanded lives on the BUTTON (not the row),\n // in a dedicated column with a visually-hidden header (Roselli expando spec).\n const expandColumn: ColumnDef<TData, unknown> = {\n id: '_expand',\n header: () => <span className=\"sr-only\">Expand rows</span>,\n cell: ({ row }) => (\n <button\n type=\"button\"\n onClick={() => row.toggleExpanded()}\n aria-expanded={row.getIsExpanded()}\n aria-label={row.getIsExpanded() ? 'Collapse row' : 'Expand row'}\n className=\"flex items-center justify-center p-ds-01 rounded-control-inner hover:bg-surface-raised-hover transition-colors\"\n >\n <Icon\n icon={IconChevronRight}\n size=\"sm\"\n className={cn(\n 'transition-transform duration-fast-02 ease-productive-standard',\n row.getIsExpanded() && 'rotate-90',\n )}\n />\n </button>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n enableHiding: false,\n }\n\n // Assemble all columns in order: select?, expand?, ...user columns\n const allColumns = [\n ...(selectable ? [selectColumn] : []),\n ...(expandable ? [expandColumn] : []),\n ...columns,\n ]\n\n // Determine if using server-side pagination\n const useServerPagination = !!serverPagination\n const showPagination = paginated || useServerPagination\n\n // Build state object once — sorting and filtering contribute independently\n const tableState: Partial<TableState> = {\n columnVisibility,\n columnPinning: columnPinningState,\n }\n if (sortable) tableState.sorting = sorting\n if (filterable || globalFilter) {\n tableState.columnFilters = columnFilters\n tableState.globalFilter = globalFilterValue\n }\n if (showPagination) tableState.pagination = paginationState\n if (selectable) tableState.rowSelection = rowSelection\n if (expandable) tableState.expanded = expanded\n\n // Determine server-side sort mode\n const isServerSort = sortable && !!onSort\n\n const table = useReactTable({\n data,\n columns: allColumns,\n state: tableState,\n onColumnVisibilityChange: setColumnVisibility,\n onColumnPinningChange: setColumnPinningState,\n getCoreRowModel: getCoreRowModel(),\n ...(sortable && {\n onSortingChange: isServerSort ? handleSortingChange : setSorting,\n ...(isServerSort\n ? { manualSorting: true }\n : { getSortedRowModel: getSortedRowModel() }),\n }),\n ...((filterable || globalFilter) && {\n onColumnFiltersChange: setColumnFilters,\n onGlobalFilterChange: setGlobalFilterValue,\n getFilteredRowModel: getFilteredRowModel(),\n }),\n ...(showPagination && {\n onPaginationChange: useServerPagination\n ? handlePaginationChange\n : setPaginationState,\n ...(useServerPagination\n ? {\n manualPagination: true,\n pageCount: Math.ceil(\n serverPagination!.total / serverPagination!.pageSize,\n ),\n }\n : { getPaginationRowModel: getPaginationRowModel() }),\n }),\n ...(selectable && {\n onRowSelectionChange: setRowSelection,\n enableRowSelection: selectableFilter\n ? (row: Row<TData>) => selectableFilter(row.original)\n : true,\n }),\n ...(expandable && {\n onExpandedChange: singleExpand ? handleExpandedChange : setExpanded,\n getExpandedRowModel: getExpandedRowModel(),\n }),\n ...(getRowIdProp && {\n getRowId: (row: TData) => getRowIdProp(row),\n }),\n })\n\n // Stable refs to avoid effect re-fires from inline callbacks\n const onSelectionChangeRef = useRef(onSelectionChange)\n const getRowIdRef = useRef(getRowIdProp)\n useEffect(() => {\n onSelectionChangeRef.current = onSelectionChange\n getRowIdRef.current = getRowIdProp\n }, [onSelectionChange, getRowIdProp])\n\n // Fire selection callback when row selection changes (skip when syncing from prop)\n useEffect(() => {\n if (isSyncingFromPropRef.current) {\n isSyncingFromPropRef.current = false\n return\n }\n if (!onSelectionChangeRef.current) return\n const selectedRowIds = Object.keys(rowSelection).filter((k) => rowSelection[k])\n const selected = data.filter((_, i) => {\n const id = getRowIdRef.current ? getRowIdRef.current(data[i]) : String(i)\n return selectedRowIds.includes(id)\n })\n onSelectionChangeRef.current(selected)\n }, [rowSelection, data])\n\n const rows = table.getRowModel().rows\n\n // Virtualizer — always called but only active when virtualRows is true\n const virtualizer = useVirtualizer({\n count: virtualRows ? rows.length : 0,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: () => virtualRowHeight,\n overscan: 10,\n })\n\n // Number of skeleton rows for loading state\n const skeletonRowCount = serverPagination?.pageSize ?? initialPageSize ?? 5\n\n // Get selected rows for bulk actions (derived from rowSelection + data, not table instance)\n const selectedRows = useMemo(() => {\n if (!bulkActions || !selectable) return []\n const selectedRowIds = Object.keys(rowSelection).filter((k) => rowSelection[k])\n return data.filter((_, i) => {\n const id = getRowIdProp ? getRowIdProp(data[i]) : String(i)\n return selectedRowIds.includes(id)\n })\n }, [bulkActions, selectable, rowSelection, data, getRowIdProp])\n\n const hasSelectedRows = selectedRows.length > 0\n\n // Total rows for pagination display\n const totalRowCount = useServerPagination\n ? serverPagination!.total\n : table.getFilteredRowModel().rows.length\n\n // Build context value for sub-components\n const contextValue = useMemo(\n () => ({\n table,\n allColumns: allColumns.map((col) => ({\n id: (col as { id?: string }).id,\n header: (col as { header?: unknown }).header,\n })),\n columnPinningState,\n sortable,\n filterable,\n editable,\n expandable,\n virtualRows,\n selectable,\n mobileView,\n editingCell,\n setEditingCell,\n onCellEdit,\n renderExpanded,\n onRowClick,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n table,\n allColumns.length,\n columnPinningState,\n sortable,\n filterable,\n editable,\n expandable,\n virtualRows,\n selectable,\n mobileView,\n editingCell,\n onCellEdit,\n renderExpanded,\n onRowClick,\n ],\n )\n\n // Virtual items for body\n const virtualItems = virtualRows ? virtualizer.getVirtualItems() : undefined\n const totalVirtualSize = virtualRows ? virtualizer.getTotalSize() : undefined\n\n // Determine if we need a scroll wrapper for virtualization\n const tableContent = (\n <Table density={density} aria-busy={loading || undefined}>\n <DataTableHeader stickyHeader={stickyHeader} />\n <DataTableBody\n loading={loading}\n skeletonRowCount={skeletonRowCount}\n noResultsText={noResultsText}\n emptyState={emptyState}\n virtualItems={virtualItems}\n totalVirtualSize={totalVirtualSize}\n />\n </Table>\n )\n\n return (\n <DataTableProvider value={contextValue}>\n <div className={cn(className)}>\n {/* Toolbar */}\n {toolbar && (\n <DataTableToolbar\n table={table}\n globalFilter={globalFilter}\n globalFilterValue={globalFilterValue}\n onGlobalFilterChange={setGlobalFilterValue}\n density={density}\n onDensityChange={setDensity}\n />\n )}\n\n {/* Global search input — only show standalone when toolbar is disabled */}\n {globalFilter && !toolbar && (\n <div className=\"flex items-center gap-ds-03 pb-ds-04 border-b border-surface-border mb-ds-04\">\n <Icon icon={IconSearch} size=\"sm\" className=\"text-surface-fg-subtle\" />\n <input\n type=\"text\"\n value={globalFilterValue}\n onChange={(e) => setGlobalFilterValue(e.target.value)}\n placeholder=\"Search all columns...\"\n aria-label=\"Search all columns\"\n className={cn(\n 'flex-1 bg-transparent text-ds-md',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden',\n )}\n />\n </div>\n )}\n\n {/* Card view on small screens, or standard table */}\n {showCards ? (\n <DataTableCards\n loading={loading}\n skeletonRowCount={skeletonRowCount}\n noResultsText={noResultsText}\n emptyState={emptyState}\n />\n ) : virtualRows ? (\n <div\n ref={scrollContainerRef}\n style={{ maxHeight: `${maxHeight}px`, overflowY: 'auto' }}\n >\n {tableContent}\n </div>\n ) : (\n tableContent\n )}\n\n {/* Pagination controls */}\n {showPagination && (\n <DataTablePagination\n table={table}\n totalRowCount={totalRowCount}\n useServerPagination={useServerPagination}\n pageSizeOptions={pageSizeOptions}\n />\n )}\n\n {/* Bulk action bar */}\n {bulkActions && selectable && hasSelectedRows && (\n <DataTableBulkActions\n table={table}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n />\n )}\n </div>\n </DataTableProvider>\n )\n}\nDataTable.displayName = 'DataTable'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data-table.js","names":[],"sources":["../../src/ui/data-table.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronRight, IconSearch } from '@tabler/icons-react'\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnPinningState,\n type ExpandedState,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type PaginationState,\n type Row,\n type RowData,\n type RowSelectionState,\n type SortingState,\n type TableState,\n type Updater,\n useReactTable,\n type VisibilityState,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { Checkbox } from './checkbox'\nimport { DataTableBody } from './data-table-body'\nimport { type BulkAction,DataTableBulkActions } from './data-table-bulk-actions'\nimport { DataTableCards } from './data-table-card'\nimport {\n DataTableProvider,\n type EditingCell,\n} from './data-table-context'\nimport { DataTableHeader } from './data-table-header'\nimport { DataTablePagination } from './data-table-pagination'\nimport { DataTableToolbar, type Density } from './data-table-toolbar'\nimport { Icon } from './icon'\nimport { cn } from './lib/utils'\nimport { Table } from './table'\n\n// Re-export public types so consumers' imports don't break\nexport type { BulkAction } from './data-table-bulk-actions'\n\ndeclare module '@tanstack/react-table' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface ColumnMeta<TData extends RowData, TValue> {\n align?: 'left' | 'center' | 'right'\n hideBelow?: 'sm' | 'md' | 'lg'\n }\n}\n\n/**\n * Props for DataTable — a feature-rich TanStack Table wrapper supporting sorting, filtering,\n * pagination, row selection, inline editing, row expansion, column pinning, and virtualization.\n *\n * All features are opt-in via boolean flags. The component manages its own internal state for\n * sorting, filtering, pagination, and selection — just pass `columns` and `data`.\n *\n * **Feature flags:** `sortable` | `filterable` | `globalFilter` | `paginated` | `selectable` |\n * `toolbar` | `editable` | `expandable` | `virtualRows`\n *\n * **Columns:** Use TanStack Table's `ColumnDef<TData, TValue>` type. Set\n * `meta: { enableEditing: false }` on a column to disable cell editing for that column.\n *\n * @example\n * // Minimal read-only table:\n * const columns: ColumnDef<User, string>[] = [\n * { accessorKey: 'name', header: 'Name' },\n * { accessorKey: 'email', header: 'Email' },\n * ]\n * <DataTable columns={columns} data={users} />\n *\n * @example\n * // Full-featured admin table with sorting, pagination, and selection:\n * <DataTable\n * columns={projectColumns}\n * data={projects}\n * sortable\n * paginated\n * pageSize={20}\n * selectable\n * onSelectionChange={(rows) => setSelectedProjects(rows)}\n * toolbar\n * />\n *\n * @example\n * // Virtualized table for large datasets (10k+ rows):\n * <DataTable\n * columns={logColumns}\n * data={allLogs}\n * virtualRows\n * virtualRowHeight={40}\n * maxHeight={500}\n * />\n *\n * @example\n * // Table with expandable rows for nested detail:\n * <DataTable\n * columns={orderColumns}\n * data={orders}\n * expandable\n * renderExpanded={(order) => <OrderLineItems items={order.lineItems} />}\n * />\n * // These are just a few ways — feel free to combine props creatively!\n */\n/**\n * A full-featured data table built on TanStack Table with sorting, filtering,\n * pagination, row selection, inline cell editing, expandable rows, column pinning,\n * a toolbar with density/export controls, and optional row virtualization.\n */\nexport interface DataTableProps<TData, TValue> {\n /** Column definitions passed to TanStack Table. */\n columns: ColumnDef<TData, TValue>[]\n /** Row data */\n data: TData[]\n /** Additional class name for the wrapper div */\n className?: string\n /** Text shown when the table has no rows */\n noResultsText?: string\n /** Enable column sorting (click headers to sort) */\n sortable?: boolean\n /** Enable per-column filter inputs below headers */\n filterable?: boolean\n /** Enable a global search input above the table */\n globalFilter?: boolean\n /** Enable pagination controls below the table */\n paginated?: boolean\n /** Number of rows per page when paginated (default 10) */\n pageSize?: number\n /** Options for the page size selector dropdown (default [10, 20, 50, 100]) */\n pageSizeOptions?: number[]\n /** Enable row selection with checkboxes */\n selectable?: boolean\n /** Callback when row selection changes */\n onSelectionChange?: (selectedRows: TData[]) => void\n /** Show toolbar above the table with column visibility, density, and export controls */\n toolbar?: boolean\n /** Row density — controls cell vertical padding */\n density?: Density\n /** Initial column pinning configuration */\n columnPinning?: { left?: string[]; right?: string[] }\n\n // --- Cell Editing ---\n /** Enable inline cell editing (double-click to edit) */\n editable?: boolean\n /** Callback when a cell value is edited */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void\n\n // --- Row Expansion ---\n /** Enable expandable rows with detail panels */\n expandable?: boolean\n /** Render function for expanded row content */\n renderExpanded?: (row: TData) => React.ReactNode\n\n // --- Virtualization ---\n /** Enable row virtualization for large datasets */\n virtualRows?: boolean\n /** Height of each virtual row in pixels (default 48) */\n virtualRowHeight?: number\n /** Maximum height of the scrollable container in pixels (default 600) */\n maxHeight?: number\n\n // --- Server-side sorting ---\n /** Callback for server-side sorting. When provided, sorting is manual (no client-side sort). */\n onSort?: (key: string, direction: 'asc' | 'desc' | false) => void\n\n // --- Empty state ---\n /** Custom ReactNode to render when data is empty (replaces noResultsText) */\n emptyState?: React.ReactNode\n\n // --- Loading ---\n /** Show shimmer skeleton rows instead of data */\n loading?: boolean\n\n // --- Controlled selection ---\n /** Controlled set of selected row IDs — syncs internal selection state */\n selectedIds?: Set<string>\n /** Per-row filter to determine if a row is selectable */\n selectableFilter?: (row: TData) => boolean\n /** Custom row ID getter */\n getRowId?: (row: TData) => string\n\n // --- Server-side pagination ---\n /** Server-side pagination config. When provided, pagination is manual. */\n pagination?: {\n page: number\n pageSize: number\n total: number\n onPageChange: (page: number) => void\n }\n\n // --- Single-expand mode ---\n /** When true, only one row can be expanded at a time */\n singleExpand?: boolean\n\n // --- Sticky header ---\n /** When true, the table header sticks to the top on scroll */\n stickyHeader?: boolean\n\n // --- Row click ---\n /** Callback when a row is clicked (not fired from interactive elements) */\n onRowClick?: (row: TData) => void\n\n // --- Bulk actions ---\n /** Actions shown in a floating bar when rows are selected */\n bulkActions?: BulkAction<TData>[]\n\n // --- Mobile view ---\n /** Render rows as stacked cards on small screens (below sm breakpoint). Default 'table'. */\n mobileView?: 'card' | 'table'\n}\n\nexport function DataTable<TData, TValue>({\n columns,\n data,\n className,\n noResultsText,\n sortable = false,\n filterable = false,\n globalFilter = false,\n paginated = false,\n pageSize: initialPageSize,\n pageSizeOptions,\n selectable = false,\n onSelectionChange,\n toolbar = false,\n density: initialDensity = 'standard',\n columnPinning: initialColumnPinning,\n editable = false,\n onCellEdit,\n expandable = false,\n renderExpanded,\n virtualRows = false,\n virtualRowHeight = 48,\n maxHeight = 600,\n onSort,\n emptyState,\n loading = false,\n selectedIds,\n selectableFilter,\n getRowId: getRowIdProp,\n pagination: serverPagination,\n singleExpand = false,\n stickyHeader = false,\n onRowClick,\n bulkActions,\n mobileView = 'table',\n}: DataTableProps<TData, TValue>) {\n // Detect below-sm viewport (640px) for card mode — separate from useIsMobile (768px)\n const [isBelowSm, setIsBelowSm] = useState(false)\n useEffect(() => {\n const mql = window.matchMedia('(max-width: 639px)')\n const onChange = () => setIsBelowSm(mql.matches)\n mql.addEventListener('change', onChange)\n setIsBelowSm(mql.matches)\n return () => mql.removeEventListener('change', onChange)\n }, [])\n\n const showCards = mobileView === 'card' && isBelowSm\n\n const [sorting, setSorting] = useState<SortingState>([])\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n const [globalFilterValue, setGlobalFilterValue] = useState('')\n const [paginationState, setPaginationState] = useState<PaginationState>({\n pageIndex: serverPagination ? serverPagination.page - 1 : 0,\n pageSize: serverPagination?.pageSize ?? initialPageSize ?? 10,\n })\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n const [columnPinningState, setColumnPinningState] =\n useState<ColumnPinningState>({\n left: initialColumnPinning?.left ?? [],\n right: initialColumnPinning?.right ?? [],\n })\n const [density, setDensity] = useState<Density>(initialDensity)\n const [editingCell, setEditingCell] = useState<EditingCell>(null)\n const [expanded, setExpanded] = useState<ExpandedState>({})\n\n // Ref for the virtual scroll container\n const scrollContainerRef = useRef<HTMLDivElement>(null)\n\n // Guard to prevent onSelectionChange firing when syncing from selectedIds prop\n const isSyncingFromPropRef = useRef(false)\n\n // Sync controlled selectedIds to internal rowSelection\n useEffect(() => {\n if (selectedIds) {\n isSyncingFromPropRef.current = true\n const newSelection: RowSelectionState = {}\n selectedIds.forEach((id) => {\n newSelection[id] = true\n })\n setRowSelection(newSelection)\n }\n }, [selectedIds])\n\n // Sync server pagination page to internal state\n useEffect(() => {\n if (serverPagination) {\n setPaginationState((prev) => ({\n ...prev,\n pageIndex: serverPagination.page - 1,\n pageSize: serverPagination.pageSize,\n }))\n }\n }, [serverPagination?.page, serverPagination?.pageSize]) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Server-side sorting handler\n const handleSortingChange = useCallback(\n (updater: Updater<SortingState>) => {\n setSorting((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (onSort) {\n if (next.length === 0 && prev.length > 0) {\n // Sorting cleared\n onSort(prev[0].id, false)\n } else if (next.length > 0) {\n onSort(next[0].id, next[0].desc ? 'desc' : 'asc')\n }\n }\n return next\n })\n },\n [onSort],\n )\n\n // Single-expand handler\n const handleExpandedChange = useCallback(\n (updater: Updater<ExpandedState>) => {\n setExpanded((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (!singleExpand) return next\n // If next is boolean true (expand all), just use it\n if (next === true) return next\n if (typeof next !== 'object') return next\n // Determine which row was just toggled on\n const prevKeys = typeof prev === 'object' ? Object.keys(prev).filter((k) => (prev as Record<string, boolean>)[k]) : []\n const nextKeys = Object.keys(next).filter((k) => (next as Record<string, boolean>)[k])\n // Find newly expanded row\n const newlyExpanded = nextKeys.filter((k) => !prevKeys.includes(k))\n if (newlyExpanded.length > 0) {\n // Keep only the most recently expanded row\n return { [newlyExpanded[newlyExpanded.length - 1]]: true } as ExpandedState\n }\n // If no new rows, means a row was collapsed — return as-is\n return next\n })\n },\n [singleExpand],\n )\n\n // Stable ref for server pagination callback to avoid useCallback invalidation\n const onPageChangeRef = useRef(serverPagination?.onPageChange)\n useEffect(() => {\n onPageChangeRef.current = serverPagination?.onPageChange\n }, [serverPagination?.onPageChange])\n\n // Server-side pagination handler\n const handlePaginationChange = useCallback(\n (updater: Updater<PaginationState>) => {\n setPaginationState((prev) => {\n const next = typeof updater === 'function' ? updater(prev) : updater\n if (onPageChangeRef.current) {\n // Only call onPageChange if the page actually changed\n if (next.pageIndex !== prev.pageIndex) {\n onPageChangeRef.current(next.pageIndex + 1)\n }\n }\n return next\n })\n },\n [],\n )\n\n // Checkbox column prepended when selectable is enabled\n const selectColumn: ColumnDef<TData, unknown> = {\n id: '_select',\n header: ({ table: t }) => (\n <Checkbox\n size=\"sm\"\n checked={t.getIsAllPageRowsSelected()}\n indeterminate={t.getIsSomePageRowsSelected()}\n onCheckedChange={(v) => t.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all rows\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n size=\"sm\"\n checked={row.getIsSelected()}\n disabled={!row.getCanSelect()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n />\n ),\n enableSorting: false,\n enableColumnFilter: false,\n enableHiding: false,\n }\n\n // Expand toggle column — aria-expanded lives on the BUTTON (not the row),\n // in a dedicated column with a visually-hidden header (Roselli expando spec).\n const expandColumn: ColumnDef<TData, unknown> = {\n id: '_expand',\n header: () => <span className=\"sr-only\">Expand rows</span>,\n cell: ({ row }) => (\n <button\n type=\"button\"\n onClick={() => row.toggleExpanded()}\n aria-expanded={row.getIsExpanded()}\n aria-label={row.getIsExpanded() ? 'Collapse row' : 'Expand row'}\n className=\"flex items-center justify-center p-ds-01 rounded-control-inner hover:bg-surface-raised-hover transition-colors\"\n >\n <Icon\n icon={IconChevronRight}\n size=\"sm\"\n className={cn(\n 'transition-transform duration-fast-02 ease-productive-standard',\n row.getIsExpanded() && 'rotate-90',\n )}\n />\n </button>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n enableHiding: false,\n }\n\n // Assemble all columns in order: select?, expand?, ...user columns\n const allColumns = [\n ...(selectable ? [selectColumn] : []),\n ...(expandable ? [expandColumn] : []),\n ...columns,\n ]\n\n // Determine if using server-side pagination\n const useServerPagination = !!serverPagination\n const showPagination = paginated || useServerPagination\n\n // Build state object once — sorting and filtering contribute independently\n const tableState: Partial<TableState> = {\n columnVisibility,\n columnPinning: columnPinningState,\n }\n if (sortable) tableState.sorting = sorting\n if (filterable || globalFilter) {\n tableState.columnFilters = columnFilters\n tableState.globalFilter = globalFilterValue\n }\n if (showPagination) tableState.pagination = paginationState\n if (selectable) tableState.rowSelection = rowSelection\n if (expandable) tableState.expanded = expanded\n\n // Determine server-side sort mode\n const isServerSort = sortable && !!onSort\n\n const table = useReactTable({\n data,\n columns: allColumns,\n state: tableState,\n onColumnVisibilityChange: setColumnVisibility,\n onColumnPinningChange: setColumnPinningState,\n getCoreRowModel: getCoreRowModel(),\n ...(sortable && {\n onSortingChange: isServerSort ? handleSortingChange : setSorting,\n ...(isServerSort\n ? { manualSorting: true }\n : { getSortedRowModel: getSortedRowModel() }),\n }),\n ...((filterable || globalFilter) && {\n onColumnFiltersChange: setColumnFilters,\n onGlobalFilterChange: setGlobalFilterValue,\n getFilteredRowModel: getFilteredRowModel(),\n }),\n ...(showPagination && {\n onPaginationChange: useServerPagination\n ? handlePaginationChange\n : setPaginationState,\n ...(useServerPagination\n ? {\n manualPagination: true,\n pageCount: Math.ceil(\n serverPagination!.total / serverPagination!.pageSize,\n ),\n }\n : { getPaginationRowModel: getPaginationRowModel() }),\n }),\n ...(selectable && {\n onRowSelectionChange: setRowSelection,\n enableRowSelection: selectableFilter\n ? (row: Row<TData>) => selectableFilter(row.original)\n : true,\n }),\n ...(expandable && {\n onExpandedChange: singleExpand ? handleExpandedChange : setExpanded,\n getExpandedRowModel: getExpandedRowModel(),\n }),\n ...(getRowIdProp && {\n getRowId: (row: TData) => getRowIdProp(row),\n }),\n })\n\n // Stable refs to avoid effect re-fires from inline callbacks\n const onSelectionChangeRef = useRef(onSelectionChange)\n const getRowIdRef = useRef(getRowIdProp)\n useEffect(() => {\n onSelectionChangeRef.current = onSelectionChange\n getRowIdRef.current = getRowIdProp\n }, [onSelectionChange, getRowIdProp])\n\n // Fire selection callback when row selection changes (skip when syncing from prop)\n useEffect(() => {\n if (isSyncingFromPropRef.current) {\n isSyncingFromPropRef.current = false\n return\n }\n if (!onSelectionChangeRef.current) return\n const selectedRowIds = Object.keys(rowSelection).filter((k) => rowSelection[k])\n const selected = data.filter((_, i) => {\n const id = getRowIdRef.current ? getRowIdRef.current(data[i]) : String(i)\n return selectedRowIds.includes(id)\n })\n onSelectionChangeRef.current(selected)\n }, [rowSelection, data])\n\n const rows = table.getRowModel().rows\n\n // Virtualizer — always called but only active when virtualRows is true\n const virtualizer = useVirtualizer({\n count: virtualRows ? rows.length : 0,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: () => virtualRowHeight,\n overscan: 10,\n })\n\n // Number of skeleton rows for loading state\n const skeletonRowCount = serverPagination?.pageSize ?? initialPageSize ?? 5\n\n // Get selected rows for bulk actions (derived from rowSelection + data, not table instance)\n const selectedRows = useMemo(() => {\n if (!bulkActions || !selectable) return []\n const selectedRowIds = Object.keys(rowSelection).filter((k) => rowSelection[k])\n return data.filter((_, i) => {\n const id = getRowIdProp ? getRowIdProp(data[i]) : String(i)\n return selectedRowIds.includes(id)\n })\n }, [bulkActions, selectable, rowSelection, data, getRowIdProp])\n\n const hasSelectedRows = selectedRows.length > 0\n\n // Total rows for pagination display\n const totalRowCount = useServerPagination\n ? serverPagination!.total\n : table.getFilteredRowModel().rows.length\n\n // Build context value for sub-components\n const contextValue = useMemo(\n () => ({\n table,\n allColumns: allColumns.map((col) => ({\n id: (col as { id?: string }).id,\n header: (col as { header?: unknown }).header,\n })),\n columnPinningState,\n sortable,\n filterable,\n editable,\n expandable,\n virtualRows,\n selectable,\n mobileView,\n editingCell,\n setEditingCell,\n onCellEdit,\n renderExpanded,\n onRowClick,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n table,\n allColumns.length,\n columnPinningState,\n sortable,\n filterable,\n editable,\n expandable,\n virtualRows,\n selectable,\n mobileView,\n editingCell,\n onCellEdit,\n renderExpanded,\n onRowClick,\n ],\n )\n\n // Virtual items for body\n const virtualItems = virtualRows ? virtualizer.getVirtualItems() : undefined\n const totalVirtualSize = virtualRows ? virtualizer.getTotalSize() : undefined\n\n // Determine if we need a scroll wrapper for virtualization\n const tableContent = (\n <Table density={density} aria-busy={loading || undefined}>\n <DataTableHeader stickyHeader={stickyHeader} />\n <DataTableBody\n loading={loading}\n skeletonRowCount={skeletonRowCount}\n noResultsText={noResultsText}\n emptyState={emptyState}\n virtualItems={virtualItems}\n totalVirtualSize={totalVirtualSize}\n />\n </Table>\n )\n\n return (\n <DataTableProvider value={contextValue}>\n <div className={cn(className)}>\n {/* Toolbar */}\n {toolbar && (\n <DataTableToolbar\n table={table}\n globalFilter={globalFilter}\n globalFilterValue={globalFilterValue}\n onGlobalFilterChange={setGlobalFilterValue}\n density={density}\n onDensityChange={setDensity}\n />\n )}\n\n {/* Global search input — only show standalone when toolbar is disabled */}\n {globalFilter && !toolbar && (\n <div className=\"flex items-center gap-ds-03 pb-ds-04 border-b border-surface-border mb-ds-04\">\n <Icon icon={IconSearch} size=\"sm\" className=\"text-surface-fg-subtle\" />\n <input\n type=\"text\"\n value={globalFilterValue}\n onChange={(e) => setGlobalFilterValue(e.target.value)}\n placeholder=\"Search all columns...\"\n aria-label=\"Search all columns\"\n className={cn(\n 'flex-1 bg-transparent text-ds-md',\n 'text-surface-fg placeholder:text-surface-fg-subtle',\n 'outline-hidden',\n )}\n />\n </div>\n )}\n\n {/* Card view on small screens, or standard table */}\n {showCards ? (\n <DataTableCards\n loading={loading}\n skeletonRowCount={skeletonRowCount}\n noResultsText={noResultsText}\n emptyState={emptyState}\n />\n ) : virtualRows ? (\n <div\n ref={scrollContainerRef}\n style={{ maxHeight: `${maxHeight}px`, overflowY: 'auto' }}\n >\n {tableContent}\n </div>\n ) : (\n tableContent\n )}\n\n {/* Pagination controls */}\n {showPagination && (\n <DataTablePagination\n table={table}\n totalRowCount={totalRowCount}\n useServerPagination={useServerPagination}\n pageSizeOptions={pageSizeOptions}\n />\n )}\n\n {/* Bulk action bar */}\n {bulkActions && selectable && hasSelectedRows && (\n <DataTableBulkActions\n table={table}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n />\n )}\n </div>\n </DataTableProvider>\n )\n}\nDataTable.displayName = 'DataTable'\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
export type GrainIntensity = 'subtle' | 'medium' | 'heavy';
|
|
3
4
|
export interface DevalokGrainProps {
|
|
4
5
|
/** Grain intensity level. Default: 'subtle' */
|
|
@@ -74,7 +75,7 @@ export interface DevalokGrainProps {
|
|
|
74
75
|
* <h1 className="relative z-[2]">Hero</h1>
|
|
75
76
|
* </div>
|
|
76
77
|
*/
|
|
77
|
-
export declare function DevalokGrain({ intensity, surface, sheen, tint, animated, hoverIntensify, }: DevalokGrainProps):
|
|
78
|
+
export declare function DevalokGrain({ intensity, surface, sheen, tint, animated, hoverIntensify, }: DevalokGrainProps): React.JSX.Element;
|
|
78
79
|
export declare namespace DevalokGrain {
|
|
79
80
|
var displayName: string;
|
|
80
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devalok-grain.d.ts","sourceRoot":"","sources":["../../src/ui/devalok-grain.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"devalok-grain.d.ts","sourceRoot":"","sources":["../../src/ui/devalok-grain.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAc1D,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAoB,EACpB,OAAiB,EACjB,KAAa,EACb,IAAI,EACJ,QAAgB,EAChB,cAAsB,GACvB,EAAE,iBAAiB,qBAsEnB;yBA7Ee,YAAY"}
|