@alexgorbatchev/shadcn 0.0.35 → 0.0.36
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 +2 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/chunk-c7tnf6h7.js +397 -0
- package/dist/{chunk-c6g2rbhv.js → chunk-f71469fs.js} +480 -840
- package/dist/{chunk-h5kjmt32.js → chunk-kmvvw1vr.js} +17 -1
- package/dist/components/data-grid/DataGrid.d.ts +45 -1
- package/dist/components/data-grid/DataGridColumnOptions.d.ts +4 -10
- package/dist/components/data-grid/DataGridFilterSummary.d.ts +8 -0
- package/dist/components/data-grid/DataGridFilters.d.ts +9 -0
- package/dist/components/data-grid/describeDataGridFilter.d.ts +8 -0
- package/dist/components/data-grid/getDataGridFilterLabel.d.ts +5 -0
- package/dist/components/data-grid/index.d.ts +3 -1
- package/dist/components/data-grid/index.js +360 -1
- package/dist/components/data-grid/readDataGridOptionValues.d.ts +3 -0
- package/dist/components/data-grid/readDataGridRange.d.ts +6 -0
- package/dist/components/json-render/index.js +2 -1
- package/dist/components/virtual-data-grid/index.js +1 -1
- package/dist/index.js +28 -26
- package/llms/components/data-display/DataGridFilterSummary.md +35 -0
- package/llms/components/data-display/DataGridFilters.md +38 -0
- package/llms/setup.md +2 -0
- package/llms.txt +2 -0
- package/package.json +1 -1
|
@@ -22,14 +22,21 @@ import {
|
|
|
22
22
|
// src/components/data-grid/DataGrid.tsx
|
|
23
23
|
import {
|
|
24
24
|
FlexRender,
|
|
25
|
+
columnFacetingFeature,
|
|
25
26
|
columnFilteringFeature,
|
|
26
27
|
columnOrderingFeature,
|
|
27
28
|
columnResizingFeature,
|
|
28
29
|
columnSizingFeature,
|
|
29
30
|
columnVisibilityFeature,
|
|
31
|
+
createFacetedMinMaxValues,
|
|
32
|
+
createFacetedRowModel,
|
|
33
|
+
createFacetedUniqueValues,
|
|
30
34
|
createFilteredRowModel,
|
|
31
35
|
createPaginatedRowModel,
|
|
32
36
|
createSortedRowModel,
|
|
37
|
+
filterFn_arrHas,
|
|
38
|
+
filterFn_arrIncludesSome,
|
|
39
|
+
filterFn_inNumberRange,
|
|
33
40
|
filterFn_includesString,
|
|
34
41
|
globalFilteringFeature,
|
|
35
42
|
rowPaginationFeature,
|
|
@@ -97,6 +104,7 @@ function getDataGridColumnSizeVariables(table) {
|
|
|
97
104
|
import { jsx as jsx2, jsxs, Fragment } from "react/jsx-runtime";
|
|
98
105
|
var columnMeta = {};
|
|
99
106
|
var dataGridFeatures2 = tableFeatures({
|
|
107
|
+
columnFacetingFeature,
|
|
100
108
|
columnFilteringFeature,
|
|
101
109
|
columnOrderingFeature,
|
|
102
110
|
columnSizingFeature,
|
|
@@ -106,10 +114,18 @@ var dataGridFeatures2 = tableFeatures({
|
|
|
106
114
|
rowPaginationFeature,
|
|
107
115
|
rowSelectionFeature,
|
|
108
116
|
rowSortingFeature,
|
|
117
|
+
facetedRowModel: createFacetedRowModel(),
|
|
118
|
+
facetedMinMaxValues: createFacetedMinMaxValues(),
|
|
119
|
+
facetedUniqueValues: createFacetedUniqueValues(),
|
|
109
120
|
filteredRowModel: createFilteredRowModel(),
|
|
110
121
|
sortedRowModel: createSortedRowModel(),
|
|
111
122
|
paginatedRowModel: createPaginatedRowModel(),
|
|
112
|
-
filterFns: {
|
|
123
|
+
filterFns: {
|
|
124
|
+
arrHas: filterFn_arrHas,
|
|
125
|
+
arrIncludesSome: filterFn_arrIncludesSome,
|
|
126
|
+
includesString: filterFn_includesString,
|
|
127
|
+
inNumberRange: filterFn_inNumberRange
|
|
128
|
+
},
|
|
113
129
|
sortFns: { alphanumeric: sortFn_alphanumeric, basic: sortFn_basic },
|
|
114
130
|
columnMeta
|
|
115
131
|
});
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
import { type CellData, type Column, type ReactTable, type Row, type RowData, type Table as CoreTable, type TableState } from "@tanstack/react-table";
|
|
2
2
|
import { type ReactElement, type ReactNode } from "react";
|
|
3
3
|
import type { IDensityProps } from "../../density/types.js";
|
|
4
|
+
import type { ILabelValue } from "../../options/types.js";
|
|
4
5
|
import { type TableTextAlign, type TableVisibility } from "../Table.js";
|
|
6
|
+
/**
|
|
7
|
+
* A numeric range. The filter value is `[min, max]`, with `null` for an open end; pair it with
|
|
8
|
+
* `filterFn: "inNumberRange"`. The inputs suggest the range of the rows other filters leave.
|
|
9
|
+
*/
|
|
10
|
+
interface IDataGridRangeFilter {
|
|
11
|
+
variant: "range";
|
|
12
|
+
/** Names the filter; defaults to the column label. */
|
|
13
|
+
label?: string;
|
|
14
|
+
step?: number;
|
|
15
|
+
/** Formats the bounds in the inputs and the active-filter summary, such as `{ useGrouping: false }` for years. */
|
|
16
|
+
format?: Intl.NumberFormatOptions;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A choice among known values. The filter value is the chosen option values; pair it with `filterFn: "arrHas"` for a
|
|
20
|
+
* single value per row, `"arrIncludesSome"` for an array of values, or a column `filterFn` that reads them. Each option
|
|
21
|
+
* shows how many rows the other filters leave with that value, so the column's unique values must be option values;
|
|
22
|
+
* a column whose rows hold several values, or values in another form, supplies them through `getUniqueValues`.
|
|
23
|
+
*/
|
|
24
|
+
interface IDataGridOptionsFilter {
|
|
25
|
+
variant: "options";
|
|
26
|
+
/** Names the filter; defaults to the column label. */
|
|
27
|
+
label?: string;
|
|
28
|
+
options: readonly ILabelValue[];
|
|
29
|
+
/** Allows choosing several options; a single choice still writes a one-value array. Defaults to true. */
|
|
30
|
+
multiple?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** How `DataGridFilters` edits a column's filter and `DataGridFilterSummary` describes it. */
|
|
33
|
+
type DataGridColumnFilter = IDataGridRangeFilter | IDataGridOptionsFilter;
|
|
5
34
|
/** Presentation settings a column definition carries in its `meta`. */
|
|
6
35
|
interface IDataGridColumnMeta {
|
|
7
36
|
/** Name in the column picker and resize handle; defaults to a string header, then the column ID. */
|
|
@@ -17,8 +46,11 @@ interface IDataGridColumnMeta {
|
|
|
17
46
|
* header's `aria-sort` reports whichever of them, or the column itself, is sorted.
|
|
18
47
|
*/
|
|
19
48
|
sortColumnIds?: readonly string[];
|
|
49
|
+
/** Offers the column in `DataGridFilters`, whether or not it is visible. */
|
|
50
|
+
filter?: DataGridColumnFilter;
|
|
20
51
|
}
|
|
21
52
|
declare const dataGridFeatures: {
|
|
53
|
+
columnFacetingFeature: import("@tanstack/react-table").TableFeature;
|
|
22
54
|
columnFilteringFeature: import("@tanstack/react-table").TableFeature;
|
|
23
55
|
columnOrderingFeature: import("@tanstack/react-table").TableFeature;
|
|
24
56
|
columnSizingFeature: import("@tanstack/react-table").TableFeature;
|
|
@@ -28,11 +60,17 @@ declare const dataGridFeatures: {
|
|
|
28
60
|
rowPaginationFeature: import("@tanstack/react-table").TableFeature;
|
|
29
61
|
rowSelectionFeature: import("@tanstack/react-table").TableFeature;
|
|
30
62
|
rowSortingFeature: import("@tanstack/react-table").TableFeature;
|
|
63
|
+
facetedRowModel: (table: CoreTable<any, any>, columnId: string) => () => import("@tanstack/react-table").RowModel<any, any>;
|
|
64
|
+
facetedMinMaxValues: (table: CoreTable<import("@tanstack/react-table").TableFeatures, any>, columnId: string) => () => undefined | [number, number];
|
|
65
|
+
facetedUniqueValues: (table: CoreTable<import("@tanstack/react-table").TableFeatures, any>, columnId: string) => () => Map<any, number>;
|
|
31
66
|
filteredRowModel: (table: CoreTable<any, any>) => () => import("@tanstack/react-table").RowModel<any, any>;
|
|
32
67
|
sortedRowModel: (table: CoreTable<any, any>) => () => import("@tanstack/react-table").RowModel<any, any>;
|
|
33
68
|
paginatedRowModel: (table: CoreTable<any, any>) => () => import("@tanstack/react-table").RowModel<any, any>;
|
|
34
69
|
filterFns: {
|
|
70
|
+
arrHas: import("@tanstack/react-table").CreatedFilterFn<any, any>;
|
|
71
|
+
arrIncludesSome: import("@tanstack/react-table").CreatedFilterFn<any, any>;
|
|
35
72
|
includesString: import("@tanstack/react-table").CreatedFilterFn<any, any>;
|
|
73
|
+
inNumberRange: import("@tanstack/react-table").CreatedFilterFn<any, any>;
|
|
36
74
|
};
|
|
37
75
|
sortFns: {
|
|
38
76
|
alphanumeric: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
@@ -43,6 +81,12 @@ declare const dataGridFeatures: {
|
|
|
43
81
|
type DataGridFeatures = typeof dataGridFeatures;
|
|
44
82
|
/** A table built with `dataGridFeatures`; `TSelected` is the state its `useTable` selector returns. */
|
|
45
83
|
type DataGridTable<T extends RowData, TSelected = TableState<DataGridFeatures>> = ReactTable<DataGridFeatures, T, TSelected>;
|
|
84
|
+
/** Props of a control that works on a whole grid, such as its column options or filters. */
|
|
85
|
+
interface IDataGridControlProps<T extends RowData> {
|
|
86
|
+
table: CoreTable<DataGridFeatures, T>;
|
|
87
|
+
/** Names the control; each control documents its default. */
|
|
88
|
+
label?: string;
|
|
89
|
+
}
|
|
46
90
|
type DataGridRow<T extends RowData> = Row<DataGridFeatures, T>;
|
|
47
91
|
type DataGridColumn<T extends RowData> = Column<DataGridFeatures, T, CellData>;
|
|
48
92
|
declare function getDataGridColumnLabel<T extends RowData>(column: DataGridColumn<T>): string;
|
|
@@ -85,4 +129,4 @@ declare function DataGridPagination<T extends RowData>({ table }: {
|
|
|
85
129
|
table: DataGridTable<T>;
|
|
86
130
|
}): ReactElement;
|
|
87
131
|
export { DataGrid, DataGridCells, DataGridColumnHeader, DataGridColumns, DataGridFilter, DataGridHeaderRows, DataGridPagination, dataGridFeatures, getDataGridColumnLabel, };
|
|
88
|
-
export type { DataGridColumn, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta };
|
|
132
|
+
export type { DataGridColumn, DataGridColumnFilter, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, IDataGridControlProps, IDataGridOptionsFilter, IDataGridRangeFilter, };
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { type RowData
|
|
1
|
+
import { type RowData } from "@tanstack/react-table";
|
|
2
2
|
import type { ReactElement } from "react";
|
|
3
|
-
import { type
|
|
4
|
-
interface IDataGridColumnOptionsProps<T extends RowData> {
|
|
5
|
-
table: Table<DataGridFeatures, T>;
|
|
6
|
-
/** Trigger and popover title. */
|
|
7
|
-
label?: string;
|
|
8
|
-
}
|
|
3
|
+
import { type IDataGridControlProps } from "./DataGrid.js";
|
|
9
4
|
/**
|
|
10
5
|
* Shows, hides, and reorders the columns that allow hiding. Columns with `enableHiding: false` keep their positions.
|
|
11
|
-
* Reset restores the table's initial visibility, order, and sizes.
|
|
6
|
+
* Reset restores the table's initial visibility, order, and sizes. `label` titles the trigger and popover.
|
|
12
7
|
*/
|
|
13
|
-
export declare function DataGridColumnOptions<T extends RowData>({ table, label, }:
|
|
14
|
-
export {};
|
|
8
|
+
export declare function DataGridColumnOptions<T extends RowData>({ table, label, }: IDataGridControlProps<T>): ReactElement;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RowData } from "@tanstack/react-table";
|
|
2
|
+
import type { ReactElement } from "react";
|
|
3
|
+
import type { IDataGridControlProps } from "./DataGrid.js";
|
|
4
|
+
/**
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
export declare function DataGridFilterSummary<T extends RowData>({ table, label, }: IDataGridControlProps<T>): ReactElement;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RowData } from "@tanstack/react-table";
|
|
2
|
+
import { type ReactElement } from "react";
|
|
3
|
+
import type { IDataGridControlProps } from "./DataGrid.js";
|
|
4
|
+
/**
|
|
5
|
+
* Edits the filters of every column whose `meta.filter` describes one, hidden columns included. Filters combine with
|
|
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.
|
|
8
|
+
*/
|
|
9
|
+
export declare function DataGridFilters<T extends RowData>({ table, label, }: IDataGridControlProps<T>): ReactElement;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DataGridColumnFilter } from "./DataGrid.js";
|
|
2
|
+
/**
|
|
3
|
+
* Describes a filter value in a few words: `120–128`, `≥ 120`, or `≤ 128` for a range, and the chosen option labels for
|
|
4
|
+
* options. Values without a matching option read as themselves. Returns an empty string for a value that filters
|
|
5
|
+
* nothing.
|
|
6
|
+
*/
|
|
7
|
+
declare function describeDataGridFilter(filter: DataGridColumnFilter, value: unknown, locale?: string): string;
|
|
8
|
+
export { describeDataGridFilter };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RowData } from "@tanstack/react-table";
|
|
2
|
+
import { type DataGridColumn } from "./DataGrid.js";
|
|
3
|
+
/** Names a column's filter: its own label, else the column's. */
|
|
4
|
+
declare function getDataGridFilterLabel<T extends RowData>(column: DataGridColumn<T>): string;
|
|
5
|
+
export { getDataGridFilterLabel };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { DataGrid, DataGridCells, DataGridColumnHeader, DataGridFilter, DataGridPagination, dataGridFeatures, } from "./DataGrid.js";
|
|
2
|
-
export type { DataGridColumn, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, } from "./DataGrid.js";
|
|
2
|
+
export type { DataGridColumn, DataGridColumnFilter, DataGridFeatures, DataGridProps, DataGridRow, DataGridTable, IDataGridColumnMeta, IDataGridControlProps, IDataGridOptionsFilter, IDataGridRangeFilter, } from "./DataGrid.js";
|
|
3
3
|
export { DataGridColumnOptions } from "./DataGridColumnOptions.js";
|
|
4
|
+
export { DataGridFilters } from "./DataGridFilters.js";
|
|
5
|
+
export { DataGridFilterSummary } from "./DataGridFilterSummary.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
DataGridColumnHeader2,
|
|
14
14
|
DataGridFilter2,
|
|
15
15
|
DataGridPagination2
|
|
16
|
-
} from "../../chunk-
|
|
16
|
+
} from "../../chunk-kmvvw1vr.js";
|
|
17
17
|
import {
|
|
18
18
|
Checkbox2
|
|
19
19
|
} from "../../chunk-tnnf8ydf.js";
|
|
@@ -30,6 +30,28 @@ import {
|
|
|
30
30
|
PopoverHeader2,
|
|
31
31
|
PopoverTitle2
|
|
32
32
|
} from "../../chunk-4djw71cv.js";
|
|
33
|
+
import {
|
|
34
|
+
Combobox2,
|
|
35
|
+
ComboboxValue2,
|
|
36
|
+
ComboboxInput2,
|
|
37
|
+
ComboboxContent2,
|
|
38
|
+
ComboboxList2,
|
|
39
|
+
ComboboxItem2,
|
|
40
|
+
ComboboxEmpty2,
|
|
41
|
+
ComboboxChips2,
|
|
42
|
+
ComboboxChip2,
|
|
43
|
+
ComboboxChipsInput2,
|
|
44
|
+
useComboboxAnchor2,
|
|
45
|
+
ScrollArea2,
|
|
46
|
+
NumberField2,
|
|
47
|
+
NumberFieldGroup2,
|
|
48
|
+
NumberFieldInput2
|
|
49
|
+
} from "../../chunk-c7tnf6h7.js";
|
|
50
|
+
import {
|
|
51
|
+
Badge2
|
|
52
|
+
} from "../../chunk-wjx6zf94.js";
|
|
53
|
+
import"../../chunk-hz9azhzx.js";
|
|
54
|
+
import"../../chunk-57jj9v64.js";
|
|
33
55
|
// src/components/data-grid/DataGridColumnOptions.tsx
|
|
34
56
|
import { Subscribe } from "@tanstack/react-table";
|
|
35
57
|
import { ArrowDownIcon, ArrowUpIcon, Columns3Icon } from "lucide-react";
|
|
@@ -142,12 +164,349 @@ function DataGridColumnOptions({
|
|
|
142
164
|
]
|
|
143
165
|
});
|
|
144
166
|
}
|
|
167
|
+
// src/components/data-grid/DataGridFilters.tsx
|
|
168
|
+
import { Subscribe as Subscribe2 } from "@tanstack/react-table";
|
|
169
|
+
import { ListFilterIcon } from "lucide-react";
|
|
170
|
+
import { useId } from "react";
|
|
171
|
+
|
|
172
|
+
// src/components/data-grid/getDataGridFilterLabel.ts
|
|
173
|
+
function getDataGridFilterLabel(column) {
|
|
174
|
+
return column.columnDef.meta?.filter?.label ?? getDataGridColumnLabel(column);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/components/data-grid/readDataGridOptionValues.ts
|
|
178
|
+
var NO_VALUES = [];
|
|
179
|
+
function readDataGridOptionValues(value) {
|
|
180
|
+
if (!Array.isArray(value))
|
|
181
|
+
return NO_VALUES;
|
|
182
|
+
return value.filter((item) => typeof item === "string");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/components/data-grid/readDataGridRange.ts
|
|
186
|
+
var OPEN_RANGE = [null, null];
|
|
187
|
+
function readBound(value) {
|
|
188
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
189
|
+
}
|
|
190
|
+
function readDataGridRange(value) {
|
|
191
|
+
if (!Array.isArray(value) || value.length !== 2)
|
|
192
|
+
return OPEN_RANGE;
|
|
193
|
+
return [readBound(value[0]), readBound(value[1])];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/components/data-grid/DataGridFilters.tsx
|
|
197
|
+
import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
|
|
198
|
+
function DataGridRangeFilterControl({
|
|
199
|
+
column,
|
|
200
|
+
filter,
|
|
201
|
+
label
|
|
202
|
+
}) {
|
|
203
|
+
const labelId = useId();
|
|
204
|
+
const [min, max] = readDataGridRange(column.getFilterValue());
|
|
205
|
+
const available = column.getFacetedMinMaxValues();
|
|
206
|
+
const formatter = new Intl.NumberFormat(undefined, filter.format);
|
|
207
|
+
const update = (next) => column.setFilterValue(next[0] === null && next[1] === null ? undefined : next);
|
|
208
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
209
|
+
role: "group",
|
|
210
|
+
"aria-labelledby": labelId,
|
|
211
|
+
className: "grid gap-1.5",
|
|
212
|
+
children: [
|
|
213
|
+
/* @__PURE__ */ jsx2("span", {
|
|
214
|
+
id: labelId,
|
|
215
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
216
|
+
children: label
|
|
217
|
+
}),
|
|
218
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
219
|
+
className: "grid grid-cols-2 gap-2",
|
|
220
|
+
children: [
|
|
221
|
+
/* @__PURE__ */ jsx2(NumberField2, {
|
|
222
|
+
value: min,
|
|
223
|
+
step: filter.step,
|
|
224
|
+
format: filter.format,
|
|
225
|
+
onValueChange: (value) => update([value, max]),
|
|
226
|
+
children: /* @__PURE__ */ jsx2(NumberFieldGroup2, {
|
|
227
|
+
children: /* @__PURE__ */ jsx2(NumberFieldInput2, {
|
|
228
|
+
"aria-label": `Minimum ${label}`,
|
|
229
|
+
placeholder: available ? formatter.format(available[0]) : "Min"
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
}),
|
|
233
|
+
/* @__PURE__ */ jsx2(NumberField2, {
|
|
234
|
+
value: max,
|
|
235
|
+
step: filter.step,
|
|
236
|
+
format: filter.format,
|
|
237
|
+
onValueChange: (value) => update([min, value]),
|
|
238
|
+
children: /* @__PURE__ */ jsx2(NumberFieldGroup2, {
|
|
239
|
+
children: /* @__PURE__ */ jsx2(NumberFieldInput2, {
|
|
240
|
+
"aria-label": `Maximum ${label}`,
|
|
241
|
+
placeholder: available ? formatter.format(available[1]) : "Max"
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
]
|
|
246
|
+
})
|
|
247
|
+
]
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function DataGridOptionsFilterControl({
|
|
251
|
+
column,
|
|
252
|
+
filter,
|
|
253
|
+
label
|
|
254
|
+
}) {
|
|
255
|
+
const labelId = useId();
|
|
256
|
+
const anchor = useComboboxAnchor2();
|
|
257
|
+
const counts = column.getFacetedUniqueValues();
|
|
258
|
+
const selected = readDataGridOptionValues(column.getFilterValue()).map((value) => filter.options.find((option) => option.value === value) ?? { label: value, value });
|
|
259
|
+
const update = (next) => column.setFilterValue(next.length ? next.map((option) => option.value) : undefined);
|
|
260
|
+
const content = /* @__PURE__ */ jsxs2(Fragment, {
|
|
261
|
+
children: [
|
|
262
|
+
/* @__PURE__ */ jsx2(ComboboxEmpty2, {
|
|
263
|
+
children: "No matches."
|
|
264
|
+
}),
|
|
265
|
+
/* @__PURE__ */ jsx2(ComboboxList2, {
|
|
266
|
+
children: (option) => /* @__PURE__ */ jsxs2(ComboboxItem2, {
|
|
267
|
+
value: option,
|
|
268
|
+
children: [
|
|
269
|
+
/* @__PURE__ */ jsx2("span", {
|
|
270
|
+
className: "min-w-0 flex-1 truncate",
|
|
271
|
+
children: option.label
|
|
272
|
+
}),
|
|
273
|
+
" ",
|
|
274
|
+
/* @__PURE__ */ jsx2("span", {
|
|
275
|
+
className: "text-xs text-muted-foreground tabular-nums",
|
|
276
|
+
children: counts.get(option.value) ?? 0
|
|
277
|
+
})
|
|
278
|
+
]
|
|
279
|
+
}, option.value)
|
|
280
|
+
})
|
|
281
|
+
]
|
|
282
|
+
});
|
|
283
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
284
|
+
className: "grid gap-1.5",
|
|
285
|
+
children: [
|
|
286
|
+
/* @__PURE__ */ jsx2("span", {
|
|
287
|
+
id: labelId,
|
|
288
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
289
|
+
children: label
|
|
290
|
+
}),
|
|
291
|
+
filter.multiple === false ? /* @__PURE__ */ jsxs2(Combobox2, {
|
|
292
|
+
items: filter.options,
|
|
293
|
+
value: selected[0] ?? null,
|
|
294
|
+
onValueChange: (option) => update(option ? [option] : []),
|
|
295
|
+
itemToStringLabel: (option) => option.label,
|
|
296
|
+
isItemEqualToValue: (option, value) => option.value === value.value,
|
|
297
|
+
children: [
|
|
298
|
+
/* @__PURE__ */ jsx2(ComboboxInput2, {
|
|
299
|
+
"aria-labelledby": labelId,
|
|
300
|
+
placeholder: "Any",
|
|
301
|
+
showClear: true,
|
|
302
|
+
clearLabel: `Clear ${label}`
|
|
303
|
+
}),
|
|
304
|
+
/* @__PURE__ */ jsx2(ComboboxContent2, {
|
|
305
|
+
children: content
|
|
306
|
+
})
|
|
307
|
+
]
|
|
308
|
+
}) : /* @__PURE__ */ jsxs2(Combobox2, {
|
|
309
|
+
items: filter.options,
|
|
310
|
+
multiple: true,
|
|
311
|
+
value: selected,
|
|
312
|
+
onValueChange: (options) => update(options),
|
|
313
|
+
itemToStringLabel: (option) => option.label,
|
|
314
|
+
isItemEqualToValue: (option, value) => option.value === value.value,
|
|
315
|
+
children: [
|
|
316
|
+
/* @__PURE__ */ jsx2(ComboboxChips2, {
|
|
317
|
+
ref: anchor,
|
|
318
|
+
children: /* @__PURE__ */ jsx2(ComboboxValue2, {
|
|
319
|
+
children: (options) => /* @__PURE__ */ jsxs2(Fragment, {
|
|
320
|
+
children: [
|
|
321
|
+
options.map((option) => /* @__PURE__ */ jsx2(ComboboxChip2, {
|
|
322
|
+
removeLabel: `Remove ${option.label}`,
|
|
323
|
+
children: option.label
|
|
324
|
+
}, option.value)),
|
|
325
|
+
/* @__PURE__ */ jsx2(ComboboxChipsInput2, {
|
|
326
|
+
"aria-labelledby": labelId,
|
|
327
|
+
placeholder: options.length ? undefined : "Any"
|
|
328
|
+
})
|
|
329
|
+
]
|
|
330
|
+
})
|
|
331
|
+
})
|
|
332
|
+
}),
|
|
333
|
+
/* @__PURE__ */ jsx2(ComboboxContent2, {
|
|
334
|
+
anchor,
|
|
335
|
+
children: content
|
|
336
|
+
})
|
|
337
|
+
]
|
|
338
|
+
})
|
|
339
|
+
]
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function DataGridFilters({
|
|
343
|
+
table,
|
|
344
|
+
label = "Filters"
|
|
345
|
+
}) {
|
|
346
|
+
return /* @__PURE__ */ jsxs2(Popover2, {
|
|
347
|
+
children: [
|
|
348
|
+
/* @__PURE__ */ jsx2(Subscribe2, {
|
|
349
|
+
source: table.atoms.columnFilters,
|
|
350
|
+
children: (filters) => /* @__PURE__ */ jsxs2(PopoverTrigger2, {
|
|
351
|
+
render: /* @__PURE__ */ jsx2(Button2, {
|
|
352
|
+
variant: "outline"
|
|
353
|
+
}),
|
|
354
|
+
children: [
|
|
355
|
+
/* @__PURE__ */ jsx2(ListFilterIcon, {
|
|
356
|
+
"data-icon": "inline-start",
|
|
357
|
+
"aria-hidden": "true"
|
|
358
|
+
}),
|
|
359
|
+
label,
|
|
360
|
+
filters.length > 0 && /* @__PURE__ */ jsxs2(Badge2, {
|
|
361
|
+
variant: "secondary",
|
|
362
|
+
children: [
|
|
363
|
+
filters.length,
|
|
364
|
+
/* @__PURE__ */ jsx2("span", {
|
|
365
|
+
className: "sr-only",
|
|
366
|
+
children: " active"
|
|
367
|
+
})
|
|
368
|
+
]
|
|
369
|
+
})
|
|
370
|
+
]
|
|
371
|
+
})
|
|
372
|
+
}),
|
|
373
|
+
/* @__PURE__ */ jsxs2(PopoverContent2, {
|
|
374
|
+
align: "end",
|
|
375
|
+
className: "max-h-(--available-height) w-80",
|
|
376
|
+
children: [
|
|
377
|
+
/* @__PURE__ */ jsx2(PopoverHeader2, {
|
|
378
|
+
children: /* @__PURE__ */ jsx2(PopoverTitle2, {
|
|
379
|
+
children: label
|
|
380
|
+
})
|
|
381
|
+
}),
|
|
382
|
+
/* @__PURE__ */ jsx2(Subscribe2, {
|
|
383
|
+
source: table.atoms.columnFilters,
|
|
384
|
+
children: (filters) => /* @__PURE__ */ jsxs2(Fragment, {
|
|
385
|
+
children: [
|
|
386
|
+
/* @__PURE__ */ jsx2(ScrollArea2, {
|
|
387
|
+
className: "flex-1",
|
|
388
|
+
children: /* @__PURE__ */ jsx2("div", {
|
|
389
|
+
className: "grid gap-3 pe-2.5",
|
|
390
|
+
children: table.getAllLeafColumns().map((column) => {
|
|
391
|
+
const filter = column.columnDef.meta?.filter;
|
|
392
|
+
if (!filter)
|
|
393
|
+
return null;
|
|
394
|
+
const name = getDataGridFilterLabel(column);
|
|
395
|
+
return filter.variant === "range" ? /* @__PURE__ */ jsx2(DataGridRangeFilterControl, {
|
|
396
|
+
column,
|
|
397
|
+
filter,
|
|
398
|
+
label: name
|
|
399
|
+
}, column.id) : /* @__PURE__ */ jsx2(DataGridOptionsFilterControl, {
|
|
400
|
+
column,
|
|
401
|
+
filter,
|
|
402
|
+
label: name
|
|
403
|
+
}, column.id);
|
|
404
|
+
})
|
|
405
|
+
})
|
|
406
|
+
}),
|
|
407
|
+
/* @__PURE__ */ jsx2(Button2, {
|
|
408
|
+
variant: "outline",
|
|
409
|
+
size: "sm",
|
|
410
|
+
disabled: filters.length === 0,
|
|
411
|
+
onClick: () => table.setColumnFilters([]),
|
|
412
|
+
children: "Clear filters"
|
|
413
|
+
})
|
|
414
|
+
]
|
|
415
|
+
})
|
|
416
|
+
})
|
|
417
|
+
]
|
|
418
|
+
})
|
|
419
|
+
]
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
// src/components/data-grid/DataGridFilterSummary.tsx
|
|
423
|
+
import { Subscribe as Subscribe3 } from "@tanstack/react-table";
|
|
424
|
+
import { XIcon } from "lucide-react";
|
|
425
|
+
|
|
426
|
+
// src/components/data-grid/describeDataGridFilter.ts
|
|
427
|
+
function describeDataGridFilter(filter, value, locale) {
|
|
428
|
+
if (filter.variant === "options") {
|
|
429
|
+
return readDataGridOptionValues(value).map((item) => filter.options.find((option) => option.value === item)?.label ?? item).join(", ");
|
|
430
|
+
}
|
|
431
|
+
const formatter = new Intl.NumberFormat(locale, filter.format);
|
|
432
|
+
const [min, max] = readDataGridRange(value);
|
|
433
|
+
if (min !== null && max !== null)
|
|
434
|
+
return `${formatter.format(Math.min(min, max))}–${formatter.format(Math.max(min, max))}`;
|
|
435
|
+
if (min !== null)
|
|
436
|
+
return `≥ ${formatter.format(min)}`;
|
|
437
|
+
if (max !== null)
|
|
438
|
+
return `≤ ${formatter.format(max)}`;
|
|
439
|
+
return "";
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// src/components/data-grid/DataGridFilterSummary.tsx
|
|
443
|
+
import { jsx as jsx3, jsxs as jsxs3, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
444
|
+
function DataGridFilterSummary({
|
|
445
|
+
table,
|
|
446
|
+
label = "Active filters"
|
|
447
|
+
}) {
|
|
448
|
+
return /* @__PURE__ */ jsx3(Subscribe3, {
|
|
449
|
+
source: table.atoms.columnFilters,
|
|
450
|
+
children: () => {
|
|
451
|
+
const active = table.getAllLeafColumns().flatMap((column) => {
|
|
452
|
+
const filter = column.columnDef.meta?.filter;
|
|
453
|
+
const description = filter ? describeDataGridFilter(filter, column.getFilterValue()) : "";
|
|
454
|
+
return description ? [{ column, description, name: getDataGridFilterLabel(column) }] : [];
|
|
455
|
+
});
|
|
456
|
+
return /* @__PURE__ */ jsx3(Fragment2, {
|
|
457
|
+
children: active.length > 0 && /* @__PURE__ */ jsxs3("div", {
|
|
458
|
+
className: "flex min-w-0 flex-wrap items-center gap-2",
|
|
459
|
+
children: [
|
|
460
|
+
/* @__PURE__ */ jsx3("ul", {
|
|
461
|
+
"aria-label": label,
|
|
462
|
+
className: "flex min-w-0 flex-wrap gap-1.5",
|
|
463
|
+
children: active.map(({ column, description, name }) => /* @__PURE__ */ jsx3("li", {
|
|
464
|
+
className: "min-w-0",
|
|
465
|
+
children: /* @__PURE__ */ jsxs3(Badge2, {
|
|
466
|
+
variant: "outline",
|
|
467
|
+
className: "max-w-full pe-0",
|
|
468
|
+
children: [
|
|
469
|
+
/* @__PURE__ */ jsxs3("span", {
|
|
470
|
+
className: "truncate",
|
|
471
|
+
children: [
|
|
472
|
+
name,
|
|
473
|
+
": ",
|
|
474
|
+
description
|
|
475
|
+
]
|
|
476
|
+
}),
|
|
477
|
+
/* @__PURE__ */ jsx3(Button2, {
|
|
478
|
+
variant: "ghost",
|
|
479
|
+
size: "icon-xs",
|
|
480
|
+
"aria-label": `Remove ${name} filter`,
|
|
481
|
+
onClick: () => column.setFilterValue(undefined),
|
|
482
|
+
children: /* @__PURE__ */ jsx3(XIcon, {
|
|
483
|
+
"aria-hidden": "true"
|
|
484
|
+
})
|
|
485
|
+
})
|
|
486
|
+
]
|
|
487
|
+
})
|
|
488
|
+
}, column.id))
|
|
489
|
+
}),
|
|
490
|
+
/* @__PURE__ */ jsx3(Button2, {
|
|
491
|
+
variant: "ghost",
|
|
492
|
+
size: "sm",
|
|
493
|
+
onClick: () => table.setColumnFilters([]),
|
|
494
|
+
children: "Clear filters"
|
|
495
|
+
})
|
|
496
|
+
]
|
|
497
|
+
})
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
}
|
|
145
502
|
export {
|
|
146
503
|
DataGrid2 as DataGrid,
|
|
147
504
|
DataGridCells2 as DataGridCells,
|
|
148
505
|
DataGridColumnHeader2 as DataGridColumnHeader,
|
|
149
506
|
DataGridColumnOptions,
|
|
150
507
|
DataGridFilter2 as DataGridFilter,
|
|
508
|
+
DataGridFilterSummary,
|
|
509
|
+
DataGridFilters,
|
|
151
510
|
DataGridPagination2 as DataGridPagination,
|
|
152
511
|
dataGridFeatures2 as dataGridFeatures
|
|
153
512
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** A range filter's bounds; `null` leaves that end open. */
|
|
2
|
+
type DataGridRange = readonly [min: number | null, max: number | null];
|
|
3
|
+
/** Reads a range filter value, treating anything other than a two-item array of finite numbers or nulls as open. */
|
|
4
|
+
declare function readDataGridRange(value: unknown): DataGridRange;
|
|
5
|
+
export { readDataGridRange };
|
|
6
|
+
export type { DataGridRange };
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
DrawerHeader2,
|
|
28
28
|
DrawerTitle2,
|
|
29
29
|
DrawerDescription2
|
|
30
|
-
} from "../../chunk-
|
|
30
|
+
} from "../../chunk-f71469fs.js";
|
|
31
31
|
import"../../chunk-e6hk39ev.js";
|
|
32
32
|
import"../../chunk-j89xg1ak.js";
|
|
33
33
|
import"../../chunk-aa7m22zj.js";
|
|
@@ -93,6 +93,7 @@ import {
|
|
|
93
93
|
CardContent2
|
|
94
94
|
} from "../../chunk-bygq5yqf.js";
|
|
95
95
|
import"../../chunk-57jj9v64.js";
|
|
96
|
+
import"../../chunk-c7tnf6h7.js";
|
|
96
97
|
import {
|
|
97
98
|
Tabs2,
|
|
98
99
|
TabsList2,
|