@alexgorbatchev/shadcn 0.0.36 → 0.0.37
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/README.md +1 -1
- package/dist/components/data-grid/DataGrid.d.ts +10 -2
- package/dist/components/data-grid/DataGridFilterSummary.d.ts +4 -3
- package/dist/components/data-grid/DataGridFilters.d.ts +4 -3
- package/dist/components/data-grid/describeDataGridFilter.d.ts +5 -4
- package/dist/components/data-grid/getDataGridFilterOptions.d.ts +6 -0
- package/dist/components/data-grid/index.d.ts +1 -1
- package/dist/components/data-grid/index.js +24 -13
- package/llms/components/data-display/DataGridFilters.md +13 -0
- package/llms/setup.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -306,7 +306,7 @@ Compose `QuestionnaireItem`, `QuestionnaireTitle`, and answer controls inside `Q
|
|
|
306
306
|
|
|
307
307
|
`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`, `fill`, and `sortColumnIds`; a `fill` column takes the width the sized columns leave, and `sortColumnIds` names other columns the header sorts with its own buttons so its `aria-sort` reports them. Other resizable columns get a window-splitter handle that resizes by dragging, by the arrow keys, Home, and End, and resets on double-click. Set `columnResizeMode: "onChange"` so columns follow the pointer while dragging; TanStack's default `"onEnd"` resizes only on release. 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.
|
|
308
308
|
|
|
309
|
-
Column `meta.filter` offers a column in `DataGridFilters`, hidden columns included. A `range` filter edits `[min, max]` bounds, `null` for an open end, for `filterFn: "inNumberRange"`; its inputs suggest the range of the rows the other filters leave, formatted through the filter's `Intl.NumberFormatOptions`. An `options` filter chooses among labelled string values, one or several, for `filterFn: "arrHas"` (one value per row), `"arrIncludesSome"` (an array per row), or a custom `filterFn`; each option counts the rows the other filters leave with that value, so a column whose rows hold several values or values in another form supplies them through `getUniqueValues`. Column filters combine with each other and with the global filter. `DataGridFilterSummary` lists the active filters with buttons that remove them, and both controls clear every column filter at once.
|
|
309
|
+
Column `meta.filter` offers a column in `DataGridFilters`, hidden columns included. A `range` filter edits `[min, max]` bounds, `null` for an open end, for `filterFn: "inNumberRange"`; its inputs suggest the range of the rows the other filters leave, formatted through the filter's `Intl.NumberFormatOptions`. An `options` filter chooses among labelled string values, one or several, listed in its `options` or, when they depend on runtime data, in the `options` prop of `DataGridFilters` and `DataGridFilterSummary` keyed by column ID, for `filterFn: "arrHas"` (one value per row), `"arrIncludesSome"` (an array per row), or a custom `filterFn`; each option counts the rows the other filters leave with that value, so a column whose rows hold several values or values in another form supplies them through `getUniqueValues`. Column filters combine with each other and with the global filter. `DataGridFilterSummary` lists the active filters with buttons that remove them, and both controls clear every column filter at once.
|
|
310
310
|
|
|
311
311
|
`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.
|
|
312
312
|
|
|
@@ -25,7 +25,8 @@ interface IDataGridOptionsFilter {
|
|
|
25
25
|
variant: "options";
|
|
26
26
|
/** Names the filter; defaults to the column label. */
|
|
27
27
|
label?: string;
|
|
28
|
-
options
|
|
28
|
+
/** Choices known where the column is defined; the filter controls' `options` prop supplies choices known later. */
|
|
29
|
+
options?: readonly ILabelValue[];
|
|
29
30
|
/** Allows choosing several options; a single choice still writes a one-value array. Defaults to true. */
|
|
30
31
|
multiple?: boolean;
|
|
31
32
|
}
|
|
@@ -87,6 +88,13 @@ interface IDataGridControlProps<T extends RowData> {
|
|
|
87
88
|
/** Names the control; each control documents its default. */
|
|
88
89
|
label?: string;
|
|
89
90
|
}
|
|
91
|
+
/** Options-filter choices by column ID, for choices that depend on data the column definitions cannot hold. */
|
|
92
|
+
type DataGridFilterOptions = Readonly<Record<string, readonly ILabelValue[]>>;
|
|
93
|
+
/** Props of a control that edits or describes column filters. */
|
|
94
|
+
interface IDataGridFilterControlProps<T extends RowData> extends IDataGridControlProps<T> {
|
|
95
|
+
/** Replaces the choices of the options filters it names; other filters keep their column's `meta.filter.options`. */
|
|
96
|
+
options?: DataGridFilterOptions;
|
|
97
|
+
}
|
|
90
98
|
type DataGridRow<T extends RowData> = Row<DataGridFeatures, T>;
|
|
91
99
|
type DataGridColumn<T extends RowData> = Column<DataGridFeatures, T, CellData>;
|
|
92
100
|
declare function getDataGridColumnLabel<T extends RowData>(column: DataGridColumn<T>): string;
|
|
@@ -129,4 +137,4 @@ declare function DataGridPagination<T extends RowData>({ table }: {
|
|
|
129
137
|
table: DataGridTable<T>;
|
|
130
138
|
}): ReactElement;
|
|
131
139
|
export { DataGrid, DataGridCells, DataGridColumnHeader, DataGridColumns, DataGridFilter, DataGridHeaderRows, DataGridPagination, dataGridFeatures, getDataGridColumnLabel, };
|
|
132
|
-
export type { DataGridColumn, DataGridColumnFilter, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, IDataGridControlProps, IDataGridOptionsFilter, IDataGridRangeFilter, };
|
|
140
|
+
export type { DataGridColumn, DataGridColumnFilter, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, IDataGridControlProps, DataGridFilterOptions, IDataGridFilterControlProps, IDataGridOptionsFilter, IDataGridRangeFilter, };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type RowData } from "@tanstack/react-table";
|
|
2
2
|
import type { ReactElement } from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { IDataGridFilterControlProps } from "./DataGrid.js";
|
|
4
4
|
/**
|
|
5
5
|
* Lists the active filters of columns whose `meta.filter` describes one, each with a button that removes it, followed by
|
|
6
|
-
* Clear filters. Renders nothing while no such filter is active. `label` names the list
|
|
6
|
+
* Clear filters. Renders nothing while no such filter is active. `label` names the list; `options` supplies the
|
|
7
|
+
* options-filter choices given to `DataGridFilters`, so the summary names them the same way.
|
|
7
8
|
*/
|
|
8
|
-
export declare function DataGridFilterSummary<T extends RowData>({ table, label, }:
|
|
9
|
+
export declare function DataGridFilterSummary<T extends RowData>({ table, label, options, }: IDataGridFilterControlProps<T>): ReactElement;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type RowData } from "@tanstack/react-table";
|
|
2
2
|
import { type ReactElement } from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { IDataGridFilterControlProps } from "./DataGrid.js";
|
|
4
4
|
/**
|
|
5
5
|
* Edits the filters of every column whose `meta.filter` describes one, hidden columns included. Filters combine with
|
|
6
6
|
* each other and with the global filter; each control suggests only values the other filters leave. The trigger counts
|
|
7
|
-
* the active column filters, and Clear filters removes them all. `label` titles the trigger and popover
|
|
7
|
+
* the active column filters, and Clear filters removes them all. `label` titles the trigger and popover; `options`
|
|
8
|
+
* supplies options-filter choices that depend on runtime data.
|
|
8
9
|
*/
|
|
9
|
-
export declare function DataGridFilters<T extends RowData>({ table, label, }:
|
|
10
|
+
export declare function DataGridFilters<T extends RowData>({ table, label, options, }: IDataGridFilterControlProps<T>): ReactElement;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { ILabelValue } from "../../options/types.js";
|
|
1
2
|
import type { DataGridColumnFilter } from "./DataGrid.js";
|
|
2
3
|
/**
|
|
3
|
-
* Describes a filter value in a few words: `120–128`, `≥ 120`, or `≤ 128` for a range, and the
|
|
4
|
-
* options. Values without a matching option read as themselves. Returns an empty string for a
|
|
5
|
-
* nothing.
|
|
4
|
+
* Describes a filter value in a few words: `120–128`, `≥ 120`, or `≤ 128` for a range, and the labels of the chosen
|
|
5
|
+
* `options` for an options filter. Values without a matching option read as themselves. Returns an empty string for a
|
|
6
|
+
* value that filters nothing.
|
|
6
7
|
*/
|
|
7
|
-
declare function describeDataGridFilter(filter: DataGridColumnFilter, value: unknown,
|
|
8
|
+
declare function describeDataGridFilter(filter: DataGridColumnFilter, value: unknown, options: readonly ILabelValue[]): string;
|
|
8
9
|
export { describeDataGridFilter };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RowData } from "@tanstack/react-table";
|
|
2
|
+
import type { ILabelValue } from "../../options/types.js";
|
|
3
|
+
import type { DataGridColumn, DataGridFilterOptions } from "./DataGrid.js";
|
|
4
|
+
/** A column's options-filter choices: those the controls were given for it, else its own. */
|
|
5
|
+
declare function getDataGridFilterOptions<T extends RowData>(column: DataGridColumn<T>, options: DataGridFilterOptions | undefined): readonly ILabelValue[];
|
|
6
|
+
export { getDataGridFilterOptions };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { DataGrid, DataGridCells, DataGridColumnHeader, DataGridFilter, DataGridPagination, dataGridFeatures, } from "./DataGrid.js";
|
|
2
|
-
export type { DataGridColumn, DataGridColumnFilter, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, IDataGridControlProps, IDataGridOptionsFilter, IDataGridRangeFilter, } from "./DataGrid.js";
|
|
2
|
+
export type { DataGridColumn, DataGridColumnFilter, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, IDataGridControlProps, DataGridFilterOptions, IDataGridFilterControlProps, IDataGridOptionsFilter, IDataGridRangeFilter, } from "./DataGrid.js";
|
|
3
3
|
export { DataGridColumnOptions } from "./DataGridColumnOptions.js";
|
|
4
4
|
export { DataGridFilters } from "./DataGridFilters.js";
|
|
5
5
|
export { DataGridFilterSummary } from "./DataGridFilterSummary.js";
|
|
@@ -174,6 +174,13 @@ function getDataGridFilterLabel(column) {
|
|
|
174
174
|
return column.columnDef.meta?.filter?.label ?? getDataGridColumnLabel(column);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
// src/components/data-grid/getDataGridFilterOptions.ts
|
|
178
|
+
var NO_OPTIONS = [];
|
|
179
|
+
function getDataGridFilterOptions(column, options) {
|
|
180
|
+
const filter = column.columnDef.meta?.filter;
|
|
181
|
+
return options?.[column.id] ?? (filter?.variant === "options" ? filter.options : undefined) ?? NO_OPTIONS;
|
|
182
|
+
}
|
|
183
|
+
|
|
177
184
|
// src/components/data-grid/readDataGridOptionValues.ts
|
|
178
185
|
var NO_VALUES = [];
|
|
179
186
|
function readDataGridOptionValues(value) {
|
|
@@ -250,12 +257,13 @@ function DataGridRangeFilterControl({
|
|
|
250
257
|
function DataGridOptionsFilterControl({
|
|
251
258
|
column,
|
|
252
259
|
filter,
|
|
260
|
+
options,
|
|
253
261
|
label
|
|
254
262
|
}) {
|
|
255
263
|
const labelId = useId();
|
|
256
264
|
const anchor = useComboboxAnchor2();
|
|
257
265
|
const counts = column.getFacetedUniqueValues();
|
|
258
|
-
const selected = readDataGridOptionValues(column.getFilterValue()).map((value) =>
|
|
266
|
+
const selected = readDataGridOptionValues(column.getFilterValue()).map((value) => options.find((option) => option.value === value) ?? { label: value, value });
|
|
259
267
|
const update = (next) => column.setFilterValue(next.length ? next.map((option) => option.value) : undefined);
|
|
260
268
|
const content = /* @__PURE__ */ jsxs2(Fragment, {
|
|
261
269
|
children: [
|
|
@@ -289,7 +297,7 @@ function DataGridOptionsFilterControl({
|
|
|
289
297
|
children: label
|
|
290
298
|
}),
|
|
291
299
|
filter.multiple === false ? /* @__PURE__ */ jsxs2(Combobox2, {
|
|
292
|
-
items:
|
|
300
|
+
items: options,
|
|
293
301
|
value: selected[0] ?? null,
|
|
294
302
|
onValueChange: (option) => update(option ? [option] : []),
|
|
295
303
|
itemToStringLabel: (option) => option.label,
|
|
@@ -306,25 +314,25 @@ function DataGridOptionsFilterControl({
|
|
|
306
314
|
})
|
|
307
315
|
]
|
|
308
316
|
}) : /* @__PURE__ */ jsxs2(Combobox2, {
|
|
309
|
-
items:
|
|
317
|
+
items: options,
|
|
310
318
|
multiple: true,
|
|
311
319
|
value: selected,
|
|
312
|
-
onValueChange: (
|
|
320
|
+
onValueChange: (chosen) => update(chosen),
|
|
313
321
|
itemToStringLabel: (option) => option.label,
|
|
314
322
|
isItemEqualToValue: (option, value) => option.value === value.value,
|
|
315
323
|
children: [
|
|
316
324
|
/* @__PURE__ */ jsx2(ComboboxChips2, {
|
|
317
325
|
ref: anchor,
|
|
318
326
|
children: /* @__PURE__ */ jsx2(ComboboxValue2, {
|
|
319
|
-
children: (
|
|
327
|
+
children: (chosen) => /* @__PURE__ */ jsxs2(Fragment, {
|
|
320
328
|
children: [
|
|
321
|
-
|
|
329
|
+
chosen.map((option) => /* @__PURE__ */ jsx2(ComboboxChip2, {
|
|
322
330
|
removeLabel: `Remove ${option.label}`,
|
|
323
331
|
children: option.label
|
|
324
332
|
}, option.value)),
|
|
325
333
|
/* @__PURE__ */ jsx2(ComboboxChipsInput2, {
|
|
326
334
|
"aria-labelledby": labelId,
|
|
327
|
-
placeholder:
|
|
335
|
+
placeholder: chosen.length ? undefined : "Any"
|
|
328
336
|
})
|
|
329
337
|
]
|
|
330
338
|
})
|
|
@@ -341,7 +349,8 @@ function DataGridOptionsFilterControl({
|
|
|
341
349
|
}
|
|
342
350
|
function DataGridFilters({
|
|
343
351
|
table,
|
|
344
|
-
label = "Filters"
|
|
352
|
+
label = "Filters",
|
|
353
|
+
options
|
|
345
354
|
}) {
|
|
346
355
|
return /* @__PURE__ */ jsxs2(Popover2, {
|
|
347
356
|
children: [
|
|
@@ -399,6 +408,7 @@ function DataGridFilters({
|
|
|
399
408
|
}, column.id) : /* @__PURE__ */ jsx2(DataGridOptionsFilterControl, {
|
|
400
409
|
column,
|
|
401
410
|
filter,
|
|
411
|
+
options: getDataGridFilterOptions(column, options),
|
|
402
412
|
label: name
|
|
403
413
|
}, column.id);
|
|
404
414
|
})
|
|
@@ -424,11 +434,11 @@ import { Subscribe as Subscribe3 } from "@tanstack/react-table";
|
|
|
424
434
|
import { XIcon } from "lucide-react";
|
|
425
435
|
|
|
426
436
|
// src/components/data-grid/describeDataGridFilter.ts
|
|
427
|
-
function describeDataGridFilter(filter, value,
|
|
437
|
+
function describeDataGridFilter(filter, value, options) {
|
|
428
438
|
if (filter.variant === "options") {
|
|
429
|
-
return readDataGridOptionValues(value).map((item) =>
|
|
439
|
+
return readDataGridOptionValues(value).map((item) => options.find((option) => option.value === item)?.label ?? item).join(", ");
|
|
430
440
|
}
|
|
431
|
-
const formatter = new Intl.NumberFormat(
|
|
441
|
+
const formatter = new Intl.NumberFormat(undefined, filter.format);
|
|
432
442
|
const [min, max] = readDataGridRange(value);
|
|
433
443
|
if (min !== null && max !== null)
|
|
434
444
|
return `${formatter.format(Math.min(min, max))}–${formatter.format(Math.max(min, max))}`;
|
|
@@ -443,14 +453,15 @@ function describeDataGridFilter(filter, value, locale) {
|
|
|
443
453
|
import { jsx as jsx3, jsxs as jsxs3, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
444
454
|
function DataGridFilterSummary({
|
|
445
455
|
table,
|
|
446
|
-
label = "Active filters"
|
|
456
|
+
label = "Active filters",
|
|
457
|
+
options
|
|
447
458
|
}) {
|
|
448
459
|
return /* @__PURE__ */ jsx3(Subscribe3, {
|
|
449
460
|
source: table.atoms.columnFilters,
|
|
450
461
|
children: () => {
|
|
451
462
|
const active = table.getAllLeafColumns().flatMap((column) => {
|
|
452
463
|
const filter = column.columnDef.meta?.filter;
|
|
453
|
-
const description = filter ? describeDataGridFilter(filter, column.getFilterValue()) : "";
|
|
464
|
+
const description = filter ? describeDataGridFilter(filter, column.getFilterValue(), getDataGridFilterOptions(column, options)) : "";
|
|
454
465
|
return description ? [{ column, description, name: getDataGridFilterLabel(column) }] : [];
|
|
455
466
|
});
|
|
456
467
|
return /* @__PURE__ */ jsx3(Fragment2, {
|
|
@@ -36,3 +36,16 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
|
|
|
36
36
|
render: () => (<FilteredDataGridExample recordings={fixture_gridRecordings} initialFilters={[{ id: "genre", value: ["Polka"] }]}/>)
|
|
37
37
|
}
|
|
38
38
|
```
|
|
39
|
+
|
|
40
|
+
### RuntimeOptions
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
{
|
|
44
|
+
render: () => (<FilteredDataGridExample recordings={fixture_gridRecordings} options={{
|
|
45
|
+
genre: [
|
|
46
|
+
{ label: "Deep house", value: "House" },
|
|
47
|
+
{ label: "Peak-time techno", value: "Techno" },
|
|
48
|
+
],
|
|
49
|
+
}}/>)
|
|
50
|
+
}
|
|
51
|
+
```
|
package/llms/setup.md
CHANGED
|
@@ -306,7 +306,7 @@ Compose `QuestionnaireItem`, `QuestionnaireTitle`, and answer controls inside `Q
|
|
|
306
306
|
|
|
307
307
|
`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`, `fill`, and `sortColumnIds`; a `fill` column takes the width the sized columns leave, and `sortColumnIds` names other columns the header sorts with its own buttons so its `aria-sort` reports them. Other resizable columns get a window-splitter handle that resizes by dragging, by the arrow keys, Home, and End, and resets on double-click. Set `columnResizeMode: "onChange"` so columns follow the pointer while dragging; TanStack's default `"onEnd"` resizes only on release. 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.
|
|
308
308
|
|
|
309
|
-
Column `meta.filter` offers a column in `DataGridFilters`, hidden columns included. A `range` filter edits `[min, max]` bounds, `null` for an open end, for `filterFn: "inNumberRange"`; its inputs suggest the range of the rows the other filters leave, formatted through the filter's `Intl.NumberFormatOptions`. An `options` filter chooses among labelled string values, one or several, for `filterFn: "arrHas"` (one value per row), `"arrIncludesSome"` (an array per row), or a custom `filterFn`; each option counts the rows the other filters leave with that value, so a column whose rows hold several values or values in another form supplies them through `getUniqueValues`. Column filters combine with each other and with the global filter. `DataGridFilterSummary` lists the active filters with buttons that remove them, and both controls clear every column filter at once.
|
|
309
|
+
Column `meta.filter` offers a column in `DataGridFilters`, hidden columns included. A `range` filter edits `[min, max]` bounds, `null` for an open end, for `filterFn: "inNumberRange"`; its inputs suggest the range of the rows the other filters leave, formatted through the filter's `Intl.NumberFormatOptions`. An `options` filter chooses among labelled string values, one or several, listed in its `options` or, when they depend on runtime data, in the `options` prop of `DataGridFilters` and `DataGridFilterSummary` keyed by column ID, for `filterFn: "arrHas"` (one value per row), `"arrIncludesSome"` (an array per row), or a custom `filterFn`; each option counts the rows the other filters leave with that value, so a column whose rows hold several values or values in another form supplies them through `getUniqueValues`. Column filters combine with each other and with the global filter. `DataGridFilterSummary` lists the active filters with buttons that remove them, and both controls clear every column filter at once.
|
|
310
310
|
|
|
311
311
|
`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.
|
|
312
312
|
|