@zuilib/data-grid 0.3.0
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 +129 -0
- package/dist/cells.d.ts +61 -0
- package/dist/cells.js +60 -0
- package/dist/columns-Def2RYjD.d.ts +51 -0
- package/dist/data-grid.d.ts +309 -0
- package/dist/data-grid.js +1573 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1630 -0
- package/dist/server-adapter.d.ts +65 -0
- package/dist/server-adapter.js +105 -0
- package/dist/state-9r5WYKo_.d.ts +63 -0
- package/dist/types-B00kY3c9.d.ts +97 -0
- package/dist/types-Br4lyM03.d.ts +192 -0
- package/dist/types-D4DDIl3w.d.ts +73 -0
- package/dist/types-D8c-NBWy.d.ts +117 -0
- package/dist/types-DJh1--C1.d.ts +188 -0
- package/dist/types-j91R0mPE.d.ts +75 -0
- package/dist/use-data-grid.d.ts +71 -0
- package/dist/use-data-grid.js +206 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# @zuilib/data-grid
|
|
2
|
+
|
|
3
|
+
A server-driven enterprise data grid on [TanStack Table](https://tanstack.com/table),
|
|
4
|
+
built from the `@zuilib/components` primitives and styled only through ZUI tokens.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pnpm add @zuilib/data-grid @zuilib/components @zuilib/tokens @tanstack/react-table @headlessui/react
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import DataGrid, { defaultDataGridState, toQuery, toQueryKey } from '@zuilib/data-grid'
|
|
12
|
+
|
|
13
|
+
const [state, setState] = useState(defaultDataGridState)
|
|
14
|
+
const key = toQueryKey(state) // changes only when the request would
|
|
15
|
+
useEffect(() => { fetch(toQuery(state)).then(setPage) }, [key])
|
|
16
|
+
|
|
17
|
+
<DataGrid columns={columns} rows={page} rowCount={total} state={state} onStateChange={setState} loading={loading}>
|
|
18
|
+
<DataGrid.Toolbar />
|
|
19
|
+
</DataGrid>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Leave `state` out and the grid keeps it itself, starting from `defaultState`; `onStateChange` still reports every change. Controlled, every emission is the `state` prop plus one change: apply it, or ignore it to reject it.
|
|
23
|
+
|
|
24
|
+
## Exports
|
|
25
|
+
|
|
26
|
+
| Subpath | Exports |
|
|
27
|
+
|---------|---------|
|
|
28
|
+
| `@zuilib/data-grid` | Everything below in one entry; `DataGrid` is the default export |
|
|
29
|
+
| `@zuilib/data-grid/data-grid` | `DataGrid` (default) with `DataGrid.Toolbar`, plus the column, label, filter and selection-action types |
|
|
30
|
+
| `@zuilib/data-grid/use-data-grid` | `useDataGrid` — the TanStack table wiring without the layout, for composing the parts yourself |
|
|
31
|
+
| `@zuilib/data-grid/server-adapter` | `toQuery`, `fromQuery`, `toQueryKey`, `toServerState`, `toColumnState`, `fromColumnState` |
|
|
32
|
+
| `@zuilib/data-grid/cells` | `dateCell`, `dateTimeCell`, `textColumn`, `twoValuesColumn` |
|
|
33
|
+
|
|
34
|
+
## Component API
|
|
35
|
+
|
|
36
|
+
### DataGrid — `@zuilib/data-grid`
|
|
37
|
+
|
|
38
|
+
| Prop | Type | Default |
|
|
39
|
+
|------|------|---------|
|
|
40
|
+
| `columns` | `DataGridColumnDef<TData>[]` | required — TanStack column defs plus the ZUI extras below |
|
|
41
|
+
| `rows` | `TData[]` | required — the current page of rows, rendered as given |
|
|
42
|
+
| `rowCount` | `number` | required — total rows on the server (all pages); drives the page count and the range text. Ignored with `manualPagination={false}`: the rows that pass the filters are counted instead |
|
|
43
|
+
| `state` / `defaultState` / `onStateChange` | `Partial<DataGridState>` | controlled or uncontrolled — `onStateChange` receives the whole next state on every interaction |
|
|
44
|
+
| `manualPagination` / `manualSorting` / `manualFiltering` | `boolean` | `true` — the server answers the state; `false` pages, sorts or filters `rows` client-side |
|
|
45
|
+
| `getRowId` | `(row, index, parent?) => string` | row index |
|
|
46
|
+
| `enableRowSelection` | `boolean \| (row) => boolean` | `true` — adds the leading checkbox column |
|
|
47
|
+
| `enableColumnResizing` | `boolean` | `true` |
|
|
48
|
+
| `loading` | `boolean` | `false` — renders skeleton rows (keeping the layout) and marks the table busy |
|
|
49
|
+
| `skeletonWhileRefreshing` | `boolean` | `false` — show skeleton rows while `loading` even when rows are already displayed |
|
|
50
|
+
| `error` | `ReactNode` | — a string gets the danger Alert; with no rows it replaces the body, with rows it sits above them as a banner |
|
|
51
|
+
| `emptyState` | `ReactNode` | — replaces the default "No results" empty state |
|
|
52
|
+
| `density` | `'compact' \| 'comfortable'` | `'comfortable'` |
|
|
53
|
+
| `stickyHeader` | `boolean` | `false` — pins the header row to the top of the scroll container (bound it with `scrollAreaClassName`) |
|
|
54
|
+
| `onRowClick` | `(row, event) => void` | — |
|
|
55
|
+
| `onCellCommit` | `(commit: DataGridCellCommit) => void` | — commit of an inline edit (`enableInlineEdit` on a column) |
|
|
56
|
+
| `commitOnBlur` | `boolean` | `true` — an inline edit that loses focus is committed; `false` drops it instead |
|
|
57
|
+
| `renderExpanded` | `(row) => ReactNode` | — content of the full-width row under an expanded row; setting it adds the chevron column |
|
|
58
|
+
| `getRowCanExpand` | `(row) => boolean` | every row when `renderExpanded` is set |
|
|
59
|
+
| `selectionActions` | `DataGridSelectionAction[]` | `[]` — buttons in the bar that appears while rows are selected |
|
|
60
|
+
| `selectAllMatching` | `boolean` | `true` — offer "Select all N" once every row on the page is selected and more rows match |
|
|
61
|
+
| `showPagination` | `boolean` | `true` — render the pagination footer |
|
|
62
|
+
| `pageSizeOptions` | `number[]` | `[10, 25, 50, 100]` |
|
|
63
|
+
| `labels` | `Partial<DataGridLabels>` | English — every string the grid renders (`defaultDataGridLabels` lists them) |
|
|
64
|
+
| `locale` | `string` | user's locale — BCP 47 tag for the numbers the grid formats |
|
|
65
|
+
| `aria-label` | `string` | `'Data grid'` |
|
|
66
|
+
| `tableOptions` | `Partial<TableOptions>` | — anything else TanStack accepts (`defaultColumn`, `meta`, …) |
|
|
67
|
+
| `children` | `ReactNode` | — `<DataGrid.Toolbar>` and anything else to render above the table |
|
|
68
|
+
| `className` / `tableClassName` / `scrollAreaClassName` | `string` | root / `<table>` / scrolling wrapper |
|
|
69
|
+
|
|
70
|
+
`DataGridSelectionAction` is `{ id, label, variant?, tone?, onSelect }` — `variant` and `tone` are the
|
|
71
|
+
`@zuilib/components` Button axes (`ButtonVariant` / `ButtonTone`); `onSelect(selectedIds, { allMatching, rowCount })`
|
|
72
|
+
receives the selected row ids.
|
|
73
|
+
|
|
74
|
+
### DataGrid.Toolbar
|
|
75
|
+
|
|
76
|
+
| Prop | Type | Default |
|
|
77
|
+
|------|------|---------|
|
|
78
|
+
| `showSearch` | `boolean` | `true` — the global search field, debounced into the `search` state |
|
|
79
|
+
| `searchPlaceholder` | `string` | `labels.searchPlaceholder` |
|
|
80
|
+
| `searchDebounceMs` | `number` | `300` — ms between the last keystroke and the `search` change |
|
|
81
|
+
| `showFilterChips` | `boolean` | `true` — a removable chip per active column filter |
|
|
82
|
+
| `showColumnManager` | `boolean` | `true` — visibility, order and pinning in one popover |
|
|
83
|
+
| `addableColumns` | `DataGridAddableField[]` | — fields offered under "Add column" |
|
|
84
|
+
| `onAddColumn` | `(id: string) => void` | — the consumer appends the column def |
|
|
85
|
+
| `children` | `ReactNode` | — rendered between the chips and the column manager |
|
|
86
|
+
|
|
87
|
+
### Columns
|
|
88
|
+
|
|
89
|
+
`DataGridColumnDef` is a TanStack `ColumnDef` plus the ZUI extras — on the def itself or on `meta`:
|
|
90
|
+
|
|
91
|
+
| Extra | Type | Effect |
|
|
92
|
+
|-------|------|--------|
|
|
93
|
+
| `align` | `'start' \| 'center' \| 'end'` | Head and cell alignment; `'end'` for numbers |
|
|
94
|
+
| `width` | `number` | Initial width in px; the user resizes from there |
|
|
95
|
+
| `filter` | `{ control: 'text' } \| { control: 'select', options } \| { control: 'date-range' }` | Declares the column's filter popover |
|
|
96
|
+
| `enableInlineEdit` | `boolean` | Double-click or Enter turns the cell into an input; see `onCellCommit` |
|
|
97
|
+
| `meta.label` | `string` | The column's name in the column manager, filter chips and pin labels when `header` is not a string |
|
|
98
|
+
|
|
99
|
+
### State
|
|
100
|
+
|
|
101
|
+
`DataGridState` holds `pagination`, `sorting`, `columnFilters`, `search` (the free-text search),
|
|
102
|
+
`columnVisibility`, `columnOrder`, `columnPinning` (`{ start, end }` — logical directions),
|
|
103
|
+
`rowSelection`, `expanded`, `allMatching` and optionally `columnSizing`.
|
|
104
|
+
|
|
105
|
+
### Server adapter — `@zuilib/data-grid/server-adapter`
|
|
106
|
+
|
|
107
|
+
Pure functions between `DataGridState` and your API: `toQuery(state)` builds the request (`{ page, pageSize, sort, filters, search, allMatching }`, 1-based page, filters keyed in column-id order) and `fromQuery(query)` restores the state from one; `toQueryKey(state)` is a stable string that changes only when the server request would (drop it in a `useEffect` dependency or a react-query key); `toServerState(state)` strips the UI-only keys; `toColumnState` / `fromColumnState` pack the saved-view keys (visibility, order, pinning) for persistence.
|
|
108
|
+
|
|
109
|
+
### Cells — `@zuilib/data-grid/cells`
|
|
110
|
+
|
|
111
|
+
Column helpers for the common enterprise shapes: `dateCell` / `dateTimeCell` (locale-formatted presets of `createDateCell(options)`), `textColumn` (accessor + header + sorting in one call, on one row `field`), `twoValuesColumn` (primary line + muted secondary line, each a `{ field, render? }`).
|
|
112
|
+
|
|
113
|
+
### Headless — `@zuilib/data-grid/use-data-grid`
|
|
114
|
+
|
|
115
|
+
`useDataGrid(options)` is the state and TanStack wiring without the layout: it returns `{ table, state, setState, replaceState }` so the toolbar, selection bar, body and pagination can be composed differently. `<DataGrid>` is this hook plus the default layout (`DataGrid.Toolbar`, `DataGrid.SelectionBar`, `DataGrid.Body`, `DataGrid.Pagination`, `DataGrid.ColumnManager`).
|
|
116
|
+
|
|
117
|
+
## Keyboard
|
|
118
|
+
|
|
119
|
+
The grid is one tab stop (the row, cell or head last focused). ArrowUp / ArrowDown move between rows, ArrowRight enters the cells and the arrows move between them (ArrowUp from the first row reaches the header); Enter / Space on a cell act on its checkbox or chevron, start an inline edit, or click the row. Shift+ArrowRight / Shift+ArrowLeft open / close an expandable row.
|
|
120
|
+
|
|
121
|
+
## Localisation
|
|
122
|
+
|
|
123
|
+
`labels` overrides any string (`defaultDataGridLabels` lists them); `locale` formats the numbers.
|
|
124
|
+
|
|
125
|
+
## Bulk selection
|
|
126
|
+
|
|
127
|
+
Once every row on the page is selected, "Select all N" sets `allMatching` in the state; `toQuery` passes it on and selection actions receive `{allMatching, rowCount}`.
|
|
128
|
+
|
|
129
|
+
Docs: the "Data grid" section of the ZUI documentation site.
|
package/dist/cells.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CellContext } from '@tanstack/react-table';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { b as DataGridColumnDef } from './columns-Def2RYjD.js';
|
|
4
|
+
|
|
5
|
+
interface DateCellOptions {
|
|
6
|
+
/** BCP 47 tag(s); the browser's locale when left out. */
|
|
7
|
+
locale?: string | string[];
|
|
8
|
+
/** Passed to `Intl.DateTimeFormat`. */
|
|
9
|
+
format?: Intl.DateTimeFormatOptions;
|
|
10
|
+
/** Rendered for `null`, `undefined`, `''` and invalid dates. @default '-' */
|
|
11
|
+
empty?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
type DateCellValue = string | number | Date | null | undefined;
|
|
14
|
+
/** A cell renderer for `cell:`; `dateCell` and `dateTimeCell` are the two presets. */
|
|
15
|
+
type DataGridCellRenderer<TData = unknown, TValue = unknown> = (context: CellContext<TData, TValue>) => ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Builds a locale-aware date cell: a `<time dateTime>` holding the formatted
|
|
18
|
+
* value, or `empty` when there is nothing to show. The formatter is created
|
|
19
|
+
* once per column, not per row.
|
|
20
|
+
*/
|
|
21
|
+
declare function createDateCell({ locale, format, empty }?: DateCellOptions): DataGridCellRenderer<any, any>;
|
|
22
|
+
/** `cell: dateCell` renders the date part in the user's locale (`Intl` `dateStyle: 'medium'`). */
|
|
23
|
+
declare const dateCell: DataGridCellRenderer<any, any>;
|
|
24
|
+
/** `cell: dateTimeCell` renders date and time in the user's locale (`dateStyle: 'medium', timeStyle: 'short'`). */
|
|
25
|
+
declare const dateTimeCell: DataGridCellRenderer<any, any>;
|
|
26
|
+
interface TextColumnOptions<TData> extends Omit<DataGridColumnDef<TData, any>, 'id' | 'accessorKey' | 'accessorFn' | 'header'> {
|
|
27
|
+
/** The row field (also the column id). */
|
|
28
|
+
field: keyof TData & string;
|
|
29
|
+
header: string;
|
|
30
|
+
/** @default true */
|
|
31
|
+
enableSorting?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A plain text column on one field. Sortable by default; every other ZUI
|
|
35
|
+
* and TanStack column option (`filter`, `width`, `align`, `cell`, ...) passes through.
|
|
36
|
+
*/
|
|
37
|
+
declare function textColumn<TData>({ field, header, cell, enableSorting, ...rest }: TextColumnOptions<TData>): DataGridColumnDef<TData, any>;
|
|
38
|
+
interface TwoValuesColumnField<TData> {
|
|
39
|
+
/** The row field. */
|
|
40
|
+
field: keyof TData & string;
|
|
41
|
+
/** Replaces the raw field; receives the row's cell context. */
|
|
42
|
+
render?: (context: CellContext<TData, any>) => ReactNode;
|
|
43
|
+
}
|
|
44
|
+
interface TwoValuesColumnOptions<TData> extends Omit<DataGridColumnDef<TData, any>, 'id' | 'accessorKey' | 'accessorFn' | 'header' | 'cell'> {
|
|
45
|
+
/** @default primary.field */
|
|
46
|
+
id?: string;
|
|
47
|
+
header: string;
|
|
48
|
+
/** The top line, medium weight. Sorting and filtering read this field. */
|
|
49
|
+
primary: TwoValuesColumnField<TData>;
|
|
50
|
+
/** The second line, small and muted. */
|
|
51
|
+
secondary: TwoValuesColumnField<TData>;
|
|
52
|
+
/** @default false */
|
|
53
|
+
enableSorting?: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A column stacking two fields of the row: the primary value on top, a
|
|
57
|
+
* muted secondary under it (a name over an email, a title over a reference).
|
|
58
|
+
*/
|
|
59
|
+
declare function twoValuesColumn<TData>({ id, header, primary, secondary, enableSorting, ...rest }: TwoValuesColumnOptions<TData>): DataGridColumnDef<TData, any>;
|
|
60
|
+
|
|
61
|
+
export { type DataGridCellRenderer, type DateCellOptions, type DateCellValue, type TextColumnOptions, type TwoValuesColumnField, type TwoValuesColumnOptions, createDateCell, dateCell, dateTimeCell, textColumn, twoValuesColumn };
|
package/dist/cells.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/cells.tsx
|
|
4
|
+
import { cn } from "@zuilib/components/lib/cn";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function toDate(value) {
|
|
7
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
8
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
9
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
10
|
+
}
|
|
11
|
+
function createDateCell({ locale, format, empty = "-" } = {}) {
|
|
12
|
+
const formatter = new Intl.DateTimeFormat(locale, format);
|
|
13
|
+
return (context) => {
|
|
14
|
+
const date = toDate(context.getValue());
|
|
15
|
+
if (!date) {
|
|
16
|
+
return /* @__PURE__ */ jsx("span", { "data-slot": "data-grid-date-cell", "data-empty": "", className: "text-muted-foreground", children: empty });
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ jsx("time", { "data-slot": "data-grid-date-cell", dateTime: date.toISOString(), children: formatter.format(date) });
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
var dateCell = createDateCell({ format: { dateStyle: "medium" } });
|
|
22
|
+
var dateTimeCell = createDateCell({ format: { dateStyle: "medium", timeStyle: "short" } });
|
|
23
|
+
function textColumn({ field, header, cell, enableSorting = true, ...rest }) {
|
|
24
|
+
return {
|
|
25
|
+
...rest,
|
|
26
|
+
id: field,
|
|
27
|
+
accessorKey: field,
|
|
28
|
+
header,
|
|
29
|
+
enableSorting,
|
|
30
|
+
cell: cell ?? ((context) => /* @__PURE__ */ jsx("span", { "data-slot": "data-grid-text-cell", children: context.getValue() }))
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function twoValuesColumn({
|
|
34
|
+
id,
|
|
35
|
+
header,
|
|
36
|
+
primary,
|
|
37
|
+
secondary,
|
|
38
|
+
enableSorting = false,
|
|
39
|
+
...rest
|
|
40
|
+
}) {
|
|
41
|
+
const value = (row, field) => row[field];
|
|
42
|
+
return {
|
|
43
|
+
...rest,
|
|
44
|
+
id: id ?? primary.field,
|
|
45
|
+
accessorKey: primary.field,
|
|
46
|
+
header,
|
|
47
|
+
enableSorting,
|
|
48
|
+
cell: (context) => /* @__PURE__ */ jsxs("div", { "data-slot": "data-grid-two-values", className: cn("flex min-w-0 flex-col gap-0.5"), children: [
|
|
49
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "data-grid-two-values-primary", className: "truncate font-medium", children: primary.render ? primary.render(context) : value(context.row.original, primary.field) }),
|
|
50
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "data-grid-two-values-secondary", className: "truncate text-xs text-muted-foreground", children: secondary.render ? secondary.render(context) : value(context.row.original, secondary.field) })
|
|
51
|
+
] })
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
createDateCell,
|
|
56
|
+
dateCell,
|
|
57
|
+
dateTimeCell,
|
|
58
|
+
textColumn,
|
|
59
|
+
twoValuesColumn
|
|
60
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ColumnDef } from '@tanstack/react-table';
|
|
2
|
+
|
|
3
|
+
type DataGridAlign = 'start' | 'center' | 'end';
|
|
4
|
+
/** A text filter: one string, matched however the server matches it. */
|
|
5
|
+
interface DataGridFilterText {
|
|
6
|
+
control: 'text';
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
}
|
|
9
|
+
/** A facet filter: a list of options, of which any number may be picked. */
|
|
10
|
+
interface DataGridFilterSelect {
|
|
11
|
+
control: 'select';
|
|
12
|
+
options: readonly {
|
|
13
|
+
value: string;
|
|
14
|
+
label?: string;
|
|
15
|
+
}[];
|
|
16
|
+
}
|
|
17
|
+
/** A date range: ISO `YYYY-MM-DD` bounds, either side optional. */
|
|
18
|
+
interface DataGridFilterDateRange {
|
|
19
|
+
control: 'date-range';
|
|
20
|
+
}
|
|
21
|
+
/** Discriminated on `control`: the widget the filter popover renders. */
|
|
22
|
+
type DataGridFilter = DataGridFilterText | DataGridFilterSelect | DataGridFilterDateRange;
|
|
23
|
+
interface DataGridDateRange {
|
|
24
|
+
from?: string;
|
|
25
|
+
to?: string;
|
|
26
|
+
}
|
|
27
|
+
/** The ZUI extras on a TanStack column definition. */
|
|
28
|
+
interface DataGridColumnExtras {
|
|
29
|
+
/** Double-click or Enter on a cell turns it into an input; see `onCellCommit`. */
|
|
30
|
+
enableInlineEdit?: boolean;
|
|
31
|
+
/** Horizontal alignment of the head and the cells; `end` for numbers. */
|
|
32
|
+
align?: DataGridAlign;
|
|
33
|
+
/** Initial width in px (TanStack `size`); the user can resize from there. */
|
|
34
|
+
width?: number;
|
|
35
|
+
/** Declares the column's filter popover. */
|
|
36
|
+
filter?: DataGridFilter;
|
|
37
|
+
}
|
|
38
|
+
type DataGridColumnDef<TData, TValue = unknown> = ColumnDef<TData, TValue> & DataGridColumnExtras;
|
|
39
|
+
/** The extras may also be declared on `meta` (the TanStack way of extending a column). */
|
|
40
|
+
interface DataGridColumnMeta extends DataGridColumnExtras {
|
|
41
|
+
/** The column's name in the column manager, the filter chips and the pin labels, when `header` is not a string. */
|
|
42
|
+
label?: string;
|
|
43
|
+
}
|
|
44
|
+
/** The payload of `onCellCommit`: an inline edit the user committed. */
|
|
45
|
+
interface DataGridCellCommit {
|
|
46
|
+
rowId: string;
|
|
47
|
+
columnId: string;
|
|
48
|
+
value: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type { DataGridAlign as D, DataGridCellCommit as a, DataGridColumnDef as b, DataGridColumnExtras as c, DataGridColumnMeta as d, DataGridDateRange as e, DataGridFilter as f, DataGridFilterDateRange as g, DataGridFilterSelect as h, DataGridFilterText as i };
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { Row, Table, Updater } from '@tanstack/react-table';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { MouseEvent, ReactNode, ComponentPropsWithoutRef } from 'react';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import { a as DataGridCellCommit } from './columns-Def2RYjD.js';
|
|
6
|
+
export { D as DataGridAlign, b as DataGridColumnDef, c as DataGridColumnExtras, d as DataGridColumnMeta, e as DataGridDateRange, f as DataGridFilter, g as DataGridFilterDateRange, h as DataGridFilterSelect, i as DataGridFilterText } from './columns-Def2RYjD.js';
|
|
7
|
+
import { e as DataGridState, b as DataGridDensity, c as DataGridSelectionAction } from './state-9r5WYKo_.js';
|
|
8
|
+
export { D as DEFAULT_PAGE_SIZE, a as DataGridColumnPinning, d as DataGridSelectionActionContext, f as defaultDataGridState, r as resolveDataGridState } from './state-9r5WYKo_.js';
|
|
9
|
+
import { UseDataGridOptions } from './use-data-grid.js';
|
|
10
|
+
export { DataGridStateChangeHandler, UseDataGridResult, normalizeColumnState, default as useDataGrid } from './use-data-grid.js';
|
|
11
|
+
export { DataGridColumnState, DataGridQuery, DataGridServerState, fromColumnState, fromQuery, toColumnState, toQuery, toQueryKey, toServerState } from './server-adapter.js';
|
|
12
|
+
import '@zuilib/components/button';
|
|
13
|
+
|
|
14
|
+
/** A field the grid could show but has no column for yet. */
|
|
15
|
+
interface DataGridAddableField {
|
|
16
|
+
/** Becomes the argument of `onAddColumn`. */
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
}
|
|
20
|
+
interface DataGridColumnManagerProps {
|
|
21
|
+
/** Text of the trigger button. @default labels.columns ('Columns') */
|
|
22
|
+
label?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Fields the consumer could turn into columns — an "Add column" section
|
|
26
|
+
* under the list. The grid can't build a column definition itself, so
|
|
27
|
+
* picking one only calls `onAddColumn`; the consumer appends the column def
|
|
28
|
+
* (the `@zuilib/views` preset does this from the dataset schema).
|
|
29
|
+
*/
|
|
30
|
+
addable?: readonly DataGridAddableField[];
|
|
31
|
+
/** Called with the picked field's `id`. Required for `addable` to render. */
|
|
32
|
+
onAddColumn?: (id: string) => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A popover listing every column: a checkbox for visibility, up / down to
|
|
36
|
+
* reorder, pin to either edge. Changes go out as `columnVisibility`,
|
|
37
|
+
* `columnOrder` and `columnPinning` state.
|
|
38
|
+
*/
|
|
39
|
+
declare function DataGridColumnManager({ label: labelProp, className, addable, onAddColumn }: DataGridColumnManagerProps): react_jsx_runtime.JSX.Element;
|
|
40
|
+
|
|
41
|
+
interface DataGridBodyProps<TData> {
|
|
42
|
+
/** Accessible name of the table. */
|
|
43
|
+
'aria-label'?: string;
|
|
44
|
+
'aria-labelledby'?: string;
|
|
45
|
+
/** Pin the header row to the top of the scroll container (bound it with `scrollAreaClassName="max-h-96"`). */
|
|
46
|
+
stickyHeader?: boolean;
|
|
47
|
+
onRowClick?: (row: Row<TData>, event: MouseEvent<HTMLTableRowElement>) => void;
|
|
48
|
+
/** With no rows it replaces the body; with rows it sits above them as a banner. */
|
|
49
|
+
error?: ReactNode;
|
|
50
|
+
/** Show skeleton rows while loading even when rows are already displayed. @default false */
|
|
51
|
+
skeletonWhileRefreshing?: boolean;
|
|
52
|
+
emptyState?: ReactNode;
|
|
53
|
+
className?: string;
|
|
54
|
+
scrollAreaClassName?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The `<table>` itself: sortable, filterable, resizable heads; selectable,
|
|
58
|
+
* keyboard-operable rows and cells; skeleton rows while loading; an error or
|
|
59
|
+
* an empty state spanning every column. Rendered by `<DataGrid>` after its children.
|
|
60
|
+
*
|
|
61
|
+
* `aria-colcount` / `aria-colindex` count the visible leaf columns: a hidden
|
|
62
|
+
* column is removed from the grid (the column manager, not the grid, knows
|
|
63
|
+
* about it), so the visible set is the whole set the grid presents.
|
|
64
|
+
*/
|
|
65
|
+
declare function DataGridBody<TData>({ stickyHeader, onRowClick, error, skeletonWhileRefreshing, emptyState, className, scrollAreaClassName, ...aria }: DataGridBodyProps<TData>): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Every string the grid renders or announces, overridable for another
|
|
69
|
+
* language. A `{name}` placeholder is replaced with the value named.
|
|
70
|
+
*/
|
|
71
|
+
interface DataGridLabels {
|
|
72
|
+
/** @default 'Pin to start' */
|
|
73
|
+
pinStart: string;
|
|
74
|
+
/** @default 'Pin to end' */
|
|
75
|
+
pinEnd: string;
|
|
76
|
+
/** @default 'Unpin' */
|
|
77
|
+
unpin: string;
|
|
78
|
+
/** @default 'Expand row' */
|
|
79
|
+
expandRow: string;
|
|
80
|
+
/** @default 'Collapse row' */
|
|
81
|
+
collapseRow: string;
|
|
82
|
+
/** The sr-only head of the expand column. @default 'Expand' */
|
|
83
|
+
expandColumn: string;
|
|
84
|
+
/** Selection bar: the count of selected rows. `{count}` is replaced. @default '{count} selected' */
|
|
85
|
+
selectedCount: string;
|
|
86
|
+
/** Selection bar: the count when every matching row is selected. `{count}` is replaced. @default 'All {count} selected' */
|
|
87
|
+
allMatchingSelected: string;
|
|
88
|
+
/** Selection bar: the button that selects every matching row. `{count}` is replaced. @default 'Select all {count}' */
|
|
89
|
+
selectAllMatching: string;
|
|
90
|
+
/** @default 'Clear selection' */
|
|
91
|
+
clearSelection: string;
|
|
92
|
+
/** The selection bar's region name. @default 'Bulk actions' */
|
|
93
|
+
selectionActions: string;
|
|
94
|
+
/** The head checkbox. @default 'Select all rows on this page' */
|
|
95
|
+
selectAllOnPage: string;
|
|
96
|
+
/** A row checkbox. @default 'Select row' */
|
|
97
|
+
selectRow: string;
|
|
98
|
+
/** The footer's `<nav>` name. @default 'Pagination' */
|
|
99
|
+
pagination: string;
|
|
100
|
+
/** @default 'Rows per page' */
|
|
101
|
+
rowsPerPage: string;
|
|
102
|
+
/** The range text while loading. @default 'Loading…' */
|
|
103
|
+
loading: string;
|
|
104
|
+
/** The range text. `{first}`, `{last}` and `{total}` are replaced. @default '{first}–{last} of {total}' */
|
|
105
|
+
range: string;
|
|
106
|
+
/** @default 'First page' */
|
|
107
|
+
firstPage: string;
|
|
108
|
+
/** @default 'Previous page' */
|
|
109
|
+
previousPage: string;
|
|
110
|
+
/** @default 'Next page' */
|
|
111
|
+
nextPage: string;
|
|
112
|
+
/** @default 'Last page' */
|
|
113
|
+
lastPage: string;
|
|
114
|
+
/** The toolbar search field's name. @default 'Search' */
|
|
115
|
+
search: string;
|
|
116
|
+
/** The toolbar search field's placeholder. @default 'Search…' */
|
|
117
|
+
searchPlaceholder: string;
|
|
118
|
+
/** The filter chip list's name. @default 'Active filters' */
|
|
119
|
+
activeFilters: string;
|
|
120
|
+
/** A chip's remove button. `{column}` is replaced. @default 'Remove {column} filter' */
|
|
121
|
+
removeFilter: string;
|
|
122
|
+
/** The column manager button and its list. @default 'Columns' */
|
|
123
|
+
columns: string;
|
|
124
|
+
/** `{column}` is replaced. @default 'Move {column} up' */
|
|
125
|
+
moveUp: string;
|
|
126
|
+
/** `{column}` is replaced. @default 'Move {column} down' */
|
|
127
|
+
moveDown: string;
|
|
128
|
+
/** The column manager's addable-fields section. @default 'Add column' */
|
|
129
|
+
addColumnSection: string;
|
|
130
|
+
/** An addable field's button. `{column}` is replaced. @default 'Add {column}' */
|
|
131
|
+
addColumn: string;
|
|
132
|
+
/** The funnel button. `{column}` is replaced. @default 'Filter {column}' */
|
|
133
|
+
filterColumn: string;
|
|
134
|
+
/** The funnel button while a filter is set. `{column}` is replaced. @default 'Filter {column} (active)' */
|
|
135
|
+
filterColumnActive: string;
|
|
136
|
+
/** The text filter input. @default 'Filter value' */
|
|
137
|
+
filterValue: string;
|
|
138
|
+
/** The text filter placeholder when the column declares none. @default 'Contains…' */
|
|
139
|
+
filterPlaceholder: string;
|
|
140
|
+
/** The facet filter's checkbox group. @default 'Options' */
|
|
141
|
+
filterOptions: string;
|
|
142
|
+
/** @default 'From' */
|
|
143
|
+
from: string;
|
|
144
|
+
/** @default 'To' */
|
|
145
|
+
to: string;
|
|
146
|
+
/** @default 'Clear' */
|
|
147
|
+
clear: string;
|
|
148
|
+
/** @default 'Apply' */
|
|
149
|
+
apply: string;
|
|
150
|
+
/** A date-range chip with only a lower bound. `{date}` is replaced. @default 'from {date}' */
|
|
151
|
+
rangeFrom: string;
|
|
152
|
+
/** A date-range chip with only an upper bound. `{date}` is replaced. @default 'until {date}' */
|
|
153
|
+
rangeUntil: string;
|
|
154
|
+
/** The resize handle. `{column}` is replaced. @default 'Resize {column}' */
|
|
155
|
+
resizeColumn: string;
|
|
156
|
+
/** The inline edit input. `{column}` is replaced. @default 'Edit {column}' */
|
|
157
|
+
editColumn: string;
|
|
158
|
+
/** The default empty state's title. @default 'No results' */
|
|
159
|
+
noResults: string;
|
|
160
|
+
/** The default empty state's description. @default 'Try a different search or clear the filters.' */
|
|
161
|
+
noResultsDescription: string;
|
|
162
|
+
}
|
|
163
|
+
declare const defaultDataGridLabels: DataGridLabels;
|
|
164
|
+
|
|
165
|
+
interface DataGridPaginationProps extends Omit<ComponentPropsWithoutRef<'nav'>, 'className'> {
|
|
166
|
+
/** BCP 47 tag for the range numbers; the grid's `locale`, then the user's, when left out. */
|
|
167
|
+
locale?: string;
|
|
168
|
+
className?: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The footer: page size, `1–25 of 1,240`, first / previous / next / last.
|
|
172
|
+
* Reads `pagination` and `rowCount`; emits `pagination`.
|
|
173
|
+
*/
|
|
174
|
+
declare function DataGridPagination({ locale: localeProp, className, ...props }: DataGridPaginationProps): react_jsx_runtime.JSX.Element;
|
|
175
|
+
|
|
176
|
+
interface DataGridSelectionBarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'className'> {
|
|
177
|
+
className?: string;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Appears while rows are selected: the count, one button per
|
|
181
|
+
* `selectionActions` entry (called with the selected row ids) and a clear
|
|
182
|
+
* button. Once every row on the page is selected and more rows match,
|
|
183
|
+
* "Select all N" sets `allMatching` in the state; the actions then receive
|
|
184
|
+
* `{allMatching: true}`.
|
|
185
|
+
*/
|
|
186
|
+
declare function DataGridSelectionBar({ className, ...props }: DataGridSelectionBarProps): react_jsx_runtime.JSX.Element | null;
|
|
187
|
+
|
|
188
|
+
interface DataGridToolbarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'className'> {
|
|
189
|
+
/** Show the global search field. @default true */
|
|
190
|
+
showSearch?: boolean;
|
|
191
|
+
/** @default labels.searchPlaceholder ('Search…') */
|
|
192
|
+
searchPlaceholder?: string;
|
|
193
|
+
/** Milliseconds between the last keystroke and the `search` change. @default 300 */
|
|
194
|
+
searchDebounceMs?: number;
|
|
195
|
+
/** Show a removable chip per active column filter. @default true */
|
|
196
|
+
showFilterChips?: boolean;
|
|
197
|
+
/** Show the column manager button. @default true */
|
|
198
|
+
showColumnManager?: boolean;
|
|
199
|
+
/** Fields the column manager offers under "Add column" — see `DataGridColumnManagerProps.addable`. */
|
|
200
|
+
addableColumns?: readonly DataGridAddableField[];
|
|
201
|
+
/** Called with a picked addable field's `id`; the consumer appends the column def. */
|
|
202
|
+
onAddColumn?: (id: string) => void;
|
|
203
|
+
/** Rendered between the chips and the column manager. */
|
|
204
|
+
children?: ReactNode;
|
|
205
|
+
className?: string;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The bar above the table: a debounced global search (emits `search`),
|
|
209
|
+
* a removable chip per active column filter, the column manager and any
|
|
210
|
+
* children. Rendered by the consumer as a child of `<DataGrid>`.
|
|
211
|
+
*/
|
|
212
|
+
declare function DataGridToolbar({ showSearch, searchPlaceholder, searchDebounceMs, showFilterChips, showColumnManager, addableColumns, onAddColumn, children, className, ...props }: DataGridToolbarProps): react_jsx_runtime.JSX.Element;
|
|
213
|
+
|
|
214
|
+
interface DataGridContextValue<TData = unknown> {
|
|
215
|
+
table: Table<TData>;
|
|
216
|
+
state: DataGridState;
|
|
217
|
+
/** `useDataGrid`'s `setState`: replaces one key and emits. Optional; without it the selection bar has no "Select all N". */
|
|
218
|
+
setState?: <K extends keyof DataGridState>(key: K, updater: Updater<DataGridState[K]>) => void;
|
|
219
|
+
loading: boolean;
|
|
220
|
+
density: DataGridDensity;
|
|
221
|
+
onCellCommit?: (commit: DataGridCellCommit) => void;
|
|
222
|
+
/** The content of the full-width row under an expanded row. */
|
|
223
|
+
renderExpanded?: (row: Row<TData>) => ReactNode;
|
|
224
|
+
selectionActions: readonly DataGridSelectionAction[];
|
|
225
|
+
pageSizeOptions: readonly number[];
|
|
226
|
+
rowCount: number;
|
|
227
|
+
labels: DataGridLabels;
|
|
228
|
+
/** BCP 47 tag for the numbers the grid formats (the range text, the counts); the user's locale when left out. */
|
|
229
|
+
locale?: string;
|
|
230
|
+
/** An inline edit that loses focus is committed (`true`) or dropped (`false`). */
|
|
231
|
+
commitOnBlur: boolean;
|
|
232
|
+
/** Offer "Select all N" in the selection bar once every row on the page is selected. */
|
|
233
|
+
selectAllMatching: boolean;
|
|
234
|
+
}
|
|
235
|
+
declare const DataGridContext: react.Context<DataGridContextValue<unknown> | null>;
|
|
236
|
+
/** The grid a part sits in. Throws outside `<DataGrid>`: every part needs the table. */
|
|
237
|
+
declare function useDataGridContext<TData = unknown>(part: string): DataGridContextValue<TData>;
|
|
238
|
+
|
|
239
|
+
declare const SELECT_COLUMN_ID = "__select";
|
|
240
|
+
|
|
241
|
+
declare const EXPAND_COLUMN_ID = "__expand";
|
|
242
|
+
|
|
243
|
+
declare const DEFAULT_PAGE_SIZE_OPTIONS: readonly number[];
|
|
244
|
+
interface DataGridProps<TData> extends Omit<UseDataGridOptions<TData>, 'enableRowSelection' | 'fixedColumnIds'>, Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'className' | 'onError'> {
|
|
245
|
+
/** Total rows on the server (all pages). Drives the page count and the range text. Ignored with `manualPagination={false}`: the rows that pass the filters are counted instead. */
|
|
246
|
+
rowCount: number;
|
|
247
|
+
/** Renders skeleton rows (keeping the layout) and marks the table busy. */
|
|
248
|
+
loading?: boolean;
|
|
249
|
+
/**
|
|
250
|
+
* An error message (a string gets the danger Alert). With no rows it
|
|
251
|
+
* replaces the body; with rows it sits above them as a banner.
|
|
252
|
+
*/
|
|
253
|
+
error?: ReactNode;
|
|
254
|
+
/** Show skeleton rows while `loading` even when rows are already displayed. @default false */
|
|
255
|
+
skeletonWhileRefreshing?: boolean;
|
|
256
|
+
/** Overrides the grid's own strings (`defaultDataGridLabels` lists them all). */
|
|
257
|
+
labels?: Partial<DataGridLabels>;
|
|
258
|
+
/** Replaces the default "No results" empty state. */
|
|
259
|
+
emptyState?: ReactNode;
|
|
260
|
+
/** @default 'comfortable' */
|
|
261
|
+
density?: DataGridDensity;
|
|
262
|
+
/** Pin the header row to the top of the scroll container (bound it with `scrollAreaClassName`). */
|
|
263
|
+
stickyHeader?: boolean;
|
|
264
|
+
onRowClick?: (row: Row<TData>, event: React.MouseEvent<HTMLTableRowElement>) => void;
|
|
265
|
+
/** Commit of an inline edit (`enableInlineEdit` on a column). */
|
|
266
|
+
onCellCommit?: (commit: DataGridCellCommit) => void;
|
|
267
|
+
/** An inline edit that loses focus (a click elsewhere, Tab) is committed; `false` drops it instead. @default true */
|
|
268
|
+
commitOnBlur?: boolean;
|
|
269
|
+
/** Offer "Select all N" in the selection bar once every row on the page is selected and more rows match; sets `allMatching` in the state. @default true */
|
|
270
|
+
selectAllMatching?: boolean;
|
|
271
|
+
/** BCP 47 tag for the numbers the grid formats (the range text, the selection counts). The user's locale when left out or invalid. Text comes from `labels`. */
|
|
272
|
+
locale?: string;
|
|
273
|
+
/**
|
|
274
|
+
* Content of the full-width row shown under an expanded row. Setting it
|
|
275
|
+
* adds the chevron column after the selection column; `expanded` in the
|
|
276
|
+
* state records which rows are open.
|
|
277
|
+
*/
|
|
278
|
+
renderExpanded?: (row: Row<TData>) => ReactNode;
|
|
279
|
+
/** Buttons in the bar that appears while rows are selected. */
|
|
280
|
+
selectionActions?: readonly DataGridSelectionAction[];
|
|
281
|
+
/** Adds the leading checkbox column. @default true */
|
|
282
|
+
enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
|
|
283
|
+
/** @default [10, 25, 50, 100] */
|
|
284
|
+
pageSizeOptions?: readonly number[];
|
|
285
|
+
/** Render the pagination footer. @default true */
|
|
286
|
+
showPagination?: boolean;
|
|
287
|
+
/** Accessible name of the table. @default 'Data grid' */
|
|
288
|
+
'aria-label'?: string;
|
|
289
|
+
/** `<DataGrid.Toolbar>` and anything else to render above the table. */
|
|
290
|
+
children?: ReactNode;
|
|
291
|
+
/** Merged last onto the root. */
|
|
292
|
+
className?: string;
|
|
293
|
+
/** Merged last onto the `<table>`. */
|
|
294
|
+
tableClassName?: string;
|
|
295
|
+
/** Merged last onto the scrolling wrapper around the table. */
|
|
296
|
+
scrollAreaClassName?: string;
|
|
297
|
+
}
|
|
298
|
+
interface DataGridComponent {
|
|
299
|
+
<TData>(props: DataGridProps<TData>): React.JSX.Element;
|
|
300
|
+
displayName: string;
|
|
301
|
+
Toolbar: typeof DataGridToolbar;
|
|
302
|
+
ColumnManager: typeof DataGridColumnManager;
|
|
303
|
+
SelectionBar: typeof DataGridSelectionBar;
|
|
304
|
+
Body: typeof DataGridBody;
|
|
305
|
+
Pagination: typeof DataGridPagination;
|
|
306
|
+
}
|
|
307
|
+
declare const DataGrid: DataGridComponent;
|
|
308
|
+
|
|
309
|
+
export { DEFAULT_PAGE_SIZE_OPTIONS, type DataGridAddableField, DataGridBody, type DataGridBodyProps, DataGridCellCommit, DataGridColumnManager, type DataGridColumnManagerProps, DataGridContext, DataGridDensity, type DataGridLabels, DataGridPagination, type DataGridPaginationProps, type DataGridProps, DataGridSelectionAction, DataGridSelectionBar, type DataGridSelectionBarProps, DataGridState, DataGridToolbar, type DataGridToolbarProps, EXPAND_COLUMN_ID, SELECT_COLUMN_ID, UseDataGridOptions, DataGrid as default, defaultDataGridLabels, useDataGridContext };
|