@kodffe/ui 0.0.0-stage → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.js +11 -0
- package/dist/accordion/accordion.d.ts +44 -0
- package/dist/accordion/accordion.js +84 -0
- package/dist/accordion/accordion.js.map +1 -0
- package/dist/alert/alert.d.ts +17 -0
- package/dist/alert/alert.js +59 -0
- package/dist/alert/alert.js.map +1 -0
- package/dist/app-shell/app-footer.d.ts +29 -0
- package/dist/app-shell/app-footer.js +39 -0
- package/dist/app-shell/app-footer.js.map +1 -0
- package/dist/app-shell/app-shell-context.d.ts +10 -0
- package/dist/app-shell/app-shell-context.js +12 -0
- package/dist/app-shell/app-shell-context.js.map +1 -0
- package/dist/app-shell/app-shell.d.ts +42 -0
- package/dist/app-shell/app-shell.js +191 -0
- package/dist/app-shell/app-shell.js.map +1 -0
- package/dist/app-shell/floating-actions.d.ts +19 -0
- package/dist/app-shell/floating-actions.js +59 -0
- package/dist/app-shell/floating-actions.js.map +1 -0
- package/dist/app-shell/workspace-switcher.d.ts +25 -0
- package/dist/app-shell/workspace-switcher.js +82 -0
- package/dist/app-shell/workspace-switcher.js.map +1 -0
- package/dist/badge/badge.d.ts +19 -0
- package/dist/badge/badge.js +59 -0
- package/dist/badge/badge.js.map +1 -0
- package/dist/banner/banner.d.ts +22 -0
- package/dist/banner/banner.js +80 -0
- package/dist/banner/banner.js.map +1 -0
- package/dist/breadcrumbs/breadcrumbs.d.ts +18 -0
- package/dist/breadcrumbs/breadcrumbs.js +45 -0
- package/dist/breadcrumbs/breadcrumbs.js.map +1 -0
- package/dist/button/button.d.ts +38 -0
- package/dist/button/button.js +83 -0
- package/dist/button/button.js.map +1 -0
- package/dist/card/card.d.ts +159 -0
- package/dist/card/card.js +390 -0
- package/dist/card/card.js.map +1 -0
- package/dist/card/insight-card.d.ts +19 -0
- package/dist/card/insight-card.js +51 -0
- package/dist/card/insight-card.js.map +1 -0
- package/dist/card/integration-card.d.ts +19 -0
- package/dist/card/integration-card.js +70 -0
- package/dist/card/integration-card.js.map +1 -0
- package/dist/charts/charts.d.ts +75 -0
- package/dist/charts/charts.js +453 -0
- package/dist/charts/charts.js.map +1 -0
- package/dist/choice/choice.d.ts +39 -0
- package/dist/choice/choice.js +143 -0
- package/dist/choice/choice.js.map +1 -0
- package/dist/combobox/combobox.d.ts +46 -0
- package/dist/combobox/combobox.js +196 -0
- package/dist/combobox/combobox.js.map +1 -0
- package/dist/command-palette/command-palette.d.ts +35 -0
- package/dist/command-palette/command-palette.js +164 -0
- package/dist/command-palette/command-palette.js.map +1 -0
- package/dist/confirm-dialog/confirm-dialog.d.ts +37 -0
- package/dist/confirm-dialog/confirm-dialog.js +106 -0
- package/dist/confirm-dialog/confirm-dialog.js.map +1 -0
- package/dist/content/assistant.d.ts +86 -0
- package/dist/content/assistant.js +213 -0
- package/dist/content/assistant.js.map +1 -0
- package/dist/content/content.d.ts +45 -0
- package/dist/content/content.js +136 -0
- package/dist/content/content.js.map +1 -0
- package/dist/data-display/avatar-sizes.d.ts +8 -0
- package/dist/data-display/avatar-sizes.js +12 -0
- package/dist/data-display/avatar-sizes.js.map +1 -0
- package/dist/data-display/avatar.d.ts +21 -0
- package/dist/data-display/avatar.js +53 -0
- package/dist/data-display/avatar.js.map +1 -0
- package/dist/data-display/chip.d.ts +20 -0
- package/dist/data-display/chip.js +64 -0
- package/dist/data-display/chip.js.map +1 -0
- package/dist/data-display/code-block.d.ts +14 -0
- package/dist/data-display/code-block.js +50 -0
- package/dist/data-display/code-block.js.map +1 -0
- package/dist/data-display/data-display.d.ts +73 -0
- package/dist/data-display/data-display.js +227 -0
- package/dist/data-display/data-display.js.map +1 -0
- package/dist/data-display/insights.d.ts +120 -0
- package/dist/data-display/insights.js +220 -0
- package/dist/data-display/insights.js.map +1 -0
- package/dist/data-table/cells.d.ts +86 -0
- package/dist/data-table/cells.js +163 -0
- package/dist/data-table/cells.js.map +1 -0
- package/dist/data-table/data-table.d.ts +112 -0
- package/dist/data-table/data-table.js +558 -0
- package/dist/data-table/data-table.js.map +1 -0
- package/dist/date-picker/date-picker.d.ts +61 -0
- package/dist/date-picker/date-picker.js +309 -0
- package/dist/date-picker/date-picker.js.map +1 -0
- package/dist/drawer/drawer.d.ts +32 -0
- package/dist/drawer/drawer.js +72 -0
- package/dist/drawer/drawer.js.map +1 -0
- package/dist/empty-state/empty-state.d.ts +25 -0
- package/dist/empty-state/empty-state.js +78 -0
- package/dist/empty-state/empty-state.js.map +1 -0
- package/dist/error-state/error-state.d.ts +19 -0
- package/dist/error-state/error-state.js +56 -0
- package/dist/error-state/error-state.js.map +1 -0
- package/dist/event-calendar/calendar-logic.test.d.ts +1 -0
- package/dist/event-calendar/dates.d.ts +35 -0
- package/dist/event-calendar/dates.js +55 -0
- package/dist/event-calendar/dates.js.map +1 -0
- package/dist/event-calendar/event-calendar.d.ts +125 -0
- package/dist/event-calendar/event-calendar.js +795 -0
- package/dist/event-calendar/event-calendar.js.map +1 -0
- package/dist/event-calendar/event-details.d.ts +50 -0
- package/dist/event-calendar/event-details.js +124 -0
- package/dist/event-calendar/event-details.js.map +1 -0
- package/dist/event-calendar/layout.d.ts +48 -0
- package/dist/event-calendar/layout.js +55 -0
- package/dist/event-calendar/layout.js.map +1 -0
- package/dist/file-upload/file-upload.d.ts +70 -0
- package/dist/file-upload/file-upload.js +307 -0
- package/dist/file-upload/file-upload.js.map +1 -0
- package/dist/filters/filters.d.ts +48 -0
- package/dist/filters/filters.js +103 -0
- package/dist/filters/filters.js.map +1 -0
- package/dist/form-field/form-field.d.ts +39 -0
- package/dist/form-field/form-field.js +88 -0
- package/dist/form-field/form-field.js.map +1 -0
- package/dist/hover-card/hover-card.d.ts +15 -0
- package/dist/hover-card/hover-card.js +27 -0
- package/dist/hover-card/hover-card.js.map +1 -0
- package/dist/hover-card/person-hover-card.d.ts +26 -0
- package/dist/hover-card/person-hover-card.js +85 -0
- package/dist/hover-card/person-hover-card.js.map +1 -0
- package/dist/icon/icon-tile.d.ts +20 -0
- package/dist/icon/icon-tile.js +55 -0
- package/dist/icon/icon-tile.js.map +1 -0
- package/dist/icon/icon.d.ts +14 -0
- package/dist/icon/icon.js +28 -0
- package/dist/icon/icon.js.map +1 -0
- package/dist/icon/icons.generated.d.ts +358 -0
- package/dist/icon/icons.generated.js +362 -0
- package/dist/icon/icons.generated.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +88 -0
- package/dist/input/extra-inputs.d.ts +122 -0
- package/dist/input/extra-inputs.js +351 -0
- package/dist/input/extra-inputs.js.map +1 -0
- package/dist/input/field-styles.d.ts +5 -0
- package/dist/input/field-styles.js +14 -0
- package/dist/input/field-styles.js.map +1 -0
- package/dist/input/input.d.ts +50 -0
- package/dist/input/input.js +107 -0
- package/dist/input/input.js.map +1 -0
- package/dist/layout/layout.d.ts +41 -0
- package/dist/layout/layout.js +90 -0
- package/dist/layout/layout.js.map +1 -0
- package/dist/lib/control-styles.d.ts +9 -0
- package/dist/lib/control-styles.js +16 -0
- package/dist/lib/control-styles.js.map +1 -0
- package/dist/lib/cx.d.ts +2 -0
- package/dist/lib/cx.js +8 -0
- package/dist/lib/cx.js.map +1 -0
- package/dist/lib/glyphs.d.ts +13 -0
- package/dist/lib/glyphs.js +67 -0
- package/dist/lib/glyphs.js.map +1 -0
- package/dist/lib/segmented-styles.d.ts +8 -0
- package/dist/lib/segmented-styles.js +12 -0
- package/dist/lib/segmented-styles.js.map +1 -0
- package/dist/lib/select-on-arrow.d.ts +7 -0
- package/dist/lib/select-on-arrow.js +21 -0
- package/dist/lib/select-on-arrow.js.map +1 -0
- package/dist/lib/skip-link.d.ts +5 -0
- package/dist/lib/skip-link.js +13 -0
- package/dist/lib/skip-link.js.map +1 -0
- package/dist/lib/use-media-query.d.ts +4 -0
- package/dist/lib/use-media-query.js +15 -0
- package/dist/lib/use-media-query.js.map +1 -0
- package/dist/lists/lists.d.ts +76 -0
- package/dist/lists/lists.js +133 -0
- package/dist/lists/lists.js.map +1 -0
- package/dist/locale-switch/locale-switch.d.ts +29 -0
- package/dist/locale-switch/locale-switch.js +62 -0
- package/dist/locale-switch/locale-switch.js.map +1 -0
- package/dist/logo/logo.d.ts +31 -0
- package/dist/logo/logo.js +157 -0
- package/dist/logo/logo.js.map +1 -0
- package/dist/logo/product-logo.d.ts +19 -0
- package/dist/logo/product-logo.js +46 -0
- package/dist/logo/product-logo.js.map +1 -0
- package/dist/marketing/marketing.d.ts +176 -0
- package/dist/marketing/marketing.js +451 -0
- package/dist/marketing/marketing.js.map +1 -0
- package/dist/marketing/newsletter-form.d.ts +21 -0
- package/dist/marketing/newsletter-form.js +100 -0
- package/dist/marketing/newsletter-form.js.map +1 -0
- package/dist/mascot/mascot.d.ts +28 -0
- package/dist/mascot/mascot.js +28 -0
- package/dist/mascot/mascot.js.map +1 -0
- package/dist/mascot/mascots.generated.d.ts +284 -0
- package/dist/mascot/mascots.generated.js +287 -0
- package/dist/mascot/mascots.generated.js.map +1 -0
- package/dist/master-detail/master-detail.d.ts +30 -0
- package/dist/master-detail/master-detail.js +71 -0
- package/dist/master-detail/master-detail.js.map +1 -0
- package/dist/menu/account-menu.d.ts +44 -0
- package/dist/menu/account-menu.js +78 -0
- package/dist/menu/account-menu.js.map +1 -0
- package/dist/menu/context-menu.d.ts +31 -0
- package/dist/menu/context-menu.js +111 -0
- package/dist/menu/context-menu.js.map +1 -0
- package/dist/menu/dropdown-menu.d.ts +49 -0
- package/dist/menu/dropdown-menu.js +152 -0
- package/dist/menu/dropdown-menu.js.map +1 -0
- package/dist/menu/menu-styles.d.ts +8 -0
- package/dist/menu/menu-styles.js +6 -0
- package/dist/menu/menu-styles.js.map +1 -0
- package/dist/menu/menubar.d.ts +31 -0
- package/dist/menu/menubar.js +125 -0
- package/dist/menu/menubar.js.map +1 -0
- package/dist/modal/modal.d.ts +34 -0
- package/dist/modal/modal.js +58 -0
- package/dist/modal/modal.js.map +1 -0
- package/dist/notification-center/notification-center.d.ts +51 -0
- package/dist/notification-center/notification-center.js +244 -0
- package/dist/notification-center/notification-center.js.map +1 -0
- package/dist/otp-input/otp-input.d.ts +23 -0
- package/dist/otp-input/otp-input.js +61 -0
- package/dist/otp-input/otp-input.js.map +1 -0
- package/dist/overlay/overlay.d.ts +53 -0
- package/dist/overlay/overlay.js +103 -0
- package/dist/overlay/overlay.js.map +1 -0
- package/dist/page-header/page-header.d.ts +55 -0
- package/dist/page-header/page-header.js +114 -0
- package/dist/page-header/page-header.js.map +1 -0
- package/dist/page-header/record-headers.d.ts +51 -0
- package/dist/page-header/record-headers.js +134 -0
- package/dist/page-header/record-headers.js.map +1 -0
- package/dist/page-header/section-header.d.ts +21 -0
- package/dist/page-header/section-header.js +44 -0
- package/dist/page-header/section-header.js.map +1 -0
- package/dist/page-navigation/page-navigation.d.ts +59 -0
- package/dist/page-navigation/page-navigation.js +136 -0
- package/dist/page-navigation/page-navigation.js.map +1 -0
- package/dist/pagination/pagination.d.ts +28 -0
- package/dist/pagination/pagination.js +102 -0
- package/dist/pagination/pagination.js.map +1 -0
- package/dist/phone-input/phone-input.d.ts +34 -0
- package/dist/phone-input/phone-input.js +171 -0
- package/dist/phone-input/phone-input.js.map +1 -0
- package/dist/popover/popover.d.ts +23 -0
- package/dist/popover/popover.js +40 -0
- package/dist/popover/popover.js.map +1 -0
- package/dist/progress/progress.d.ts +21 -0
- package/dist/progress/progress.js +49 -0
- package/dist/progress/progress.js.map +1 -0
- package/dist/segmented-control/segmented-control.d.ts +32 -0
- package/dist/segmented-control/segmented-control.js +29 -0
- package/dist/segmented-control/segmented-control.js.map +1 -0
- package/dist/select/select.d.ts +48 -0
- package/dist/select/select.js +136 -0
- package/dist/select/select.js.map +1 -0
- package/dist/settings/permission-matrix.d.ts +29 -0
- package/dist/settings/permission-matrix.js +101 -0
- package/dist/settings/permission-matrix.js.map +1 -0
- package/dist/settings/settings-row.d.ts +32 -0
- package/dist/settings/settings-row.js +63 -0
- package/dist/settings/settings-row.js.map +1 -0
- package/dist/side-nav/side-nav.d.ts +36 -0
- package/dist/side-nav/side-nav.js +123 -0
- package/dist/side-nav/side-nav.js.map +1 -0
- package/dist/site-header/site-header.d.ts +32 -0
- package/dist/site-header/site-header.js +99 -0
- package/dist/site-header/site-header.js.map +1 -0
- package/dist/skeleton/skeleton.d.ts +16 -0
- package/dist/skeleton/skeleton.js +19 -0
- package/dist/skeleton/skeleton.js.map +1 -0
- package/dist/slider/slider.d.ts +15 -0
- package/dist/slider/slider.js +48 -0
- package/dist/slider/slider.js.map +1 -0
- package/dist/spinner/spinner.d.ts +15 -0
- package/dist/spinner/spinner.js +42 -0
- package/dist/spinner/spinner.js.map +1 -0
- package/dist/stepper/step-dots.d.ts +16 -0
- package/dist/stepper/step-dots.js +26 -0
- package/dist/stepper/step-dots.js.map +1 -0
- package/dist/stepper/stepper.d.ts +26 -0
- package/dist/stepper/stepper.js +113 -0
- package/dist/stepper/stepper.js.map +1 -0
- package/dist/tabs/tabs.d.ts +31 -0
- package/dist/tabs/tabs.js +66 -0
- package/dist/tabs/tabs.js.map +1 -0
- package/dist/templates/app-templates.d.ts +126 -0
- package/dist/templates/app-templates.js +153 -0
- package/dist/templates/app-templates.js.map +1 -0
- package/dist/templates/site-templates.d.ts +49 -0
- package/dist/templates/site-templates.js +110 -0
- package/dist/templates/site-templates.js.map +1 -0
- package/dist/toast/toast-store.d.ts +54 -0
- package/dist/toast/toast-store.js +49 -0
- package/dist/toast/toast-store.js.map +1 -0
- package/dist/toast/toaster.d.ts +15 -0
- package/dist/toast/toaster.js +124 -0
- package/dist/toast/toaster.js.map +1 -0
- package/dist/tooltip/tooltip.d.ts +29 -0
- package/dist/tooltip/tooltip.js +54 -0
- package/dist/tooltip/tooltip.js.map +1 -0
- package/package.json +88 -3
- package/styles.css +521 -0
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table.js","names":["Fragment","Fragment$1","RadixCheckbox","features","tableFeatures","createFilteredRowModel","filterFn_includesString","createSortedRowModel","sortFn_alphanumeric","sortFn_basic","sortFn_datetime","createPaginatedRowModel","LABELS","ALIGN","SelectBox","onChange","label","cx","checkboxBox","focusRing","Glyph","checked","ExpandButton","open","controls","onToggle","toCsvValue","s","v","DataTable","overrides","labels","tableId","useId","brandHead","headerAppearance","headBg","density","setDensity","useState","defaultDensity","helper","useMemo","createColumnHelper","tableColumns","columns","c","row","initialVisibility","table","useTable","getRowId","def","column","virtualize","data","pageSize","colDef","id","rowLabel","getRowLabel","first","query","rows","filteredCount","size","selectedRows","selectable","r","visibleColumns","expandable","renderExpanded","expanded","setExpanded","toggleExpanded","next","prev","colCount","cellPad","exportCsv","cols","source","lines","blob","url","exportFileName","renderCell","scrollRef","useRef","virtualizer","useVirtualizer","virtualItems","renderedRows","padTop","padBottom","emptyNode","EmptyState","empty","status","error","loading","hideOnMobile","mobileLayout","className","bulkActions","searchable","Input","searchPlaceholder","toolbar","showCount","Button","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuLabel","DropdownMenuCheckboxItem","DropdownMenuSeparator","DropdownMenuRadioGroup","DropdownMenuRadioItem","showCaption","caption","group","header","sorted","canSort","i","rowActions","Skeleton","j","ErrorState","isSelected","isOpen","panelId","onRowClick","cell","visible","title","meta","fields","m","f","pageIndex","NativeSelect","pageSizeOptions","n","Pagination","pagination","p"],"sources":["../../src/data-table/data-table.tsx"],"sourcesContent":["'use client';\n\nimport * as RadixCheckbox from '@radix-ui/react-checkbox';\nimport {\n columnFilteringFeature,\n columnVisibilityFeature,\n createColumnHelper,\n createFilteredRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n filterFn_includesString,\n globalFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_basic,\n sortFn_datetime,\n tableFeatures,\n useTable,\n} from '@tanstack/react-table';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport { Fragment, useEffect, useId, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { checkboxBox, focusRing } from '../lib/control-styles';\nimport { Glyph } from '../lib/glyphs';\nimport { Input } from '../input/input';\nimport { NativeSelect } from '../select/select';\nimport { Button } from '../button/button';\nimport { Pagination } from '../pagination/pagination';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { ErrorState } from '../error-state/error-state';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../menu/dropdown-menu';\n\n/** Stable feature registry (TanStack Table v9): sorting, global search, pagination, selection, visibility. */\nconst features = tableFeatures({\n columnFilteringFeature,\n globalFilteringFeature,\n filteredRowModel: createFilteredRowModel(),\n filterFns: { includesString: filterFn_includesString },\n rowSortingFeature,\n sortedRowModel: createSortedRowModel(),\n sortFns: { alphanumeric: sortFn_alphanumeric, basic: sortFn_basic, datetime: sortFn_datetime },\n rowPaginationFeature,\n paginatedRowModel: createPaginatedRowModel(),\n rowSelectionFeature,\n columnVisibilityFeature,\n});\n\nexport interface DataTableColumn<T> {\n id: string;\n header: string;\n /** Value used for sorting, search and CSV. Omit for display-only columns. */\n accessor?: (row: T) => string | number | Date | null | undefined;\n /** Custom cell rendering. Defaults to the accessor value. */\n cell?: (row: T) => ReactNode;\n /** Default: true when there is an accessor. */\n sortable?: boolean;\n /** Include in the global search. Default: true for string/number accessors. */\n searchable?: boolean;\n align?: 'start' | 'end' | 'center';\n /** CSS width, e.g. `12rem` or `30%`. */\n width?: string;\n /** Default: true. */\n hideable?: boolean;\n defaultHidden?: boolean;\n /** Role in the mobile card: `title` (one column), `meta` (small line under it), `field` (label: value), `hidden`. Default `field`. */\n mobile?: 'title' | 'meta' | 'field' | 'hidden';\n}\n\nexport interface DataTableProps<T> {\n data: T[];\n columns: DataTableColumn<T>[];\n /** Stable id per row (database id). */\n getRowId: (row: T) => string;\n /** Accessible name; also shown above the table when `showCaption` is set. */\n caption: string;\n showCaption?: boolean;\n /** Global search box. */\n searchable?: boolean;\n searchPlaceholder?: string;\n /** Row checkboxes + bulk actions bar. */\n selectable?: boolean;\n /** Actions for the selected rows, e.g. \"Archive\", \"Export\". `clear` deselects all. */\n bulkActions?: (rows: T[], clear: () => void) => ReactNode;\n /** Per-row actions at the end of each row (usually a DropdownMenu, or `CellActions`). */\n rowActions?: (row: T) => ReactNode;\n /**\n * Expandable rows: a chevron button opens a full-width panel under the row with this content\n * (sub-items, details). Not available with `virtualize`.\n */\n renderExpanded?: (row: T) => ReactNode;\n /**\n * How a row is named in the expand button and the row checkbox (\"Show details for Invoice intake\"). Default: the\n * first column's value, then the row id.\n */\n getRowLabel?: (row: T) => string;\n onRowClick?: (row: T) => void;\n /** Extra toolbar content (filters). */\n toolbar?: ReactNode;\n pageSize?: number;\n pageSizeOptions?: number[];\n /** Render only visible rows (TanStack Virtual); disables pagination. For 500+ rows. */\n virtualize?: boolean;\n /** Height of the scroll area when virtualized. */\n maxHeight?: string;\n loading?: boolean;\n error?: string;\n onRetry?: () => void;\n empty?: ReactNode;\n /** Shows \"Export CSV\" in the toolbar; file name without extension. */\n exportFileName?: string;\n defaultDensity?: 'comfortable' | 'compact';\n /** Below 960px: stacked `cards` (default) or horizontal `scroll` with the first column sticky. */\n mobileLayout?: 'cards' | 'scroll';\n /** `muted` (default): tinted header row. `brand`: header row in the brand color, uppercase labels (dashboards). */\n headerAppearance?: 'muted' | 'brand';\n /** Shows the number of matching rows in the toolbar (\"24 results\"). */\n showCount?: boolean;\n /** Footer pager: numbered `pages` (default) or `compact` (\"Page 1 of 4\" with arrows). */\n pagination?: 'pages' | 'compact';\n labels?: Partial<typeof LABELS>;\n className?: string;\n}\n\nconst LABELS = {\n search: 'Search',\n view: 'View',\n columns: 'Columns',\n density: 'Density',\n comfortable: 'Comfortable',\n compact: 'Compact',\n export: 'Export CSV',\n selectAll: 'Select all rows on this page',\n selectRow: 'Select row',\n /** `{count}` replaced. */\n selected: '{count} selected',\n clear: 'Clear selection',\n rowsPerPage: 'Rows per page',\n /** `{from}`, `{to}`, `{total}` replaced. */\n range: '{from}–{to} of {total}',\n actions: 'Actions',\n emptyTitle: 'Nothing here yet',\n noResultsTitle: 'No results',\n /** `{query}` replaced. */\n noResultsDescription: 'Nothing matches “{query}”. Try another word.',\n sortAscending: 'Sort ascending',\n sortDescending: 'Sort descending',\n /** `{count}` replaced. */\n results: '{count} results',\n /** `{row}` replaced with the row id. */\n expand: 'Show details for {row}',\n collapse: 'Hide details for {row}',\n details: 'Details',\n};\n\nconst ALIGN = { start: 'text-left', end: 'text-right', center: 'text-center' };\n\nfunction SelectBox({\n checked,\n onChange,\n label,\n}: {\n checked: boolean | 'indeterminate';\n onChange: (e: unknown) => void;\n label: string;\n}) {\n return (\n <RadixCheckbox.Root\n checked={checked}\n onClick={(e) => {\n e.stopPropagation();\n onChange(e);\n }}\n aria-label={label}\n className={cx(checkboxBox({ size: 'sm' }), focusRing)}\n >\n <RadixCheckbox.Indicator>\n <Glyph name={checked === 'indeterminate' ? 'minus' : 'check'} size={12} strokeWidth={3} />\n </RadixCheckbox.Indicator>\n </RadixCheckbox.Root>\n );\n}\n\nfunction ExpandButton({ open, controls, label, onToggle }: { open: boolean; controls: string; label: string; onToggle: () => void }) {\n return (\n <button\n type=\"button\"\n aria-expanded={open}\n aria-controls={open ? controls : undefined}\n aria-label={label}\n onClick={onToggle}\n className=\"-my-1 grid size-8 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg-muted hover:bg-surface-muted hover:text-fg focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus\"\n >\n <Glyph\n name=\"chevron-right\"\n size={16}\n className={cx('transition-transform duration-150 motion-reduce:transition-none', open && 'rotate-90')}\n />\n </button>\n );\n}\n\nconst toCsvValue = (v: unknown) => {\n const s = v instanceof Date ? v.toISOString() : v == null ? '' : String(v);\n return /[\",\\n]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\n};\n\n/**\n * Data table for product back-offices: global search, sorting, pagination, row selection with\n * bulk actions, column visibility, density, CSV export, loading/empty/error states, stacked\n * cards on mobile and virtualization for large datasets. Built on TanStack Table v9.\n */\nexport function DataTable<T extends object>({\n data,\n columns,\n getRowId,\n caption,\n showCaption,\n searchable = true,\n searchPlaceholder,\n selectable,\n bulkActions,\n rowActions,\n renderExpanded,\n getRowLabel,\n onRowClick,\n toolbar,\n pageSize = 25,\n pageSizeOptions = [10, 25, 50, 100],\n virtualize,\n maxHeight = '36rem',\n loading,\n error,\n onRetry,\n empty,\n exportFileName,\n defaultDensity = 'comfortable',\n mobileLayout = 'cards',\n headerAppearance = 'muted',\n pagination = 'pages',\n showCount,\n labels: overrides,\n className,\n}: DataTableProps<T>) {\n const labels = { ...LABELS, ...overrides };\n const tableId = useId();\n const brandHead = headerAppearance === 'brand';\n // One background class per header cell (`cx` does not merge): sticky cells repeat it.\n const headBg = brandHead ? 'bg-primary' : 'bg-surface-muted';\n const [density, setDensity] = useState(defaultDensity);\n const helper = useMemo(() => createColumnHelper<typeof features, T>(), []);\n\n const tableColumns = useMemo(\n () =>\n columns.map((c) =>\n c.accessor\n ? helper.accessor((row: T) => c.accessor!(row), {\n id: c.id,\n header: c.header,\n enableSorting: c.sortable ?? true,\n enableHiding: c.hideable ?? true,\n enableGlobalFilter: c.searchable,\n sortFn: 'auto',\n })\n : helper.display({ id: c.id, header: c.header, enableSorting: false, enableHiding: c.hideable ?? true }),\n ),\n [columns, helper],\n );\n\n const initialVisibility = useMemo(\n () => Object.fromEntries(columns.filter((c) => c.defaultHidden).map((c) => [c.id, false])),\n [columns],\n );\n\n const table = useTable({\n features,\n columns: tableColumns as never,\n data,\n getRowId: (row: T) => getRowId(row),\n globalFilterFn: 'includesString',\n getColumnCanGlobalFilter: (column: { id: string }) => {\n const def = columns.find((c) => c.id === column.id);\n return !!def?.accessor && def.searchable !== false;\n },\n enableSortingRemoval: true,\n // Every column sorts ascending on the first click (TanStack defaults numbers to descending).\n sortDescFirst: false,\n initialState: {\n pagination: { pageIndex: 0, pageSize: virtualize ? Math.max(data.length, 1) : pageSize },\n columnVisibility: initialVisibility,\n },\n } as never) as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n // Virtualized tables show every row: keep the page size in sync with the data.\n useEffect(() => {\n if (virtualize) table.setPageSize(Math.max(data.length, 1));\n }, [virtualize, data.length, table]);\n\n const colDef = (id: string) => columns.find((c) => c.id === id)!;\n const rowLabel = (row: { id: string; original: T }) => {\n if (getRowLabel) return getRowLabel(row.original);\n const first = columns[0]?.accessor?.(row.original);\n return first === null || first === undefined || first instanceof Date ? row.id : String(first);\n };\n const query: string = table.state.globalFilter ?? '';\n const rows: any[] = table.getRowModel().rows; // eslint-disable-line @typescript-eslint/no-explicit-any\n const filteredCount: number = table.getFilteredRowModel().rows.length;\n const { pageIndex, pageSize: size } = table.state.pagination;\n const selectedRows: T[] = selectable ? table.getSelectedRowModel().rows.map((r: { original: T }) => r.original) : [];\n const visibleColumns = table.getVisibleLeafColumns() as { id: string }[];\n const expandable = Boolean(renderExpanded) && !virtualize;\n const [expanded, setExpanded] = useState<ReadonlySet<string>>(() => new Set());\n const toggleExpanded = (id: string) =>\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n const colCount = visibleColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0) + (expandable ? 1 : 0);\n const cellPad = density === 'compact' ? 'px-3 py-1.5' : 'px-4 py-3';\n\n const exportCsv = () => {\n const cols = visibleColumns.map((c) => colDef(c.id)).filter((c) => c.accessor);\n const source: T[] = selectedRows.length\n ? selectedRows\n : table.getFilteredRowModel().rows.map((r: { original: T }) => r.original);\n const lines = [\n cols.map((c) => toCsvValue(c.header)).join(','),\n ...source.map((row) => cols.map((c) => toCsvValue(c.accessor!(row))).join(',')),\n ];\n const blob = new Blob([`${lines.join('\\n')}`], { type: 'text/csv;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${exportFileName}.csv`;\n a.click();\n URL.revokeObjectURL(url);\n };\n\n const renderCell = (row: { original: T }, id: string) => {\n const def = colDef(id);\n if (def.cell) return def.cell(row.original);\n const v = def.accessor?.(row.original);\n return v instanceof Date ? v.toLocaleDateString() : (v ?? '—');\n };\n\n // Virtualization\n const scrollRef = useRef<HTMLDivElement>(null);\n const virtualizer = useVirtualizer({\n count: virtualize ? rows.length : 0,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => (density === 'compact' ? 37 : 49),\n overscan: 8,\n });\n const virtualItems = virtualize ? virtualizer.getVirtualItems() : [];\n const renderedRows = virtualize ? virtualItems.map((v) => rows[v.index]) : rows;\n const padTop = virtualize && virtualItems.length ? virtualItems[0]!.start : 0;\n const padBottom =\n virtualize && virtualItems.length ? virtualizer.getTotalSize() - virtualItems[virtualItems.length - 1]!.end : 0;\n\n const emptyNode =\n query && filteredCount === 0 ? (\n <EmptyState\n size=\"sm\"\n mascot=\"lost\"\n headingLevel={3}\n title={labels.noResultsTitle}\n description={labels.noResultsDescription.replace('{query}', query)}\n />\n ) : (\n (empty ?? <EmptyState size=\"sm\" headingLevel={3} title={labels.emptyTitle} />)\n );\n\n const status = error ? 'error' : loading ? 'loading' : rows.length === 0 ? 'empty' : 'ready';\n const hideOnMobile = mobileLayout === 'cards' ? 'hidden md:block' : 'block';\n\n return (\n <div className={cx('grid gap-3 font-sans', className)}>\n {/* Toolbar or bulk-actions bar */}\n {selectedRows.length > 0 ? (\n <div\n role=\"region\"\n aria-label={labels.selected.replace('{count}', String(selectedRows.length))}\n className=\"flex min-h-11 flex-wrap items-center gap-3 rounded-md bg-primary px-4 py-2 text-on-primary\"\n >\n <span className=\"text-sm font-semibold\">\n {labels.selected.replace('{count}', String(selectedRows.length))}\n </span>\n <div className=\"flex flex-1 flex-wrap items-center gap-2 [&_button]:text-on-primary\">\n {bulkActions?.(selectedRows, () => table.resetRowSelection(true))}\n </div>\n <button\n type=\"button\"\n onClick={() => table.resetRowSelection(true)}\n className=\"cursor-pointer rounded-full border-0 bg-transparent px-3 py-1.5 text-sm font-semibold text-on-primary underline-offset-4 hover:underline focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white\"\n >\n {labels.clear}\n </button>\n </div>\n ) : (\n <div className=\"flex flex-wrap items-center gap-2\">\n {searchable && (\n <Input\n type=\"search\"\n size=\"sm\"\n iconStart=\"search\"\n aria-label={labels.search}\n placeholder={searchPlaceholder ?? `${labels.search}…`}\n value={query}\n onChange={(e) => table.setGlobalFilter(e.target.value)}\n className=\"w-full sm:w-72\"\n />\n )}\n {toolbar}\n {showCount && (\n <span aria-live=\"polite\" className=\"text-sm text-fg-muted tabular-nums\">\n {labels.results.replace('{count}', String(filteredCount))}\n </span>\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {exportFileName && (\n <Button size=\"sm\" variant=\"secondary\" iconStart=\"download\" onClick={exportCsv}>\n {labels.export}\n </Button>\n )}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button size=\"sm\" variant=\"secondary\">\n <span className=\"inline-flex items-center gap-1.5\">\n <Glyph name=\"columns\" size={16} />\n {labels.view}\n </span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>{labels.columns}</DropdownMenuLabel>\n {(\n table.getAllLeafColumns() as {\n id: string;\n getCanHide: () => boolean;\n getIsVisible: () => boolean;\n toggleVisibility: (v: boolean) => void;\n }[]\n )\n .filter((c) => c.getCanHide())\n .map((c) => (\n <DropdownMenuCheckboxItem\n key={c.id}\n checked={c.getIsVisible()}\n onCheckedChange={(v) => c.toggleVisibility(v === true)}\n onSelect={(e) => e.preventDefault()}\n >\n {colDef(c.id).header}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>{labels.density}</DropdownMenuLabel>\n <DropdownMenuRadioGroup value={density} onValueChange={(v) => setDensity(v as typeof density)}>\n <DropdownMenuRadioItem value=\"comfortable\">{labels.comfortable}</DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"compact\">{labels.compact}</DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n )}\n\n {showCaption && <h3 className=\"m-0 font-display text-lg font-bold\">{caption}</h3>}\n\n {/* Desktop table (and mobile when mobileLayout=\"scroll\") */}\n <div\n ref={scrollRef}\n className={cx('relative overflow-auto rounded-md border border-border bg-surface', hideOnMobile)}\n style={virtualize ? { maxHeight } : undefined}\n tabIndex={virtualize ? 0 : undefined}\n role={virtualize ? 'region' : undefined}\n aria-label={virtualize ? caption : undefined}\n >\n <table\n className=\"w-full border-collapse text-sm\"\n aria-busy={loading || undefined}\n aria-rowcount={virtualize ? rows.length + 1 : undefined}\n >\n <caption className=\"sr-only\">{caption}</caption>\n <thead className={cx('sticky top-0 z-10', headBg)}>\n {table.getHeaderGroups().map((group: { id: string; headers: any[] }) => (\n <tr key={group.id}>\n {expandable && (\n <th scope=\"col\" className={cx('w-10 border-b border-border', cellPad)}>\n <span className=\"sr-only\">{labels.details}</span>\n </th>\n )}\n {selectable && (\n <th\n scope=\"col\"\n className={cx('w-10', cellPad, mobileLayout === 'scroll' && cx('sticky left-0 z-10', headBg))}\n >\n <SelectBox\n label={labels.selectAll}\n checked={\n table.getIsAllPageRowsSelected()\n ? true\n : table.getIsSomePageRowsSelected()\n ? 'indeterminate'\n : false\n }\n onChange={() => table.toggleAllPageRowsSelected()}\n />\n </th>\n )}\n {group.headers.map((header, i) => {\n const def = colDef(header.column.id);\n const sorted: false | 'asc' | 'desc' = header.column.getIsSorted();\n const canSort = header.column.getCanSort();\n return (\n <th\n key={header.id}\n scope=\"col\"\n aria-sort={sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : undefined}\n style={{ width: def.width }}\n className={cx(\n cellPad,\n 'border-b border-border font-semibold whitespace-nowrap',\n brandHead ? 'text-xs tracking-wider text-on-primary uppercase' : 'text-fg-muted',\n ALIGN[def.align ?? 'start'],\n mobileLayout === 'scroll' && i === 0 && !selectable && cx('sticky left-0 z-10', headBg),\n )}\n >\n {canSort ? (\n <button\n type=\"button\"\n onClick={header.column.getToggleSortingHandler()}\n className={cx(\n 'inline-flex cursor-pointer items-center gap-1 rounded-xs border-0 bg-transparent p-0 font-[inherit] text-[length:inherit] font-semibold tracking-[inherit] focus-visible:outline-3 focus-visible:outline-offset-2',\n brandHead\n ? 'text-on-primary uppercase underline-offset-4 hover:underline focus-visible:outline-white'\n : cx('hover:text-fg focus-visible:outline-focus', sorted ? 'text-fg' : 'text-fg-muted'),\n brandHead && sorted && 'underline',\n def.align === 'end' && 'flex-row-reverse',\n )}\n >\n {def.header}\n <Glyph\n name={sorted === 'asc' ? 'arrow-up' : sorted === 'desc' ? 'arrow-down' : 'sort'}\n size={14}\n className={sorted ? (brandHead ? '' : 'text-link') : brandHead ? 'opacity-60' : 'opacity-40'}\n />\n </button>\n ) : (\n def.header\n )}\n </th>\n );\n })}\n {rowActions && (\n <th scope=\"col\" className={cx(cellPad, 'w-12 border-b border-border')}>\n <span className=\"sr-only\">{labels.actions}</span>\n </th>\n )}\n </tr>\n ))}\n </thead>\n <tbody>\n {status === 'loading' &&\n Array.from({ length: Math.min(size, 6) }, (_, i) => (\n <tr key={i} className=\"border-b border-border last:border-b-0\">\n {Array.from({ length: colCount }, (_, j) => (\n <td key={j} className={cellPad}>\n <Skeleton className=\"h-3.5 rounded-full\" />\n </td>\n ))}\n </tr>\n ))}\n {status === 'error' && (\n <tr>\n <td colSpan={colCount}>\n <ErrorState size=\"sm\" headingLevel={3} description={error} onRetry={onRetry} />\n </td>\n </tr>\n )}\n {status === 'empty' && (\n <tr>\n <td colSpan={colCount}>{emptyNode}</td>\n </tr>\n )}\n {status === 'ready' && padTop > 0 && (\n <tr aria-hidden=\"true\">\n <td colSpan={colCount} style={{ height: padTop, padding: 0 }} />\n </tr>\n )}\n {status === 'ready' &&\n renderedRows.map((row) => {\n const isSelected = selectable && row.getIsSelected();\n const isOpen = expandable && expanded.has(row.id);\n const panelId = `${tableId}-x-${row.id}`;\n return (\n <Fragment key={row.id}>\n <tr\n aria-selected={selectable ? isSelected : undefined}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n className={cx(\n 'border-b border-border transition-colors last:border-b-0 hover:bg-surface-muted/60',\n isSelected && 'bg-info-surface/50 hover:bg-info-surface/70',\n onRowClick && 'cursor-pointer',\n isOpen && 'border-b-0',\n isOpen && !isSelected && 'bg-surface-muted/40',\n )}\n >\n {expandable && (\n <td className={cx(cellPad, 'w-10 pr-0')} onClick={(e) => e.stopPropagation()}>\n <ExpandButton\n open={isOpen}\n controls={panelId}\n label={(isOpen ? labels.collapse : labels.expand).replace('{row}', rowLabel(row))}\n onToggle={() => toggleExpanded(row.id)}\n />\n </td>\n )}\n {selectable && (\n <td className={cx(cellPad, mobileLayout === 'scroll' && 'sticky left-0 bg-surface')}>\n <SelectBox\n label={`${labels.selectRow} ${rowLabel(row)}`}\n checked={!!isSelected}\n onChange={row.getToggleSelectedHandler()}\n />\n </td>\n )}\n {row.getVisibleCells().map((cell: { id: string; column: { id: string } }, i: number) => {\n const def = colDef(cell.column.id);\n return (\n <td\n key={cell.id}\n className={cx(\n cellPad,\n 'text-fg',\n ALIGN[def.align ?? 'start'],\n def.align === 'end' && 'tabular-nums',\n mobileLayout === 'scroll' && i === 0 && !selectable && 'sticky left-0 bg-surface',\n )}\n >\n {renderCell(row, cell.column.id)}\n </td>\n );\n })}\n {rowActions && (\n <td className={cx(cellPad, 'text-right')} onClick={(e) => e.stopPropagation()}>\n {rowActions(row.original)}\n </td>\n )}\n </tr>\n {isOpen && (\n <tr id={panelId} className=\"border-b border-border bg-surface-muted/40 last:border-b-0\">\n <td colSpan={colCount} className={cx(cellPad, 'pt-0')}>\n <div className=\"rounded-md border border-border bg-surface p-4\">{renderExpanded!(row.original)}</div>\n </td>\n </tr>\n )}\n </Fragment>\n );\n })}\n {status === 'ready' && padBottom > 0 && (\n <tr aria-hidden=\"true\">\n <td colSpan={colCount} style={{ height: padBottom, padding: 0 }} />\n </tr>\n )}\n </tbody>\n </table>\n </div>\n\n {/* Mobile cards */}\n {mobileLayout === 'cards' && (\n <div className=\"grid gap-2 md:hidden\">\n {status === 'loading' && [0, 1, 2].map((i) => <Skeleton key={i} className=\"h-24\" />)}\n {status === 'error' && <ErrorState size=\"sm\" headingLevel={3} description={error} onRetry={onRetry} />}\n {status === 'empty' && emptyNode}\n {status === 'ready' && (\n <ul aria-label={caption} className=\"m-0 grid list-none gap-2 p-0\">\n {rows.map((row) => {\n const visible = visibleColumns.map((c) => colDef(c.id));\n const title = visible.find((c) => c.mobile === 'title') ?? visible[0]!;\n const meta = visible.filter((c) => c.mobile === 'meta');\n const fields = visible.filter((c) => c !== title && (c.mobile ?? 'field') === 'field');\n return (\n <li\n key={row.id}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n className={cx(\n 'grid gap-2 rounded-md border border-border bg-surface p-4',\n selectable && row.getIsSelected() && 'border-primary bg-info-surface/50',\n onRowClick && 'cursor-pointer',\n )}\n >\n <div className=\"flex items-start gap-3\">\n {selectable && (\n <span className=\"pt-0.5\">\n <SelectBox\n label={`${labels.selectRow} ${rowLabel(row)}`}\n checked={row.getIsSelected()}\n onChange={row.getToggleSelectedHandler()}\n />\n </span>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"font-semibold text-fg\">{renderCell(row, title.id)}</div>\n {meta.length > 0 && (\n <div className=\"mt-0.5 flex flex-wrap gap-x-2 text-sm text-fg-muted\">\n {meta.map((m) => (\n <span key={m.id}>{renderCell(row, m.id)}</span>\n ))}\n </div>\n )}\n </div>\n {rowActions && <div onClick={(e) => e.stopPropagation()}>{rowActions(row.original)}</div>}\n </div>\n {fields.length > 0 && (\n <dl className=\"m-0 grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-sm\">\n {fields.map((f) => (\n <div key={f.id} className=\"contents\">\n <dt className=\"text-fg-muted\">{f.header}</dt>\n <dd className=\"m-0 min-w-0 text-right text-fg\">{renderCell(row, f.id)}</dd>\n </div>\n ))}\n </dl>\n )}\n {expandable && (\n <div onClick={(e) => e.stopPropagation()} className=\"grid gap-2\">\n <button\n type=\"button\"\n aria-expanded={expanded.has(row.id)}\n aria-controls={expanded.has(row.id) ? `${tableId}-m-${row.id}` : undefined}\n onClick={() => toggleExpanded(row.id)}\n className=\"inline-flex w-fit cursor-pointer items-center gap-1.5 rounded-xs border-0 bg-transparent p-0 font-sans text-sm font-semibold text-link focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus\"\n >\n {labels.details}\n <Glyph\n name=\"chevron-down\"\n size={14}\n className={cx('transition-transform motion-reduce:transition-none', expanded.has(row.id) && 'rotate-180')}\n />\n </button>\n {expanded.has(row.id) && (\n <div id={`${tableId}-m-${row.id}`} className=\"rounded-sm bg-surface-muted p-3 text-sm\">\n {renderExpanded!(row.original)}\n </div>\n )}\n </div>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n )}\n\n {/* Footer: range, page size, pagination */}\n {!virtualize && status === 'ready' && filteredCount > 0 && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted\">\n <span aria-live=\"polite\">\n {labels.range\n .replace('{from}', String(pageIndex * size + 1))\n .replace('{to}', String(Math.min(filteredCount, (pageIndex + 1) * size)))\n .replace('{total}', String(filteredCount))}\n </span>\n <label className=\"hidden items-center gap-2 sm:flex\">\n {labels.rowsPerPage}\n <NativeSelect\n size=\"sm\"\n value={size}\n onChange={(e) => table.setPageSize(Number(e.target.value))}\n wrapperClassName=\"w-20\"\n >\n {pageSizeOptions.map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </NativeSelect>\n </label>\n <Pagination\n variant={pagination}\n page={pageIndex + 1}\n pageCount={table.getPageCount()}\n onPageChange={(p) => table.setPageIndex(p - 1)}\n className={pagination === 'compact' ? undefined : 'w-full sm:w-auto'}\n />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type ComponentProps } from 'react';
|
|
2
|
+
import { DayPicker, type DateRange, type DayPickerLocale, type Matcher } from 'react-day-picker';
|
|
3
|
+
import { type ControlSize } from '../input/field-styles';
|
|
4
|
+
export type { DateRange };
|
|
5
|
+
export type CalendarProps = ComponentProps<typeof DayPicker>;
|
|
6
|
+
/**
|
|
7
|
+
* Month grid with keyboard navigation (arrows, PageUp/PageDown, Home/End), built on
|
|
8
|
+
* react-day-picker (ADR-0004) and styled with Kodffe tokens. Pass `locale` from
|
|
9
|
+
* `react-day-picker/locale` (`es`, `enUS`).
|
|
10
|
+
*/
|
|
11
|
+
export declare function Calendar({ classNames, locale, labels, ...rest }: CalendarProps): import("react").JSX.Element;
|
|
12
|
+
export interface DatePickerProps {
|
|
13
|
+
value: Date | undefined;
|
|
14
|
+
onChange: (value: Date | undefined) => void;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
/** Days that cannot be picked: `{ before: new Date() }`, `{ dayOfWeek: [0, 6] }`, a function… */
|
|
17
|
+
disabled?: Matcher | Matcher[];
|
|
18
|
+
/** date-fns format for the field ("PP" → "Nov 4, 2026" / "4 nov 2026"). */
|
|
19
|
+
displayFormat?: string;
|
|
20
|
+
locale?: Partial<DayPickerLocale>;
|
|
21
|
+
/** Month/year dropdowns, e.g. for birth dates. */
|
|
22
|
+
dropdowns?: boolean;
|
|
23
|
+
startMonth?: Date;
|
|
24
|
+
endMonth?: Date;
|
|
25
|
+
size?: ControlSize;
|
|
26
|
+
id?: string;
|
|
27
|
+
invalid?: boolean;
|
|
28
|
+
required?: boolean;
|
|
29
|
+
isDisabled?: boolean;
|
|
30
|
+
labels?: {
|
|
31
|
+
dialog?: string;
|
|
32
|
+
clear?: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Single date: field + calendar (popover on desktop, bottom sheet on mobile). */
|
|
36
|
+
export declare function DatePicker({ value, onChange, placeholder, disabled, displayFormat, locale, dropdowns, startMonth, endMonth, size, labels, isDisabled, ...rest }: DatePickerProps): import("react").JSX.Element;
|
|
37
|
+
export interface RangePreset {
|
|
38
|
+
label: string;
|
|
39
|
+
range: () => DateRange;
|
|
40
|
+
}
|
|
41
|
+
/** Presets relative to today. Labels are English; pass translated ones via `presets`. */
|
|
42
|
+
export declare const DEFAULT_PRESETS: RangePreset[];
|
|
43
|
+
export interface DateRangePickerProps extends Omit<DatePickerProps, 'value' | 'onChange' | 'dropdowns'> {
|
|
44
|
+
value: DateRange | undefined;
|
|
45
|
+
onChange: (value: DateRange | undefined) => void;
|
|
46
|
+
/** Quick ranges shown beside the calendar. `[]` hides them. */
|
|
47
|
+
presets?: RangePreset[];
|
|
48
|
+
/** Longest allowed range in days. */
|
|
49
|
+
maxDays?: number;
|
|
50
|
+
/**
|
|
51
|
+
* `list` (default): presets beside the calendar. `select`: a select of presets with the resolved range beside it,
|
|
52
|
+
* and a "Custom range" option that shows the calendar field (report and attendance filters).
|
|
53
|
+
*/
|
|
54
|
+
presetLayout?: 'list' | 'select';
|
|
55
|
+
labels?: DatePickerProps['labels'] & {
|
|
56
|
+
custom?: string;
|
|
57
|
+
presets?: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Date range with presets: two months on desktop, one in the mobile sheet. */
|
|
61
|
+
export declare function DateRangePicker({ value, onChange, placeholder, disabled, displayFormat, locale, presets, presetLayout, maxDays, startMonth, endMonth, size, labels, isDisabled, ...rest }: DateRangePickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { Icon as t } from "../icon/icon.js";
|
|
4
|
+
import { Drawer as n, DrawerContent as r } from "../drawer/drawer.js";
|
|
5
|
+
import { DESKTOP_QUERY as i, useMediaQuery as a } from "../lib/use-media-query.js";
|
|
6
|
+
import { Glyph as o } from "../lib/glyphs.js";
|
|
7
|
+
import { controlClasses as s } from "../input/field-styles.js";
|
|
8
|
+
import { useFieldProps as c } from "../input/input.js";
|
|
9
|
+
import { Select as l } from "../select/select.js";
|
|
10
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
11
|
+
import { useId as f, useState as p } from "react";
|
|
12
|
+
import * as m from "@radix-ui/react-popover";
|
|
13
|
+
import { endOfMonth as h, format as g, isSameDay as _, startOfDay as v, startOfMonth as y, subDays as b, subMonths as x } from "date-fns";
|
|
14
|
+
import { DayPicker as S, labelDayButton as C } from "react-day-picker";
|
|
15
|
+
import { enUS as w } from "react-day-picker/locale";
|
|
16
|
+
//#region src/date-picker/date-picker.tsx
|
|
17
|
+
var T = {
|
|
18
|
+
root: "kf-cal",
|
|
19
|
+
months: "kf-cal-months",
|
|
20
|
+
month: "kf-cal-month",
|
|
21
|
+
month_caption: "kf-cal-caption",
|
|
22
|
+
caption_label: "kf-cal-caption-label",
|
|
23
|
+
nav: "kf-cal-nav",
|
|
24
|
+
button_previous: "kf-cal-nav-btn",
|
|
25
|
+
button_next: "kf-cal-nav-btn",
|
|
26
|
+
chevron: "kf-cal-chevron",
|
|
27
|
+
month_grid: "kf-cal-grid",
|
|
28
|
+
weekdays: "kf-cal-weekdays",
|
|
29
|
+
weekday: "kf-cal-weekday",
|
|
30
|
+
week: "kf-cal-week",
|
|
31
|
+
day: "kf-cal-day",
|
|
32
|
+
day_button: "kf-cal-day-btn",
|
|
33
|
+
selected: "is-selected",
|
|
34
|
+
today: "is-today",
|
|
35
|
+
outside: "is-outside",
|
|
36
|
+
disabled: "is-disabled",
|
|
37
|
+
hidden: "is-hidden",
|
|
38
|
+
range_start: "is-range-start",
|
|
39
|
+
range_middle: "is-range-middle",
|
|
40
|
+
range_end: "is-range-end",
|
|
41
|
+
dropdowns: "kf-cal-dropdowns",
|
|
42
|
+
dropdown_root: "kf-cal-dropdown-root",
|
|
43
|
+
dropdown: "kf-cal-dropdown",
|
|
44
|
+
footer: "kf-cal-footer"
|
|
45
|
+
};
|
|
46
|
+
function E({ classNames: e, locale: t = w, labels: n, ...r }) {
|
|
47
|
+
return /* @__PURE__ */ u(S, {
|
|
48
|
+
showOutsideDays: !0,
|
|
49
|
+
locale: t,
|
|
50
|
+
classNames: {
|
|
51
|
+
...T,
|
|
52
|
+
...e
|
|
53
|
+
},
|
|
54
|
+
labels: {
|
|
55
|
+
labelDayButton: (e, t, n, r) => `${e.getDate()} – ${C(e, t, n, r)}`,
|
|
56
|
+
...n
|
|
57
|
+
},
|
|
58
|
+
components: { Chevron: ({ orientation: e }) => /* @__PURE__ */ u(o, {
|
|
59
|
+
name: e === "left" ? "chevron-left" : e === "right" ? "chevron-right" : e === "up" ? "chevron-up" : "chevron-down",
|
|
60
|
+
size: 16
|
|
61
|
+
}) },
|
|
62
|
+
...r
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function D({ triggerId: e, open: t, onOpenChange: o, trigger: s, title: c, children: l }) {
|
|
66
|
+
let f = a(i), p = (t) => {
|
|
67
|
+
t.preventDefault(), document.getElementById(e)?.focus();
|
|
68
|
+
};
|
|
69
|
+
return f ? /* @__PURE__ */ d(m.Root, {
|
|
70
|
+
open: t,
|
|
71
|
+
onOpenChange: o,
|
|
72
|
+
children: [/* @__PURE__ */ u(m.Anchor, {
|
|
73
|
+
asChild: !0,
|
|
74
|
+
children: s
|
|
75
|
+
}), /* @__PURE__ */ u(m.Portal, { children: /* @__PURE__ */ u(m.Content, {
|
|
76
|
+
align: "start",
|
|
77
|
+
sideOffset: 6,
|
|
78
|
+
collisionPadding: 16,
|
|
79
|
+
"aria-label": c,
|
|
80
|
+
onCloseAutoFocus: p,
|
|
81
|
+
className: "kf-popover z-50 max-w-[calc(100vw-2rem)] rounded-md border border-border bg-surface p-3 font-sans text-fg shadow-overlay focus:outline-none",
|
|
82
|
+
children: l
|
|
83
|
+
}) })]
|
|
84
|
+
}) : /* @__PURE__ */ d(n, {
|
|
85
|
+
open: t,
|
|
86
|
+
onOpenChange: o,
|
|
87
|
+
children: [s, /* @__PURE__ */ u(r, {
|
|
88
|
+
side: "bottom",
|
|
89
|
+
size: "lg",
|
|
90
|
+
title: c,
|
|
91
|
+
onCloseAutoFocus: p,
|
|
92
|
+
bodyClassName: "px-4! [&_.kf-cal]:mx-auto [&_.kf-cal]:w-fit [&_.kf-cal]:[--kf-cal-size:2.75rem]",
|
|
93
|
+
children: l
|
|
94
|
+
})]
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function O({ label: n, placeholder: r, size: i, invalid: a, field: c, onClear: l, clearLabel: f, onOpen: p, expanded: m, ...h }) {
|
|
98
|
+
return /* @__PURE__ */ d("div", {
|
|
99
|
+
className: "relative",
|
|
100
|
+
children: [/* @__PURE__ */ d("button", {
|
|
101
|
+
type: "button",
|
|
102
|
+
id: c.id,
|
|
103
|
+
disabled: c.disabled,
|
|
104
|
+
"aria-invalid": c["aria-invalid"],
|
|
105
|
+
"aria-describedby": c["aria-describedby"],
|
|
106
|
+
"aria-haspopup": "dialog",
|
|
107
|
+
"aria-expanded": m,
|
|
108
|
+
onClick: p,
|
|
109
|
+
...h,
|
|
110
|
+
className: e(s(i, a), "flex cursor-pointer items-center gap-2 px-3 pr-10 text-left outline-none disabled:cursor-not-allowed disabled:bg-surface-muted", "focus-visible:border-primary focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-focus),transparent_70%)]", r && "text-fg-muted"),
|
|
111
|
+
children: [/* @__PURE__ */ u(t, {
|
|
112
|
+
name: "c-calendar",
|
|
113
|
+
size: 20,
|
|
114
|
+
className: "shrink-0 text-fg-muted"
|
|
115
|
+
}), /* @__PURE__ */ u("span", {
|
|
116
|
+
className: "min-w-0 flex-1 truncate tabular-nums",
|
|
117
|
+
children: n
|
|
118
|
+
})]
|
|
119
|
+
}), l && !r && !c.disabled && /* @__PURE__ */ u("button", {
|
|
120
|
+
type: "button",
|
|
121
|
+
"aria-label": f,
|
|
122
|
+
onClick: l,
|
|
123
|
+
className: "absolute top-1/2 right-2 grid size-7 -translate-y-1/2 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg-muted hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-focus",
|
|
124
|
+
children: /* @__PURE__ */ u(o, {
|
|
125
|
+
name: "close",
|
|
126
|
+
size: 14
|
|
127
|
+
})
|
|
128
|
+
})]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function k({ value: e, onChange: t, placeholder: n = "Pick a date", disabled: r, displayFormat: i = "PP", locale: a = w, dropdowns: o, startMonth: s, endMonth: l, size: d = "md", labels: m = {}, isDisabled: h, ..._ }) {
|
|
132
|
+
let { invalid: v, ...y } = c({
|
|
133
|
+
..._,
|
|
134
|
+
disabled: h
|
|
135
|
+
}), b = f(), x = {
|
|
136
|
+
...y,
|
|
137
|
+
id: y.id ?? b
|
|
138
|
+
}, [S, C] = p(!1);
|
|
139
|
+
return /* @__PURE__ */ u(D, {
|
|
140
|
+
triggerId: x.id,
|
|
141
|
+
open: S,
|
|
142
|
+
onOpenChange: C,
|
|
143
|
+
title: m.dialog ?? "Choose a date",
|
|
144
|
+
trigger: /* @__PURE__ */ u(O, {
|
|
145
|
+
label: e ? ((e) => g(e, i, { locale: a }))(e) : n,
|
|
146
|
+
placeholder: !e,
|
|
147
|
+
size: d,
|
|
148
|
+
invalid: v,
|
|
149
|
+
field: x,
|
|
150
|
+
clearLabel: m.clear ?? "Clear date",
|
|
151
|
+
onClear: () => t(void 0),
|
|
152
|
+
onOpen: () => C(!0),
|
|
153
|
+
expanded: S
|
|
154
|
+
}),
|
|
155
|
+
children: /* @__PURE__ */ u(E, {
|
|
156
|
+
mode: "single",
|
|
157
|
+
autoFocus: !0,
|
|
158
|
+
selected: e,
|
|
159
|
+
defaultMonth: e,
|
|
160
|
+
onSelect: (e) => {
|
|
161
|
+
t(e), e && C(!1);
|
|
162
|
+
},
|
|
163
|
+
disabled: r,
|
|
164
|
+
locale: a,
|
|
165
|
+
captionLayout: o ? "dropdown" : "label",
|
|
166
|
+
startMonth: s,
|
|
167
|
+
endMonth: l
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
var A = [
|
|
172
|
+
{
|
|
173
|
+
label: "Today",
|
|
174
|
+
range: () => ({
|
|
175
|
+
from: v(/* @__PURE__ */ new Date()),
|
|
176
|
+
to: v(/* @__PURE__ */ new Date())
|
|
177
|
+
})
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
label: "Yesterday",
|
|
181
|
+
range: () => ({
|
|
182
|
+
from: b(v(/* @__PURE__ */ new Date()), 1),
|
|
183
|
+
to: b(v(/* @__PURE__ */ new Date()), 1)
|
|
184
|
+
})
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
label: "Last 7 days",
|
|
188
|
+
range: () => ({
|
|
189
|
+
from: b(v(/* @__PURE__ */ new Date()), 6),
|
|
190
|
+
to: v(/* @__PURE__ */ new Date())
|
|
191
|
+
})
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
label: "Last 30 days",
|
|
195
|
+
range: () => ({
|
|
196
|
+
from: b(v(/* @__PURE__ */ new Date()), 29),
|
|
197
|
+
to: v(/* @__PURE__ */ new Date())
|
|
198
|
+
})
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
label: "This month",
|
|
202
|
+
range: () => ({
|
|
203
|
+
from: y(/* @__PURE__ */ new Date()),
|
|
204
|
+
to: v(/* @__PURE__ */ new Date())
|
|
205
|
+
})
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
label: "Last month",
|
|
209
|
+
range: () => ({
|
|
210
|
+
from: y(x(/* @__PURE__ */ new Date(), 1)),
|
|
211
|
+
to: h(x(/* @__PURE__ */ new Date(), 1))
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
], j = (e, t) => !!(e?.from && e.to && t.from && t.to && _(e.from, t.from) && _(e.to, t.to));
|
|
215
|
+
function M({ value: e, onChange: t, placeholder: n = "Pick a date range", disabled: r, displayFormat: o = "PP", locale: s = w, presets: m = A, presetLayout: h = "list", maxDays: _, startMonth: v, endMonth: y, size: b = "md", labels: x = {}, isDisabled: S, ...C }) {
|
|
216
|
+
let { invalid: T, ...k } = c({
|
|
217
|
+
...C,
|
|
218
|
+
disabled: S
|
|
219
|
+
}), M = f(), N = {
|
|
220
|
+
...k,
|
|
221
|
+
id: k.id ?? M
|
|
222
|
+
}, P = a(i), [F, I] = p(!1), L = f(), [R, z] = p(!1), B = (e) => g(e, o, { locale: s }), V = e?.from ? e.to ? `${B(e.from)} – ${B(e.to)}` : `${B(e.from)} – …` : n, H = h === "select" && m.length > 0, U = "__custom", W = m.find((t) => j(e, t.range())), G = R || e?.from && !W ? U : W?.label, K = x.custom ?? "Custom range", q = H ? {
|
|
223
|
+
...N,
|
|
224
|
+
id: L
|
|
225
|
+
} : N, J = /* @__PURE__ */ u(D, {
|
|
226
|
+
triggerId: q.id,
|
|
227
|
+
open: F,
|
|
228
|
+
onOpenChange: I,
|
|
229
|
+
title: x.dialog ?? "Choose a date range",
|
|
230
|
+
trigger: /* @__PURE__ */ u(O, {
|
|
231
|
+
label: V,
|
|
232
|
+
placeholder: !e?.from,
|
|
233
|
+
size: b,
|
|
234
|
+
invalid: T,
|
|
235
|
+
field: q,
|
|
236
|
+
clearLabel: x.clear ?? "Clear dates",
|
|
237
|
+
onClear: () => t(void 0),
|
|
238
|
+
onOpen: () => I(!0),
|
|
239
|
+
expanded: F,
|
|
240
|
+
"aria-label": H ? `${K}: ${V}` : void 0
|
|
241
|
+
}),
|
|
242
|
+
children: /* @__PURE__ */ d("div", {
|
|
243
|
+
className: "flex min-w-0 flex-col gap-3 sm:flex-row",
|
|
244
|
+
children: [m.length > 0 && !H && /* @__PURE__ */ u("ul", {
|
|
245
|
+
className: "m-0 flex min-w-0 list-none flex-wrap gap-1 p-0 sm:flex-col sm:flex-nowrap sm:border-r sm:border-border sm:pr-3",
|
|
246
|
+
children: m.map((e) => /* @__PURE__ */ u("li", { children: /* @__PURE__ */ u("button", {
|
|
247
|
+
type: "button",
|
|
248
|
+
onClick: () => {
|
|
249
|
+
t(e.range()), I(!1);
|
|
250
|
+
},
|
|
251
|
+
className: "w-full cursor-pointer rounded-sm border-0 bg-transparent px-3 py-2 text-left font-sans text-sm font-medium whitespace-nowrap text-fg hover:bg-surface-muted focus-visible:outline-3 focus-visible:outline-focus",
|
|
252
|
+
children: e.label
|
|
253
|
+
}) }, e.label))
|
|
254
|
+
}), /* @__PURE__ */ u(E, {
|
|
255
|
+
mode: "range",
|
|
256
|
+
autoFocus: !0,
|
|
257
|
+
selected: e,
|
|
258
|
+
defaultMonth: e?.from,
|
|
259
|
+
onSelect: (e) => {
|
|
260
|
+
t(e), e?.from && e.to && e.from.getTime() !== e.to.getTime() && I(!1);
|
|
261
|
+
},
|
|
262
|
+
numberOfMonths: P ? 2 : 1,
|
|
263
|
+
max: _,
|
|
264
|
+
disabled: r,
|
|
265
|
+
locale: s,
|
|
266
|
+
startMonth: v,
|
|
267
|
+
endMonth: y
|
|
268
|
+
})]
|
|
269
|
+
})
|
|
270
|
+
});
|
|
271
|
+
return H ? /* @__PURE__ */ d("div", {
|
|
272
|
+
className: "flex flex-wrap items-center gap-x-3 gap-y-2",
|
|
273
|
+
children: [/* @__PURE__ */ u(l, {
|
|
274
|
+
id: N.id,
|
|
275
|
+
width: "sm",
|
|
276
|
+
className: "min-w-44",
|
|
277
|
+
disabled: N.disabled,
|
|
278
|
+
"aria-label": x.presets,
|
|
279
|
+
value: G ?? "",
|
|
280
|
+
placeholder: n,
|
|
281
|
+
options: [...m.map((e) => ({
|
|
282
|
+
value: e.label,
|
|
283
|
+
label: e.label
|
|
284
|
+
})), {
|
|
285
|
+
value: U,
|
|
286
|
+
label: K
|
|
287
|
+
}],
|
|
288
|
+
onValueChange: (e) => {
|
|
289
|
+
if (e === U) {
|
|
290
|
+
z(!0), I(!0);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
z(!1);
|
|
294
|
+
let n = m.find((t) => t.label === e);
|
|
295
|
+
n && t(n.range());
|
|
296
|
+
}
|
|
297
|
+
}), G === U ? /* @__PURE__ */ u("div", {
|
|
298
|
+
className: "min-w-64 flex-1",
|
|
299
|
+
children: J
|
|
300
|
+
}) : e?.from && /* @__PURE__ */ u("span", {
|
|
301
|
+
className: "text-sm text-fg-muted tabular-nums",
|
|
302
|
+
children: V
|
|
303
|
+
})]
|
|
304
|
+
}) : J;
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
307
|
+
export { E as Calendar, A as DEFAULT_PRESETS, k as DatePicker, M as DateRangePicker };
|
|
308
|
+
|
|
309
|
+
//# sourceMappingURL=date-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-picker.js","names":["Popover","CLASS_NAMES","Calendar","enUS","rest","DayPicker","classNames","date","labelDayButton","modifiers","options","dateLib","labels","Glyph","orientation","PickerShell","desktop","useMediaQuery","DESKTOP_QUERY","returnFocus","e","triggerId","trigger","title","Drawer","DrawerContent","TriggerButton","field","expanded","onOpen","cx","controlClasses","size","invalid","placeholder","Icon","label","onClear","clearLabel","DatePicker","f","useFieldProps","isDisabled","autoId","useId","open","setOpen","useState","value","format","d","displayFormat","onChange","dropdowns","DEFAULT_PRESETS","startOfDay","subDays","startOfMonth","subMonths","endOfMonth","sameRange","a","b","isSameDay","DateRangePicker","pickerId","customChosen","setCustomChosen","fmt","asSelect","presetLayout","presets","CUSTOM","matched","p","selected","customLabel","pickerField","picker","r","maxDays","Select","key","preset"],"sources":["../../src/date-picker/date-picker.tsx"],"sourcesContent":["'use client';\n\nimport * as Popover from '@radix-ui/react-popover';\nimport { endOfMonth, format, isSameDay, startOfDay, startOfMonth, subDays, subMonths } from 'date-fns';\nimport { useId, useState, type ComponentProps, type ReactNode } from 'react';\nimport { DayPicker, labelDayButton, type DateRange, type DayPickerLocale, type Matcher } from 'react-day-picker';\nimport { enUS } from 'react-day-picker/locale';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\nimport { Icon } from '../icon/icon';\nimport { useMediaQuery, DESKTOP_QUERY } from '../lib/use-media-query';\nimport { Drawer, DrawerContent } from '../drawer/drawer';\nimport { useFieldProps } from '../input/input';\nimport { controlClasses, type ControlSize } from '../input/field-styles';\nimport { Select } from '../select/select';\n\nexport type { DateRange };\n\n/* ---------------- Calendar ---------------- */\n\nconst CLASS_NAMES = {\n root: 'kf-cal',\n months: 'kf-cal-months',\n month: 'kf-cal-month',\n month_caption: 'kf-cal-caption',\n caption_label: 'kf-cal-caption-label',\n nav: 'kf-cal-nav',\n button_previous: 'kf-cal-nav-btn',\n button_next: 'kf-cal-nav-btn',\n chevron: 'kf-cal-chevron',\n month_grid: 'kf-cal-grid',\n weekdays: 'kf-cal-weekdays',\n weekday: 'kf-cal-weekday',\n week: 'kf-cal-week',\n day: 'kf-cal-day',\n day_button: 'kf-cal-day-btn',\n selected: 'is-selected',\n today: 'is-today',\n outside: 'is-outside',\n disabled: 'is-disabled',\n hidden: 'is-hidden',\n range_start: 'is-range-start',\n range_middle: 'is-range-middle',\n range_end: 'is-range-end',\n dropdowns: 'kf-cal-dropdowns',\n dropdown_root: 'kf-cal-dropdown-root',\n dropdown: 'kf-cal-dropdown',\n footer: 'kf-cal-footer',\n};\n\nexport type CalendarProps = ComponentProps<typeof DayPicker>;\n\n/**\n * Month grid with keyboard navigation (arrows, PageUp/PageDown, Home/End), built on\n * react-day-picker (ADR-0004) and styled with Kodffe tokens. Pass `locale` from\n * `react-day-picker/locale` (`es`, `enUS`).\n */\nexport function Calendar({ classNames, locale = enUS, labels, ...rest }: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays\n locale={locale}\n classNames={{ ...CLASS_NAMES, ...classNames }}\n labels={{\n // Start the accessible name with the visible day number (\"20 – Friday, November 20th…\")\n // so voice-control users can say what they see.\n labelDayButton: (date, modifiers, options, dateLib) => `${date.getDate()} – ${labelDayButton(date, modifiers, options, dateLib)}`,\n ...labels,\n }}\n components={{\n Chevron: ({ orientation }) => (\n <Glyph\n name={\n orientation === 'left'\n ? 'chevron-left'\n : orientation === 'right'\n ? 'chevron-right'\n : orientation === 'up'\n ? 'chevron-up'\n : 'chevron-down'\n }\n size={16}\n />\n ),\n }}\n {...(rest as object)}\n />\n );\n}\n\n/* ---------------- Shared trigger + surface ---------------- */\n\ninterface PickerShellProps {\n /** id of the field button; focus returns there on close. */\n triggerId: string;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n trigger: ReactNode;\n title: string;\n children: ReactNode;\n}\n\n/** Popover on desktop; bottom drawer with large day targets on mobile. */\nfunction PickerShell({ triggerId, open, onOpenChange, trigger, title, children }: PickerShellProps) {\n const desktop = useMediaQuery(DESKTOP_QUERY);\n const returnFocus = (e: Event) => {\n e.preventDefault();\n document.getElementById(triggerId)?.focus();\n };\n if (!desktop) {\n return (\n <Drawer open={open} onOpenChange={onOpenChange}>\n {trigger}\n <DrawerContent\n side=\"bottom\"\n size=\"lg\"\n title={title}\n onCloseAutoFocus={returnFocus}\n // Large day targets, shrinking to fit 7 columns on the smallest phones (320px).\n bodyClassName=\"px-4! [&_.kf-cal]:mx-auto [&_.kf-cal]:w-fit [&_.kf-cal]:[--kf-cal-size:2.75rem]\"\n >\n {children}\n </DrawerContent>\n </Drawer>\n );\n }\n return (\n <Popover.Root open={open} onOpenChange={onOpenChange}>\n <Popover.Anchor asChild>{trigger}</Popover.Anchor>\n <Popover.Portal>\n <Popover.Content\n align=\"start\"\n sideOffset={6}\n collisionPadding={16}\n aria-label={title}\n onCloseAutoFocus={returnFocus}\n className=\"kf-popover z-50 max-w-[calc(100vw-2rem)] rounded-md border border-border bg-surface p-3 font-sans text-fg shadow-overlay focus:outline-none\"\n >\n {children}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\ninterface TriggerProps {\n label: ReactNode;\n placeholder: boolean;\n size: ControlSize;\n invalid: boolean;\n field: Omit<ReturnType<typeof useFieldProps>, 'invalid'>;\n onClear?: () => void;\n clearLabel: string;\n onOpen?: () => void;\n expanded: boolean;\n 'aria-label'?: string;\n}\n\nfunction TriggerButton({\n label,\n placeholder,\n size,\n invalid,\n field,\n onClear,\n clearLabel,\n onOpen,\n expanded,\n ...rest\n}: TriggerProps) {\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n id={field.id}\n disabled={field.disabled}\n aria-invalid={field['aria-invalid']}\n aria-describedby={field['aria-describedby']}\n aria-haspopup=\"dialog\"\n aria-expanded={expanded}\n onClick={onOpen}\n {...rest}\n className={cx(\n controlClasses(size, invalid),\n 'flex cursor-pointer items-center gap-2 px-3 pr-10 text-left outline-none disabled:cursor-not-allowed disabled:bg-surface-muted',\n 'focus-visible:border-primary focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-focus),transparent_70%)]',\n placeholder && 'text-fg-muted',\n )}\n >\n <Icon name=\"c-calendar\" size={20} className=\"shrink-0 text-fg-muted\" />\n <span className=\"min-w-0 flex-1 truncate tabular-nums\">{label}</span>\n </button>\n {onClear && !placeholder && !field.disabled && (\n <button\n type=\"button\"\n aria-label={clearLabel}\n onClick={onClear}\n className=\"absolute top-1/2 right-2 grid size-7 -translate-y-1/2 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg-muted hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-focus\"\n >\n <Glyph name=\"close\" size={14} />\n </button>\n )}\n </div>\n );\n}\n\n/* ---------------- DatePicker ---------------- */\n\nexport interface DatePickerProps {\n value: Date | undefined;\n onChange: (value: Date | undefined) => void;\n placeholder?: string;\n /** Days that cannot be picked: `{ before: new Date() }`, `{ dayOfWeek: [0, 6] }`, a function… */\n disabled?: Matcher | Matcher[];\n /** date-fns format for the field (\"PP\" → \"Nov 4, 2026\" / \"4 nov 2026\"). */\n displayFormat?: string;\n locale?: Partial<DayPickerLocale>;\n /** Month/year dropdowns, e.g. for birth dates. */\n dropdowns?: boolean;\n startMonth?: Date;\n endMonth?: Date;\n size?: ControlSize;\n id?: string;\n invalid?: boolean;\n required?: boolean;\n isDisabled?: boolean;\n labels?: { dialog?: string; clear?: string };\n}\n\n/** Single date: field + calendar (popover on desktop, bottom sheet on mobile). */\nexport function DatePicker({\n value,\n onChange,\n placeholder = 'Pick a date',\n disabled,\n displayFormat = 'PP',\n locale = enUS,\n dropdowns,\n startMonth,\n endMonth,\n size = 'md',\n labels = {},\n isDisabled,\n ...rest\n}: DatePickerProps) {\n const { invalid, ...f } = useFieldProps({ ...rest, disabled: isDisabled });\n const autoId = useId();\n const field = { ...f, id: f.id ?? autoId };\n const [open, setOpen] = useState(false);\n const fmt = (d: Date) => format(d, displayFormat, { locale: locale as never });\n return (\n <PickerShell\n triggerId={field.id}\n open={open}\n onOpenChange={setOpen}\n title={labels.dialog ?? 'Choose a date'}\n trigger={\n <TriggerButton\n label={value ? fmt(value) : placeholder}\n placeholder={!value}\n size={size}\n invalid={invalid}\n field={field}\n clearLabel={labels.clear ?? 'Clear date'}\n onClear={() => onChange(undefined)}\n onOpen={() => setOpen(true)}\n expanded={open}\n />\n }\n >\n <Calendar\n mode=\"single\"\n autoFocus\n selected={value}\n defaultMonth={value}\n onSelect={(d: Date | undefined) => {\n onChange(d);\n if (d) setOpen(false);\n }}\n disabled={disabled}\n locale={locale}\n captionLayout={dropdowns ? 'dropdown' : 'label'}\n startMonth={startMonth}\n endMonth={endMonth}\n />\n </PickerShell>\n );\n}\n\n/* ---------------- DateRangePicker ---------------- */\n\nexport interface RangePreset {\n label: string;\n range: () => DateRange;\n}\n\n/** Presets relative to today. Labels are English; pass translated ones via `presets`. */\nexport const DEFAULT_PRESETS: RangePreset[] = [\n { label: 'Today', range: () => ({ from: startOfDay(new Date()), to: startOfDay(new Date()) }) },\n { label: 'Yesterday', range: () => ({ from: subDays(startOfDay(new Date()), 1), to: subDays(startOfDay(new Date()), 1) }) },\n { label: 'Last 7 days', range: () => ({ from: subDays(startOfDay(new Date()), 6), to: startOfDay(new Date()) }) },\n { label: 'Last 30 days', range: () => ({ from: subDays(startOfDay(new Date()), 29), to: startOfDay(new Date()) }) },\n { label: 'This month', range: () => ({ from: startOfMonth(new Date()), to: startOfDay(new Date()) }) },\n {\n label: 'Last month',\n range: () => ({ from: startOfMonth(subMonths(new Date(), 1)), to: endOfMonth(subMonths(new Date(), 1)) }),\n },\n];\n\nexport interface DateRangePickerProps extends Omit<DatePickerProps, 'value' | 'onChange' | 'dropdowns'> {\n value: DateRange | undefined;\n onChange: (value: DateRange | undefined) => void;\n /** Quick ranges shown beside the calendar. `[]` hides them. */\n presets?: RangePreset[];\n /** Longest allowed range in days. */\n maxDays?: number;\n /**\n * `list` (default): presets beside the calendar. `select`: a select of presets with the resolved range beside it,\n * and a \"Custom range\" option that shows the calendar field (report and attendance filters).\n */\n presetLayout?: 'list' | 'select';\n labels?: DatePickerProps['labels'] & { custom?: string; presets?: string };\n}\n\nconst sameRange = (a: DateRange | undefined, b: DateRange) =>\n Boolean(a?.from && a.to && b.from && b.to && isSameDay(a.from, b.from) && isSameDay(a.to, b.to));\n\n/** Date range with presets: two months on desktop, one in the mobile sheet. */\nexport function DateRangePicker({\n value,\n onChange,\n placeholder = 'Pick a date range',\n disabled,\n displayFormat = 'PP',\n locale = enUS,\n presets = DEFAULT_PRESETS,\n presetLayout = 'list',\n maxDays,\n startMonth,\n endMonth,\n size = 'md',\n labels = {},\n isDisabled,\n ...rest\n}: DateRangePickerProps) {\n const { invalid, ...f } = useFieldProps({ ...rest, disabled: isDisabled });\n const autoId = useId();\n const field = { ...f, id: f.id ?? autoId };\n const desktop = useMediaQuery(DESKTOP_QUERY);\n const [open, setOpen] = useState(false);\n const pickerId = useId();\n const [customChosen, setCustomChosen] = useState(false);\n const fmt = (d: Date) => format(d, displayFormat, { locale: locale as never });\n const label = value?.from\n ? value.to\n ? `${fmt(value.from)} – ${fmt(value.to)}`\n : `${fmt(value.from)} – …`\n : placeholder;\n const asSelect = presetLayout === 'select' && presets.length > 0;\n const CUSTOM = '__custom';\n const matched = presets.find((p) => sameRange(value, p.range()));\n const selected = customChosen || (value?.from && !matched) ? CUSTOM : matched?.label;\n const customLabel = labels.custom ?? 'Custom range';\n // In select mode the field's label goes to the select; the calendar field is named \"Custom range\".\n const pickerField = asSelect ? { ...field, id: pickerId } : field;\n\n const picker = (\n <PickerShell\n triggerId={pickerField.id}\n open={open}\n onOpenChange={setOpen}\n title={labels.dialog ?? 'Choose a date range'}\n trigger={\n <TriggerButton\n label={label}\n placeholder={!value?.from}\n size={size}\n invalid={invalid}\n field={pickerField}\n clearLabel={labels.clear ?? 'Clear dates'}\n onClear={() => onChange(undefined)}\n onOpen={() => setOpen(true)}\n expanded={open}\n // Visible text (the dates) must be part of the name: \"Custom range: Nov 6 – Nov 12\".\n aria-label={asSelect ? `${customLabel}: ${label}` : undefined}\n />\n }\n >\n <div className=\"flex min-w-0 flex-col gap-3 sm:flex-row\">\n {presets.length > 0 && !asSelect && (\n // Mobile: presets wrap above the calendar; never wider than the sheet.\n <ul className=\"m-0 flex min-w-0 list-none flex-wrap gap-1 p-0 sm:flex-col sm:flex-nowrap sm:border-r sm:border-border sm:pr-3\">\n {presets.map((p) => (\n <li key={p.label}>\n <button\n type=\"button\"\n onClick={() => {\n onChange(p.range());\n setOpen(false);\n }}\n className=\"w-full cursor-pointer rounded-sm border-0 bg-transparent px-3 py-2 text-left font-sans text-sm font-medium whitespace-nowrap text-fg hover:bg-surface-muted focus-visible:outline-3 focus-visible:outline-focus\"\n >\n {p.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n <Calendar\n mode=\"range\"\n autoFocus\n selected={value}\n defaultMonth={value?.from}\n onSelect={(r: DateRange | undefined) => {\n onChange(r);\n if (r?.from && r.to && r.from.getTime() !== r.to.getTime()) setOpen(false);\n }}\n numberOfMonths={desktop ? 2 : 1}\n max={maxDays}\n disabled={disabled}\n locale={locale}\n startMonth={startMonth}\n endMonth={endMonth}\n />\n </div>\n </PickerShell>\n );\n\n if (!asSelect) return picker;\n return (\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">\n <Select\n id={field.id}\n width=\"sm\"\n className=\"min-w-44\"\n disabled={field.disabled}\n aria-label={labels.presets}\n // Always controlled: '' shows the placeholder when the range is cleared from outside (a filter Reset).\n value={selected ?? ''}\n placeholder={placeholder}\n options={[...presets.map((p) => ({ value: p.label, label: p.label })), { value: CUSTOM, label: customLabel }]}\n onValueChange={(key) => {\n if (key === CUSTOM) {\n setCustomChosen(true);\n setOpen(true);\n return;\n }\n setCustomChosen(false);\n const preset = presets.find((p) => p.label === key);\n if (preset) onChange(preset.range());\n }}\n />\n {selected === CUSTOM ? (\n <div className=\"min-w-64 flex-1\">{picker}</div>\n ) : (\n value?.from && <span className=\"text-sm text-fg-muted tabular-nums\">{label}</span>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as Dialog from '@radix-ui/react-dialog';
|
|
2
|
+
import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
3
|
+
export type DrawerSide = 'left' | 'right' | 'bottom';
|
|
4
|
+
export type DrawerSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
export interface DrawerProps {
|
|
6
|
+
open?: boolean;
|
|
7
|
+
defaultOpen?: boolean;
|
|
8
|
+
onOpenChange?: (open: boolean) => void;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Panel that slides in from an edge while keeping the page context: navigation on mobile,
|
|
13
|
+
* filters, record details, settings. Swipe toward its edge to dismiss on touch screens.
|
|
14
|
+
*/
|
|
15
|
+
export declare function Drawer({ open: openProp, defaultOpen, onOpenChange, children }: DrawerProps): import("react").JSX.Element;
|
|
16
|
+
export declare const DrawerTrigger: import("react").ForwardRefExoticComponent<Dialog.DialogTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
17
|
+
export declare const DrawerClose: import("react").ForwardRefExoticComponent<Dialog.DialogCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
18
|
+
export interface DrawerContentProps extends Omit<ComponentPropsWithoutRef<typeof Dialog.Content>, 'title' | 'asChild'> {
|
|
19
|
+
title: ReactNode;
|
|
20
|
+
description?: ReactNode;
|
|
21
|
+
side?: DrawerSide;
|
|
22
|
+
size?: DrawerSize;
|
|
23
|
+
footer?: ReactNode;
|
|
24
|
+
hideTitle?: boolean;
|
|
25
|
+
hideClose?: boolean;
|
|
26
|
+
closeLabel?: string;
|
|
27
|
+
/** `brand`: the header is a solid brand band (record and edit drawers in product dashboards). */
|
|
28
|
+
headerTone?: 'default' | 'brand';
|
|
29
|
+
/** Extra classes for the scrollable body. To override its padding use the important modifier (`px-0!`). */
|
|
30
|
+
bodyClassName?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function DrawerContent({ title, description, side, size, footer, hideTitle, hideClose, closeLabel, headerTone, bodyClassName, className, children, ...rest }: DrawerContentProps): import("react").JSX.Element;
|