@alexgorbatchev/shadcn 0.0.29 → 0.0.31

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.
Files changed (38) hide show
  1. package/README.md +25 -22
  2. package/THIRD_PARTY_NOTICES.md +6 -0
  3. package/dist/chunk-1xncv9gb.js +19 -0
  4. package/dist/chunk-2dxa9enk.js +98 -0
  5. package/dist/{chunk-3z5gpbh0.js → chunk-987zth0a.js} +1 -1
  6. package/dist/{chunk-g238nezp.js → chunk-pg9rhbgm.js} +4 -2
  7. package/dist/{chunk-5da3rzn5.js → chunk-s0typ7hv.js} +1 -1
  8. package/dist/{chunk-eehfrrdz.js → chunk-tnnf8ydf.js} +1 -15
  9. package/dist/chunk-yfr9syen.js +363 -0
  10. package/dist/{chunk-v0k5jnk5.js → chunk-zte6pw69.js} +2 -1
  11. package/dist/components/Table.d.ts +7 -3
  12. package/dist/components/assistant-ui/elements/DataTable.js +2 -2
  13. package/dist/components/assistant-ui/elements/OptionList.js +3 -2
  14. package/dist/components/assistant-ui/elements/QuestionFlow.js +4 -3
  15. package/dist/components/assistant-ui/index.js +6 -5
  16. package/dist/components/data-grid/DataGrid.d.ts +48 -9
  17. package/dist/components/data-grid/DataGridColumnOptions.d.ts +14 -0
  18. package/dist/components/data-grid/DataGridColumnResizer.d.ts +13 -0
  19. package/dist/components/data-grid/getDataGridColumnSizeVariables.d.ts +6 -0
  20. package/dist/components/data-grid/hooks/useDataGridColumnSizes.d.ts +8 -0
  21. package/dist/components/data-grid/index.d.ts +3 -2
  22. package/dist/components/data-grid/index.js +124 -199
  23. package/dist/components/data-grid/moveDataGridColumn.d.ts +5 -0
  24. package/dist/components/event-calendar/index.js +4 -2
  25. package/dist/components/gantt/index.js +1 -1
  26. package/dist/components/virtual-data-grid/VirtualDataGrid.d.ts +26 -0
  27. package/dist/components/virtual-data-grid/index.d.ts +2 -0
  28. package/dist/components/virtual-data-grid/index.js +88 -0
  29. package/dist/components/virtual-table/index.js +4 -96
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +6 -4
  32. package/llms/components/data-display/DataGridColumnOptions.md +22 -0
  33. package/llms/components/data-display/Table.md +1 -1
  34. package/llms/components/data-display/VirtualDataGrid.md +71 -0
  35. package/llms/components/data-display/VirtualTable.md +2 -2
  36. package/llms/setup.md +25 -22
  37. package/llms.txt +2 -0
  38. package/package.json +6 -2
package/README.md CHANGED
@@ -50,28 +50,29 @@ Package preparation and contributor commands are documented in [AGENTS.md](./AGE
50
50
 
51
51
  Import shared controls and providers from `@alexgorbatchev/shadcn`. Import the following features from their dedicated entry points and install only the peers you use. These features, their hooks, and their types are not exported from the package root.
52
52
 
53
- | Import path suffix | Components | Install alongside the package |
54
- | ------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
55
- | `/chart` | Chart parts, AnalyticsChart, Sparkline, hooks and types | `bun add recharts@3.8.0 cssesc@3.0.0 es-toolkit@1.52.0` |
56
- | `/calendar` | Calendar, CalendarDayButton, DatePicker, DateRangePicker | `bun add @daypicker/react@^10.0.2` |
57
- | `/persian-calendar` | PersianCalendar | `bun add @daypicker/persian@^10.0.2 @daypicker/react@^10.0.2` |
58
- | `/carousel` | Carousel components, useCarousel, and carousel types | `bun add embla-carousel-react@^8.6.0` |
59
- | `/command` | Command components, including CommandDialog | `bun add cmdk@^1.1.1` |
60
- | `/resizable` | Resizable components and SplitView | `bun add react-resizable-panels@^4.14.3` |
61
- | `/fonts.css` | JetBrains Mono font stylesheet | `bun add @fontsource-variable/jetbrains-mono@^5.3.0` |
62
- | `/sonner` | Sonner, SonnerToaster, Toaster, toast, useSonner | No additional install; patched implementation is bundled |
63
- | `/input-otp` | InputOTP components | No additional install; patched implementation is bundled |
64
- | `/virtual-table` | VirtualTable and row measurement props | `@tanstack/react-virtual@3.14.13` |
65
- | `/message-scroller` | MessageScroller components, hooks, and types | No additional install; patched implementation is bundled |
66
- | `/questionnaire` | Questionnaire components and types | No additional install; patched implementation is bundled |
67
- | `/data-grid` | DataGrid and native table helpers | `bun add @tanstack/react-table@9.2.8` |
68
- | `/file-upload` | FileUpload selection and validation | `bun add react-dropzone@^20.1.4` |
69
- | `/color-picker` | ColorPicker | `bun add react-colorful@^5.8.1` |
70
- | `/image-crop` | ImageCrop and native export helpers | `bun add react-image-crop@^11.1.2` |
71
- | `/tree` | Tree, native hooks and features | `bun add @headless-tree/core@^1.8.0 @headless-tree/react@^1.8.0` |
72
- | `/editor` | RichTextEditor, native Tiptap hooks and StarterKit | `bun add @tiptap/core@^3.32.0 @tiptap/react@^3.32.0 @tiptap/pm@^3.32.0 @tiptap/starter-kit@^3.32.0` |
73
- | `/event-calendar` | EventCalendar, EventForm and native calendar APIs | `bun add date-fns@^4.4.0`; TypeScript: `bun add -d @types/react-big-calendar@^1.16.3` |
74
- | `/gantt` | Gantt and Roadmap | `bun add date-fns@^4.4.0 @date-fns/tz@^1.5.0` |
53
+ | Import path suffix | Components | Install alongside the package |
54
+ | -------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
55
+ | `/chart` | Chart parts, AnalyticsChart, Sparkline, hooks and types | `bun add recharts@3.8.0 cssesc@3.0.0 es-toolkit@1.52.0` |
56
+ | `/calendar` | Calendar, CalendarDayButton, DatePicker, DateRangePicker | `bun add @daypicker/react@^10.0.2` |
57
+ | `/persian-calendar` | PersianCalendar | `bun add @daypicker/persian@^10.0.2 @daypicker/react@^10.0.2` |
58
+ | `/carousel` | Carousel components, useCarousel, and carousel types | `bun add embla-carousel-react@^8.6.0` |
59
+ | `/command` | Command components, including CommandDialog | `bun add cmdk@^1.1.1` |
60
+ | `/resizable` | Resizable components and SplitView | `bun add react-resizable-panels@^4.14.3` |
61
+ | `/fonts.css` | JetBrains Mono font stylesheet | `bun add @fontsource-variable/jetbrains-mono@^5.3.0` |
62
+ | `/sonner` | Sonner, SonnerToaster, Toaster, toast, useSonner | No additional install; patched implementation is bundled |
63
+ | `/input-otp` | InputOTP components | No additional install; patched implementation is bundled |
64
+ | `/virtual-table` | VirtualTable and row measurement props | `@tanstack/react-virtual@3.14.13` |
65
+ | `/message-scroller` | MessageScroller components, hooks, and types | No additional install; patched implementation is bundled |
66
+ | `/questionnaire` | Questionnaire components and types | No additional install; patched implementation is bundled |
67
+ | `/data-grid` | DataGrid, column picker, and native table helpers | `bun add @tanstack/react-table@9.2.8` |
68
+ | `/virtual-data-grid` | VirtualDataGrid and row measurement props | `bun add @tanstack/react-table@9.2.8 @tanstack/react-virtual@3.14.13` |
69
+ | `/file-upload` | FileUpload selection and validation | `bun add react-dropzone@^20.1.4` |
70
+ | `/color-picker` | ColorPicker | `bun add react-colorful@^5.8.1` |
71
+ | `/image-crop` | ImageCrop and native export helpers | `bun add react-image-crop@^11.1.2` |
72
+ | `/tree` | Tree, native hooks and features | `bun add @headless-tree/core@^1.8.0 @headless-tree/react@^1.8.0` |
73
+ | `/editor` | RichTextEditor, native Tiptap hooks and StarterKit | `bun add @tiptap/core@^3.32.0 @tiptap/react@^3.32.0 @tiptap/pm@^3.32.0 @tiptap/starter-kit@^3.32.0` |
74
+ | `/event-calendar` | EventCalendar, EventForm and native calendar APIs | `bun add date-fns@^4.4.0`; TypeScript: `bun add -d @types/react-big-calendar@^1.16.3` |
75
+ | `/gantt` | Gantt and Roadmap | `bun add date-fns@^4.4.0 @date-fns/tz@^1.5.0` |
75
76
 
76
77
  Import `@alexgorbatchev/shadcn/event-calendar.css` for EventCalendar, and `react-image-crop/dist/ReactCrop.css` for ImageCrop. The root also provides application shells, dashboard and billing layouts, authentication/settings forms, account/workspace controls, Kanban, facets, tags, number fields, toolbars, meters, stat cards and status displays. See the [component catalog reference](./docs/internal/component-catalog.md) for source groups, native APIs, dependency costs and consumer responsibilities.
77
78
 
@@ -302,6 +303,8 @@ Compose `QuestionnaireItem`, `QuestionnaireTitle`, and answer controls inside `Q
302
303
 
303
304
  `VirtualTable` renders a bounded, dynamically measured set of native table rows using TanStack Virtual. Supply `items`, stable `getItemKey`, `header`, `label`, and `renderRow`; spread the supplied measurement props onto each native row. Optional `columns` accepts a `TableColumnGroup`; responsive columns keep their widths aligned with cells that share their `visibleFrom`. `maxHeight` defaults to `65vh`, `estimateRowHeight` to 80 pixels, and `overscan` to five rows. `retainedKeys` keeps editing rows mounted; the focused row is retained automatically. Filtering and selection belong to the consumer.
304
305
 
306
+ `VirtualDataGrid` renders a TanStack Table instance built with `dataGridFeatures` through `VirtualTable`: every filtered and sorted row, without pagination, in a fixed-layout table. Column `meta` sets `label`, `textAlign`, `truncate`, `visibleFrom`, and `fill`; a `fill` column takes the width the sized columns leave. Other resizable columns get a window-splitter handle that resizes by dragging, by the arrow keys, Home, and End, and resets on double-click. Widths change through CSS variables, so a `useTable` selector can omit `columnSizing` and `columnResizing` to keep resizing from rendering rows. `renderRow` receives each row and its measurement props; spread the props onto a `TableRow` and render `DataGridCells` inside it to wrap rows in menus or drag sources. `retainedRowIds` keeps rows mounted while they hold editors. `DataGridColumnOptions` shows, hides, and reorders the columns that allow hiding; its reset restores the table's initial visibility, order, and sizes.
307
+
305
308
  `StarRating` takes a controlled numeric `value` from 0 to 5, `onValueChange`, and an accessible `label`. Its native radio buttons support keyboard selection and an Unrated option to clear the rating. Set `disabled` while saving. `Avatar shape="square"` displays square artwork with matching image, fallback, and border corners.
306
309
 
307
310
  `DialogContent size="wide"` uses a desktop maximum width of 576px; `size="narrow"` uses 192px, and the default uses 384px. Dialogs remain bounded by the viewport. `FieldGroup columns={2}` arranges fields in two columns on desktop and one on mobile.
@@ -164,6 +164,12 @@ DataGrid, FilterBar, Stepper, FileUpload, Tree, Kanban and planning compositions
164
164
 
165
165
  Reviewed source: https://github.com/keenthemes/reui/tree/067aa0dc7f8bbfec1cd76fc5ad31f842be5f569a
166
166
 
167
+ ## TanStack Table examples
168
+
169
+ VirtualDataGrid and DataGridColumnOptions follow the MIT-licensed TanStack Table React examples for virtualized rows, performant column resizing through CSS variables, column ordering, and column visibility. The package implementation, styling, keyboard resizing and behavioral tests are package-owned.
170
+
171
+ Reviewed source: https://github.com/TanStack/table/tree/main/examples/react
172
+
167
173
  MIT License
168
174
 
169
175
  Copyright (c) 2025 Keenthemes Inc
@@ -0,0 +1,19 @@
1
+ import {
2
+ cn2
3
+ } from "./chunk-cp2m7y7v.js";
4
+
5
+ // src/components/Spinner.tsx
6
+ import { Loader2Icon } from "lucide-react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ function Spinner2({ density, className, ...props }) {
9
+ return /* @__PURE__ */ jsx(Loader2Icon, {
10
+ "data-density": density,
11
+ "data-slot": "spinner",
12
+ role: "status",
13
+ "aria-label": "Loading",
14
+ className: cn2("size-4 animate-spin", className),
15
+ ...props
16
+ });
17
+ }
18
+
19
+ export { Spinner2 };
@@ -0,0 +1,98 @@
1
+ import {
2
+ Table2,
3
+ TableHeader2,
4
+ TableBody2
5
+ } from "./chunk-zte6pw69.js";
6
+
7
+ // src/components/virtual-table/VirtualTable.tsx
8
+ import {
9
+ Fragment,
10
+ useCallback,
11
+ useMemo,
12
+ useRef,
13
+ useState
14
+ } from "react";
15
+ import { defaultRangeExtractor, useVirtualizer } from "@tanstack/react-virtual";
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ function VirtualTable2({
18
+ items,
19
+ getItemKey,
20
+ renderRow,
21
+ header,
22
+ columns,
23
+ label,
24
+ maxHeight = "65vh",
25
+ estimateRowHeight = 80,
26
+ overscan = 5,
27
+ retainedKeys,
28
+ layout = "fixed"
29
+ }) {
30
+ const viewport = useRef(null);
31
+ const [focusedKey, setFocusedKey] = useState();
32
+ const retained = useMemo(() => items.flatMap((item, index) => retainedKeys?.includes(getItemKey(item)) || getItemKey(item) === focusedKey ? [index] : []), [items, retainedKeys, getItemKey, focusedKey]);
33
+ const rangeExtractor = useCallback((range) => [...new Set([...defaultRangeExtractor(range), ...retained])].sort((a, b) => a - b), [retained]);
34
+ const itemKey = useCallback((index) => getItemKey(items[index]), [items, getItemKey]);
35
+ const virtualizer = useVirtualizer({
36
+ count: items.length,
37
+ getScrollElement: () => viewport.current,
38
+ getItemKey: itemKey,
39
+ estimateSize: () => estimateRowHeight,
40
+ overscan,
41
+ rangeExtractor
42
+ });
43
+ const rows = virtualizer.getVirtualItems();
44
+ const last = rows.at(-1);
45
+ return /* @__PURE__ */ jsx("div", {
46
+ ref: viewport,
47
+ "data-testid": "VirtualTable",
48
+ role: "region",
49
+ "aria-label": label,
50
+ tabIndex: 0,
51
+ className: "min-w-0 overflow-auto overscroll-contain",
52
+ style: { maxHeight },
53
+ onFocusCapture: (event) => {
54
+ const row = event.target.closest("tr[data-index]");
55
+ const item = items[Number(row?.dataset.index)];
56
+ if (row && item)
57
+ setFocusedKey(getItemKey(item));
58
+ },
59
+ children: /* @__PURE__ */ jsxs(Table2, {
60
+ layout,
61
+ "aria-label": label,
62
+ "aria-rowcount": items.length + 1,
63
+ children: [
64
+ columns,
65
+ /* @__PURE__ */ jsx(TableHeader2, {
66
+ children: header
67
+ }),
68
+ /* @__PURE__ */ jsxs(TableBody2, {
69
+ children: [
70
+ rows.map((row, index) => /* @__PURE__ */ jsxs(Fragment, {
71
+ children: [
72
+ row.start > (rows[index - 1]?.end ?? 0) && /* @__PURE__ */ jsx("tr", {
73
+ "aria-hidden": "true",
74
+ children: /* @__PURE__ */ jsx("td", {
75
+ style: { height: row.start - (rows[index - 1]?.end ?? 0), padding: 0, border: 0 }
76
+ })
77
+ }),
78
+ renderRow(items[row.index], {
79
+ ref: virtualizer.measureElement,
80
+ "data-index": row.index,
81
+ "aria-rowindex": row.index + 2
82
+ })
83
+ ]
84
+ }, row.key)),
85
+ last && virtualizer.getTotalSize() > last.end && /* @__PURE__ */ jsx("tr", {
86
+ "aria-hidden": "true",
87
+ children: /* @__PURE__ */ jsx("td", {
88
+ style: { height: virtualizer.getTotalSize() - last.end, padding: 0, border: 0 }
89
+ })
90
+ })
91
+ ]
92
+ })
93
+ ]
94
+ })
95
+ });
96
+ }
97
+
98
+ export { VirtualTable2 };
@@ -21,7 +21,7 @@ import {
21
21
  TableHead2,
22
22
  TableCell2,
23
23
  TableCaption2
24
- } from "./chunk-v0k5jnk5.js";
24
+ } from "./chunk-zte6pw69.js";
25
25
  import {
26
26
  safeHref
27
27
  } from "./chunk-xhtsnwnb.js";
@@ -5,9 +5,11 @@ import {
5
5
  Button2
6
6
  } from "./chunk-q7p28b89.js";
7
7
  import {
8
- Checkbox2,
9
8
  Spinner2
10
- } from "./chunk-eehfrrdz.js";
9
+ } from "./chunk-1xncv9gb.js";
10
+ import {
11
+ Checkbox2
12
+ } from "./chunk-tnnf8ydf.js";
11
13
  import {
12
14
  useReceiptFocus
13
15
  } from "./chunk-vxvaaptq.js";
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-vxvaaptq.js";
7
7
  import {
8
8
  OptionList2
9
- } from "./chunk-g238nezp.js";
9
+ } from "./chunk-pg9rhbgm.js";
10
10
 
11
11
  // src/components/assistant-ui/elements/QuestionFlow.tsx
12
12
  import { useCallback, useId, useLayoutEffect, useRef, useState } from "react";
@@ -20,18 +20,4 @@ function Checkbox2({ density, className, ...props }) {
20
20
  });
21
21
  }
22
22
 
23
- // src/components/Spinner.tsx
24
- import { Loader2Icon } from "lucide-react";
25
- import { jsx as jsx2 } from "react/jsx-runtime";
26
- function Spinner2({ density, className, ...props }) {
27
- return /* @__PURE__ */ jsx2(Loader2Icon, {
28
- "data-density": density,
29
- "data-slot": "spinner",
30
- role: "status",
31
- "aria-label": "Loading",
32
- className: cn2("size-4 animate-spin", className),
33
- ...props
34
- });
35
- }
36
-
37
- export { Checkbox2, Spinner2 };
23
+ export { Checkbox2 };
@@ -0,0 +1,363 @@
1
+ import {
2
+ Button2
3
+ } from "./chunk-q7p28b89.js";
4
+ import {
5
+ Table2,
6
+ TableHeader2,
7
+ TableBody2,
8
+ TableRow2,
9
+ TableHead2,
10
+ TableCell2,
11
+ TableColumnGroup2,
12
+ TableColumn2
13
+ } from "./chunk-zte6pw69.js";
14
+ import {
15
+ NativeSelect2,
16
+ NativeSelectOption2
17
+ } from "./chunk-r9qrb6b6.js";
18
+ import {
19
+ Input2
20
+ } from "./chunk-59p19t57.js";
21
+
22
+ // src/components/data-grid/DataGrid.tsx
23
+ import {
24
+ FlexRender,
25
+ columnFilteringFeature,
26
+ columnOrderingFeature,
27
+ columnResizingFeature,
28
+ columnSizingFeature,
29
+ columnVisibilityFeature,
30
+ createFilteredRowModel,
31
+ createPaginatedRowModel,
32
+ createSortedRowModel,
33
+ filterFn_includesString,
34
+ globalFilteringFeature,
35
+ rowPaginationFeature,
36
+ rowSelectionFeature,
37
+ rowSortingFeature,
38
+ sortFn_alphanumeric,
39
+ sortFn_basic,
40
+ tableFeatures
41
+ } from "@tanstack/react-table";
42
+ import { ArrowDownIcon, ArrowUpIcon, ChevronsUpDownIcon } from "lucide-react";
43
+ import { useId } from "react";
44
+
45
+ // src/components/data-grid/DataGridColumnResizer.tsx
46
+ import { Subscribe } from "@tanstack/react-table";
47
+ import { jsx } from "react/jsx-runtime";
48
+ var KEYBOARD_STEP = 16;
49
+ function DataGridColumnResizer({
50
+ header,
51
+ label
52
+ }) {
53
+ const column = header.column;
54
+ const table = column.table;
55
+ const minSize = column.columnDef.minSize ?? 0;
56
+ const maxSize = column.columnDef.maxSize ?? Number.MAX_SAFE_INTEGER;
57
+ const resize = header.getResizeHandler();
58
+ const setSize = (size) => table.setColumnSizing((sizes) => ({ ...sizes, [column.id]: Math.min(maxSize, Math.max(minSize, size)) }));
59
+ const onKeyDown = (event) => {
60
+ const growKey = table.options.columnResizeDirection === "rtl" ? "ArrowLeft" : "ArrowRight";
61
+ const shrinkKey = growKey === "ArrowRight" ? "ArrowLeft" : "ArrowRight";
62
+ const size = column.getSize();
63
+ const next = event.key === growKey ? size + KEYBOARD_STEP : event.key === shrinkKey ? size - KEYBOARD_STEP : event.key === "Home" ? minSize : event.key === "End" && maxSize < Number.MAX_SAFE_INTEGER ? maxSize : undefined;
64
+ if (next === undefined)
65
+ return;
66
+ event.preventDefault();
67
+ setSize(next);
68
+ };
69
+ return /* @__PURE__ */ jsx(Subscribe, {
70
+ source: table.store,
71
+ selector: (state) => `${state.columnSizing[column.id]}:${state.columnResizing.isResizingColumn === column.id}`,
72
+ children: () => /* @__PURE__ */ jsx("div", {
73
+ role: "separator",
74
+ "aria-orientation": "vertical",
75
+ "aria-label": `Resize ${label}`,
76
+ "aria-valuenow": column.getSize(),
77
+ "aria-valuemin": minSize,
78
+ "aria-valuemax": maxSize < Number.MAX_SAFE_INTEGER ? maxSize : undefined,
79
+ tabIndex: 0,
80
+ "data-slot": "data-grid-column-resizer",
81
+ "data-resizing": column.getIsResizing() || undefined,
82
+ onMouseDown: resize,
83
+ onTouchStart: resize,
84
+ onDoubleClick: () => column.resetSize(),
85
+ onKeyDown,
86
+ className: "absolute inset-y-0 end-0 flex w-2 cursor-col-resize touch-none justify-center outline-none select-none after:w-px after:bg-border hover:after:bg-ring focus-visible:after:w-0.5 focus-visible:after:bg-ring data-resizing:after:bg-ring"
87
+ })
88
+ });
89
+ }
90
+
91
+ // src/components/data-grid/getDataGridColumnSizeVariables.ts
92
+ function getDataGridColumnSizeVariables(table) {
93
+ return new Map(table.getAllColumns().flatMap((column) => column.getLeafColumns()).map((column, index) => [column.id, `--data-grid-column-${index}-size`]));
94
+ }
95
+
96
+ // src/components/data-grid/DataGrid.tsx
97
+ import { jsx as jsx2, jsxs, Fragment } from "react/jsx-runtime";
98
+ var columnMeta = {};
99
+ var dataGridFeatures2 = tableFeatures({
100
+ columnFilteringFeature,
101
+ columnOrderingFeature,
102
+ columnSizingFeature,
103
+ columnResizingFeature,
104
+ columnVisibilityFeature,
105
+ globalFilteringFeature,
106
+ rowPaginationFeature,
107
+ rowSelectionFeature,
108
+ rowSortingFeature,
109
+ filteredRowModel: createFilteredRowModel(),
110
+ sortedRowModel: createSortedRowModel(),
111
+ paginatedRowModel: createPaginatedRowModel(),
112
+ filterFns: { includesString: filterFn_includesString },
113
+ sortFns: { alphanumeric: sortFn_alphanumeric, basic: sortFn_basic },
114
+ columnMeta
115
+ });
116
+ function getDataGridColumnLabel(column) {
117
+ const header = column.columnDef.header;
118
+ return column.columnDef.meta?.label ?? (typeof header === "string" ? header : column.id);
119
+ }
120
+ function getAriaSort(column) {
121
+ if (!column.getCanSort())
122
+ return;
123
+ const sorted = column.getIsSorted();
124
+ return sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : "none";
125
+ }
126
+ function DataGridHeaderCell({ header, isResizable }) {
127
+ const contentId = useId();
128
+ const meta = header.column.columnDef.meta;
129
+ const hasResizer = isResizable && !meta?.fill && header.column.getCanResize();
130
+ return /* @__PURE__ */ jsx2(TableHead2, {
131
+ scope: "col",
132
+ colSpan: header.colSpan,
133
+ "aria-sort": getAriaSort(header.column),
134
+ "aria-labelledby": hasResizer ? contentId : undefined,
135
+ textAlign: meta?.textAlign,
136
+ truncate: meta?.truncate,
137
+ visibleFrom: meta?.visibleFrom,
138
+ className: hasResizer ? "relative" : undefined,
139
+ children: hasResizer ? /* @__PURE__ */ jsxs(Fragment, {
140
+ children: [
141
+ /* @__PURE__ */ jsx2("span", {
142
+ id: contentId,
143
+ children: header.isPlaceholder ? null : /* @__PURE__ */ jsx2(FlexRender, {
144
+ header
145
+ })
146
+ }),
147
+ /* @__PURE__ */ jsx2(DataGridColumnResizer, {
148
+ header,
149
+ label: getDataGridColumnLabel(header.column)
150
+ })
151
+ ]
152
+ }) : header.isPlaceholder ? null : /* @__PURE__ */ jsx2(FlexRender, {
153
+ header
154
+ })
155
+ });
156
+ }
157
+ function DataGridHeaderRows({
158
+ table,
159
+ isResizable = false
160
+ }) {
161
+ return /* @__PURE__ */ jsx2(Fragment, {
162
+ children: table.getHeaderGroups().map((group) => /* @__PURE__ */ jsx2(TableRow2, {
163
+ children: group.headers.map((header) => /* @__PURE__ */ jsx2(DataGridHeaderCell, {
164
+ header,
165
+ isResizable
166
+ }, header.id))
167
+ }, group.id))
168
+ });
169
+ }
170
+ function DataGridCells2({ row }) {
171
+ return /* @__PURE__ */ jsx2(Fragment, {
172
+ children: row.getVisibleCells().map((cell) => {
173
+ const meta = cell.column.columnDef.meta;
174
+ return /* @__PURE__ */ jsx2(TableCell2, {
175
+ textAlign: meta?.textAlign,
176
+ truncate: meta?.truncate,
177
+ visibleFrom: meta?.visibleFrom,
178
+ children: /* @__PURE__ */ jsx2(FlexRender, {
179
+ cell
180
+ })
181
+ }, cell.id);
182
+ })
183
+ });
184
+ }
185
+ function DataGridColumns({ table }) {
186
+ const variables = getDataGridColumnSizeVariables(table);
187
+ return /* @__PURE__ */ jsx2(TableColumnGroup2, {
188
+ children: table.getVisibleLeafColumns().map((column) => {
189
+ const meta = column.columnDef.meta;
190
+ const variable = variables.get(column.id);
191
+ return /* @__PURE__ */ jsx2(TableColumn2, {
192
+ visibleFrom: meta?.visibleFrom,
193
+ width: meta?.fill ? undefined : `var(${variable}, ${column.getSize()}px)`
194
+ }, column.id);
195
+ })
196
+ });
197
+ }
198
+ function DataGrid2({
199
+ table,
200
+ label,
201
+ toolbar,
202
+ empty = "No results.",
203
+ loading = false,
204
+ pagination = true,
205
+ density
206
+ }) {
207
+ const rows = table.getRowModel().rows;
208
+ return /* @__PURE__ */ jsxs("div", {
209
+ "data-density": density,
210
+ "data-scroll": "none",
211
+ className: "grid min-w-0 gap-3",
212
+ "aria-busy": loading,
213
+ children: [
214
+ toolbar,
215
+ /* @__PURE__ */ jsx2("div", {
216
+ className: "min-w-0 rounded-sm border border-border",
217
+ children: /* @__PURE__ */ jsxs(Table2, {
218
+ "aria-label": label,
219
+ children: [
220
+ /* @__PURE__ */ jsx2(TableHeader2, {
221
+ children: /* @__PURE__ */ jsx2(DataGridHeaderRows, {
222
+ table
223
+ })
224
+ }),
225
+ /* @__PURE__ */ jsx2(TableBody2, {
226
+ children: loading ? /* @__PURE__ */ jsx2(TableRow2, {
227
+ children: /* @__PURE__ */ jsx2(TableCell2, {
228
+ colSpan: table.getVisibleLeafColumns().length,
229
+ children: /* @__PURE__ */ jsxs("p", {
230
+ role: "status",
231
+ children: [
232
+ "Loading ",
233
+ label,
234
+ "…"
235
+ ]
236
+ })
237
+ })
238
+ }) : rows.length ? rows.map((row) => /* @__PURE__ */ jsx2(TableRow2, {
239
+ "data-state": row.getIsSelected() ? "selected" : undefined,
240
+ children: /* @__PURE__ */ jsx2(DataGridCells2, {
241
+ row
242
+ })
243
+ }, row.id)) : /* @__PURE__ */ jsx2(TableRow2, {
244
+ children: /* @__PURE__ */ jsx2(TableCell2, {
245
+ colSpan: table.getVisibleLeafColumns().length,
246
+ children: /* @__PURE__ */ jsx2("p", {
247
+ role: "status",
248
+ children: empty
249
+ })
250
+ })
251
+ })
252
+ })
253
+ ]
254
+ })
255
+ }),
256
+ pagination && /* @__PURE__ */ jsx2(DataGridPagination2, {
257
+ table
258
+ })
259
+ ]
260
+ });
261
+ }
262
+ function DataGridColumnHeader2({
263
+ column,
264
+ children
265
+ }) {
266
+ const sorted = column.getIsSorted();
267
+ return column.getCanSort() ? /* @__PURE__ */ jsxs(Button2, {
268
+ type: "button",
269
+ variant: "ghost",
270
+ size: "sm",
271
+ onClick: column.getToggleSortingHandler(),
272
+ children: [
273
+ children,
274
+ sorted === "asc" ? /* @__PURE__ */ jsx2(ArrowUpIcon, {
275
+ "aria-hidden": "true"
276
+ }) : sorted === "desc" ? /* @__PURE__ */ jsx2(ArrowDownIcon, {
277
+ "aria-hidden": "true"
278
+ }) : /* @__PURE__ */ jsx2(ChevronsUpDownIcon, {
279
+ "aria-hidden": "true"
280
+ })
281
+ ]
282
+ }) : /* @__PURE__ */ jsx2("span", {
283
+ children
284
+ });
285
+ }
286
+ function DataGridFilter2({
287
+ table,
288
+ columnId,
289
+ label
290
+ }) {
291
+ const column = table.getColumn(columnId);
292
+ if (!column)
293
+ throw new Error(`Unknown filter column: ${columnId}`);
294
+ const value = column.getFilterValue();
295
+ return /* @__PURE__ */ jsx2(Input2, {
296
+ "aria-label": label,
297
+ placeholder: label,
298
+ value: typeof value === "string" ? value : "",
299
+ onChange: (event) => column.setFilterValue(event.target.value)
300
+ });
301
+ }
302
+ function DataGridPagination2({ table }) {
303
+ return /* @__PURE__ */ jsxs("div", {
304
+ className: "flex flex-wrap items-center justify-between gap-3 text-sm",
305
+ children: [
306
+ /* @__PURE__ */ jsxs("span", {
307
+ role: "status",
308
+ children: [
309
+ table.getSelectedRowModel().rows.length,
310
+ " selected · Page ",
311
+ table.state.pagination.pageIndex + 1,
312
+ " of",
313
+ " ",
314
+ Math.max(1, table.getPageCount())
315
+ ]
316
+ }),
317
+ /* @__PURE__ */ jsxs("div", {
318
+ className: "flex items-center gap-2",
319
+ children: [
320
+ /* @__PURE__ */ jsxs(NativeSelect2, {
321
+ "aria-label": "Rows per page",
322
+ value: table.state.pagination.pageSize,
323
+ onChange: (event) => table.setPageSize(Number(event.target.value)),
324
+ children: [
325
+ [10, 20, 50, 100].map((size) => /* @__PURE__ */ jsxs(NativeSelectOption2, {
326
+ value: size,
327
+ children: [
328
+ size,
329
+ " rows"
330
+ ]
331
+ }, size)),
332
+ ![10, 20, 50, 100].includes(table.state.pagination.pageSize) && /* @__PURE__ */ jsxs(NativeSelectOption2, {
333
+ value: table.state.pagination.pageSize,
334
+ children: [
335
+ table.state.pagination.pageSize,
336
+ " rows"
337
+ ]
338
+ })
339
+ ]
340
+ }),
341
+ /* @__PURE__ */ jsx2(Button2, {
342
+ type: "button",
343
+ variant: "outline",
344
+ size: "sm",
345
+ disabled: !table.getCanPreviousPage(),
346
+ onClick: () => table.previousPage(),
347
+ children: "Previous"
348
+ }),
349
+ /* @__PURE__ */ jsx2(Button2, {
350
+ type: "button",
351
+ variant: "outline",
352
+ size: "sm",
353
+ disabled: !table.getCanNextPage(),
354
+ onClick: () => table.nextPage(),
355
+ children: "Next"
356
+ })
357
+ ]
358
+ })
359
+ ]
360
+ });
361
+ }
362
+
363
+ export { getDataGridColumnSizeVariables, dataGridFeatures2, getDataGridColumnLabel, DataGridHeaderRows, DataGridCells2, DataGridColumns, DataGrid2, DataGridColumnHeader2, DataGridFilter2, DataGridPagination2 };
@@ -103,10 +103,11 @@ function TableColumnGroup2(props) {
103
103
  ...props
104
104
  });
105
105
  }
106
- function TableColumn2({ className, visibleFrom, ...props }) {
106
+ function TableColumn2({ className, style, visibleFrom, width, ...props }) {
107
107
  return /* @__PURE__ */ jsx("col", {
108
108
  "data-slot": "table-column",
109
109
  className: cn2(visibleFrom && columnVisibilityClasses[visibleFrom], className),
110
+ style: width === undefined ? style : { ...style, width },
110
111
  ...props
111
112
  });
112
113
  }
@@ -25,9 +25,13 @@ type TableCellProps = ComponentProps<"td"> & IDensityProps & ITableCellOptions;
25
25
  declare function TableCell({ density, className, truncate, textAlign, visibleFrom, ...props }: TableCellProps): ReactElement;
26
26
  type TableColumnGroupProps = ComponentProps<"colgroup">;
27
27
  declare function TableColumnGroup(props: TableColumnGroupProps): ReactElement;
28
- type TableColumnProps = ComponentProps<"col"> & Pick<ITableCellOptions, "visibleFrom">;
29
- /** A sized column; give it the same `visibleFrom` as its header and cells. */
30
- declare function TableColumn({ className, visibleFrom, ...props }: TableColumnProps): ReactElement;
28
+ type TableColumnProps = ComponentProps<"col"> & Pick<ITableCellOptions, "visibleFrom"> & {
29
+ /** Fixed column width; numbers are pixels. Columns without one share the remaining width. */
30
+ width?: number | string;
31
+ };
32
+ /** A column; give it the same `visibleFrom` as its header and cells. */
33
+ declare function TableColumn({ className, style, visibleFrom, width, ...props }: TableColumnProps): ReactElement;
31
34
  type TableCaptionProps = ComponentProps<"caption"> & IDensityProps;
32
35
  declare function TableCaption({ density, className, ...props }: TableCaptionProps): ReactElement;
33
36
  export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, TableColumnGroup, TableColumn, };
37
+ export type { TableTextAlign, TableVisibility };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  DataTable2
3
- } from "../../../chunk-3z5gpbh0.js";
3
+ } from "../../../chunk-987zth0a.js";
4
4
  import"../../../chunk-1wz92wgg.js";
5
- import"../../../chunk-v0k5jnk5.js";
5
+ import"../../../chunk-zte6pw69.js";
6
6
  import"../../../chunk-bygq5yqf.js";
7
7
  import"../../../chunk-wjx6zf94.js";
8
8
  import"../../../chunk-q7p28b89.js";