@helix-x/datagrid-ui 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1240 -63
- package/dist/index.d.ts +1240 -63
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.d.ts
CHANGED
|
@@ -2,75 +2,284 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, Ref } from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* backend
|
|
5
|
+
* Every public type in `@helix-x/datagrid-ui`.
|
|
6
|
+
*
|
|
7
|
+
* The filter, sort and row-request shapes deliberately mirror what ag-grid's
|
|
8
|
+
* server-side row model posts, so a backend written for that model accepts this
|
|
9
|
+
* grid's requests unchanged.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Comparison operators available on a `text` column filter.
|
|
14
|
+
*
|
|
15
|
+
* `blank` and `notBlank` take no operand — see {@link isUnaryFilter}.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link TEXT_FILTER_TYPES} for the same list as a runtime array.
|
|
9
18
|
*/
|
|
10
19
|
type TextFilterType = 'contains' | 'notContains' | 'equals' | 'notEqual' | 'startsWith' | 'endsWith' | 'blank' | 'notBlank';
|
|
20
|
+
/**
|
|
21
|
+
* Comparison operators available on a `number` column filter.
|
|
22
|
+
*
|
|
23
|
+
* `inRange` uses both `filter` and `filterTo`; `blank` and `notBlank` take no
|
|
24
|
+
* operand at all.
|
|
25
|
+
*
|
|
26
|
+
* @see {@link NUMBER_FILTER_TYPES} for the same list as a runtime array.
|
|
27
|
+
*/
|
|
11
28
|
type NumberFilterType = 'equals' | 'notEqual' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'inRange' | 'blank' | 'notBlank';
|
|
29
|
+
/**
|
|
30
|
+
* Comparison operators available on a `date` column filter.
|
|
31
|
+
*
|
|
32
|
+
* `inRange` uses both `dateFrom` and `dateTo`; `blank` and `notBlank` take no
|
|
33
|
+
* operand.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link DATE_FILTER_TYPES} for the same list as a runtime array.
|
|
36
|
+
*/
|
|
12
37
|
type DateFilterType = 'equals' | 'notEqual' | 'before' | 'after' | 'inRange' | 'blank' | 'notBlank';
|
|
38
|
+
/**
|
|
39
|
+
* A text filter as sent to the server.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const model: TextFilterModel = {
|
|
44
|
+
* filterType: 'text',
|
|
45
|
+
* type: 'contains',
|
|
46
|
+
* filter: 'acme',
|
|
47
|
+
* };
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
13
50
|
interface TextFilterModel {
|
|
51
|
+
/** Discriminant. Always `'text'`. */
|
|
14
52
|
filterType: 'text';
|
|
53
|
+
/** The comparison to apply. */
|
|
15
54
|
type: TextFilterType;
|
|
55
|
+
/** The search term. Absent for `blank` and `notBlank`. */
|
|
16
56
|
filter?: string;
|
|
17
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* A numeric filter as sent to the server.
|
|
60
|
+
*
|
|
61
|
+
* @example Between two values
|
|
62
|
+
* ```ts
|
|
63
|
+
* const model: NumberFilterModel = {
|
|
64
|
+
* filterType: 'number',
|
|
65
|
+
* type: 'inRange',
|
|
66
|
+
* filter: 10,
|
|
67
|
+
* filterTo: 100,
|
|
68
|
+
* };
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
18
71
|
interface NumberFilterModel {
|
|
72
|
+
/** Discriminant. Always `'number'`. */
|
|
19
73
|
filterType: 'number';
|
|
74
|
+
/** The comparison to apply. */
|
|
20
75
|
type: NumberFilterType;
|
|
76
|
+
/** The operand, or the lower bound when `type` is `'inRange'`. */
|
|
21
77
|
filter?: number;
|
|
78
|
+
/** The upper bound. Only meaningful when `type` is `'inRange'`. */
|
|
22
79
|
filterTo?: number;
|
|
23
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* A date filter as sent to the server.
|
|
83
|
+
*
|
|
84
|
+
* Dates are calendar days, not instants — compare on the day, or a same-day
|
|
85
|
+
* timestamp will never match its own date.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const model: DateFilterModel = {
|
|
90
|
+
* filterType: 'date',
|
|
91
|
+
* type: 'after',
|
|
92
|
+
* dateFrom: '2026-01-01',
|
|
93
|
+
* };
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
24
96
|
interface DateFilterModel {
|
|
97
|
+
/** Discriminant. Always `'date'`. */
|
|
25
98
|
filterType: 'date';
|
|
99
|
+
/** The comparison to apply. */
|
|
26
100
|
type: DateFilterType;
|
|
27
|
-
/** `YYYY-MM-DD
|
|
101
|
+
/** Lower bound, formatted `YYYY-MM-DD`. */
|
|
28
102
|
dateFrom?: string;
|
|
103
|
+
/** Upper bound, formatted `YYYY-MM-DD`. Only used by `'inRange'`. */
|
|
29
104
|
dateTo?: string;
|
|
30
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* A set (multi-select) filter as sent to the server.
|
|
108
|
+
*
|
|
109
|
+
* An empty `values` array means "no constraint" — that is how the grid clears
|
|
110
|
+
* a set filter. {@link buildSetFilter} returns `null` rather than an empty set.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* const model: SetFilterModel = {
|
|
115
|
+
* filterType: 'set',
|
|
116
|
+
* values: ['ACTIVE', 'PENDING'],
|
|
117
|
+
* };
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
31
120
|
interface SetFilterModel {
|
|
121
|
+
/** Discriminant. Always `'set'`. */
|
|
32
122
|
filterType: 'set';
|
|
123
|
+
/** The selected values. Compared as strings. */
|
|
33
124
|
values: string[];
|
|
34
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Any one column filter. Discriminate on `filterType`.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* function describe(filter: HxFilterModel) {
|
|
132
|
+
* switch (filter.filterType) {
|
|
133
|
+
* case 'text': return filter.filter;
|
|
134
|
+
* case 'number': return filter.filter;
|
|
135
|
+
* case 'date': return filter.dateFrom;
|
|
136
|
+
* case 'set': return filter.values.join(', ');
|
|
137
|
+
* }
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
35
141
|
type HxFilterModel = TextFilterModel | NumberFilterModel | DateFilterModel | SetFilterModel;
|
|
142
|
+
/**
|
|
143
|
+
* Every active filter, keyed by {@link ColumnDef.colId | column id}.
|
|
144
|
+
*
|
|
145
|
+
* A column with no entry is unfiltered. Use {@link withFilter} to add or remove
|
|
146
|
+
* one immutably.
|
|
147
|
+
*/
|
|
36
148
|
type FilterModelMap = Record<string, HxFilterModel>;
|
|
149
|
+
/**
|
|
150
|
+
* Which filter UI a column offers, set via {@link ColumnDef.filter}.
|
|
151
|
+
*
|
|
152
|
+
* Pass `false` on the column instead to disable filtering entirely.
|
|
153
|
+
*/
|
|
37
154
|
type FilterKind = 'text' | 'number' | 'date' | 'set';
|
|
155
|
+
/** Sort direction for one column. */
|
|
38
156
|
type SortDirection = 'asc' | 'desc';
|
|
157
|
+
/**
|
|
158
|
+
* One entry in the sort model.
|
|
159
|
+
*
|
|
160
|
+
* The model is an ordered array: the first entry is the primary sort, and later
|
|
161
|
+
* entries break ties in the ones before them.
|
|
162
|
+
*
|
|
163
|
+
* @example Sort by status, then by newest first
|
|
164
|
+
* ```ts
|
|
165
|
+
* const sortModel: SortModelItem[] = [
|
|
166
|
+
* { colId: 'status', sort: 'asc' },
|
|
167
|
+
* { colId: 'createdAt', sort: 'desc' },
|
|
168
|
+
* ];
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
39
171
|
interface SortModelItem {
|
|
172
|
+
/** The {@link ColumnDef.colId | column id} to sort on. */
|
|
40
173
|
colId: string;
|
|
174
|
+
/** Direction to sort in. */
|
|
41
175
|
sort: SortDirection;
|
|
42
176
|
}
|
|
43
177
|
/**
|
|
178
|
+
* What the grid asks the server for: one page, with the active sort and
|
|
179
|
+
* filters.
|
|
180
|
+
*
|
|
44
181
|
* Structurally compatible with ag-grid's `IServerSideGetRowsRequest`, so an
|
|
45
|
-
* endpoint written for that model accepts this verbatim. The grouping
|
|
182
|
+
* endpoint written for that model accepts this verbatim. The grouping and pivot
|
|
46
183
|
* fields are always sent empty — this grid does not implement them — but they
|
|
47
184
|
* are present so servers that destructure them do not fall over.
|
|
185
|
+
*
|
|
186
|
+
* @example Handling the request on the server
|
|
187
|
+
* ```ts
|
|
188
|
+
* app.post('/api/rows', (req, res) => {
|
|
189
|
+
* const { startRow, endRow, sortModel, filterModel } = req.body;
|
|
190
|
+
* const filtered = applyFilters(allRows, filterModel);
|
|
191
|
+
* const sorted = applySort(filtered, sortModel);
|
|
192
|
+
* res.json({ rows: sorted.slice(startRow, endRow), lastRow: filtered.length });
|
|
193
|
+
* });
|
|
194
|
+
* ```
|
|
48
195
|
*/
|
|
49
196
|
interface HxRowsRequest {
|
|
197
|
+
/** Zero-based index of the first row wanted, inclusive. */
|
|
50
198
|
startRow: number;
|
|
199
|
+
/** Index one past the last row wanted, exclusive. */
|
|
51
200
|
endRow: number;
|
|
201
|
+
/** Active sorts, primary first. Empty when unsorted. */
|
|
52
202
|
sortModel: SortModelItem[];
|
|
203
|
+
/** Active filters, keyed by column id. Empty when unfiltered. */
|
|
53
204
|
filterModel: FilterModelMap;
|
|
205
|
+
/** Always empty. Present only for ag-grid wire compatibility. */
|
|
54
206
|
rowGroupCols: never[];
|
|
207
|
+
/** Always empty. Present only for ag-grid wire compatibility. */
|
|
55
208
|
valueCols: never[];
|
|
209
|
+
/** Always empty. Present only for ag-grid wire compatibility. */
|
|
56
210
|
pivotCols: never[];
|
|
211
|
+
/** Always `false`. Present only for ag-grid wire compatibility. */
|
|
57
212
|
pivotMode: false;
|
|
213
|
+
/** Always empty. Present only for ag-grid wire compatibility. */
|
|
58
214
|
groupKeys: never[];
|
|
59
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* What the server returns for one {@link HxRowsRequest}.
|
|
218
|
+
*
|
|
219
|
+
* @typeParam T - The row type.
|
|
220
|
+
*/
|
|
60
221
|
interface HxRowsResponse<T> {
|
|
222
|
+
/** The rows for the requested page only, not the whole result set. */
|
|
61
223
|
rows: T[];
|
|
62
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* Total row count across **all** pages — not `rows.length`. This is what
|
|
226
|
+
* drives the pager. Return `-1` when the total is genuinely unknown.
|
|
227
|
+
*/
|
|
63
228
|
lastRow: number;
|
|
64
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* The grid's one required dependency: something that turns a request into rows.
|
|
232
|
+
*
|
|
233
|
+
* @typeParam T - The row type.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```tsx
|
|
237
|
+
* const dataSource: HxDataSource<Person> = {
|
|
238
|
+
* getRows: async (request, signal) => {
|
|
239
|
+
* const response = await fetch('/api/people', {
|
|
240
|
+
* method: 'POST',
|
|
241
|
+
* headers: { 'content-type': 'application/json' },
|
|
242
|
+
* body: JSON.stringify(request),
|
|
243
|
+
* signal,
|
|
244
|
+
* });
|
|
245
|
+
* return response.json();
|
|
246
|
+
* },
|
|
247
|
+
* };
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
250
|
+
* @remarks
|
|
251
|
+
* Memoise the object (or define it outside the component). A new identity on
|
|
252
|
+
* every render causes a refetch.
|
|
253
|
+
*/
|
|
65
254
|
interface HxDataSource<T> {
|
|
255
|
+
/**
|
|
256
|
+
* Fetch one page of rows.
|
|
257
|
+
*
|
|
258
|
+
* @param request - The page, sort and filters being asked for.
|
|
259
|
+
* @param signal - Aborts when the grid supersedes this request. Pass it to
|
|
260
|
+
* `fetch` so a slow response for an old sort can never overwrite a newer one.
|
|
261
|
+
* @returns The page of rows plus the total row count.
|
|
262
|
+
*/
|
|
66
263
|
getRows(request: HxRowsRequest, signal: AbortSignal): Promise<HxRowsResponse<T>>;
|
|
67
264
|
}
|
|
265
|
+
/** Which edge a pinned column sticks to. */
|
|
68
266
|
type Pinned = 'left' | 'right';
|
|
267
|
+
/**
|
|
268
|
+
* What {@link ColumnDef.cellRenderer} receives.
|
|
269
|
+
*
|
|
270
|
+
* @typeParam T - The row type.
|
|
271
|
+
* @typeParam C - The {@link DataGridProps.context | context} type.
|
|
272
|
+
*/
|
|
69
273
|
interface CellRendererParams<T, C = unknown> {
|
|
274
|
+
/** The whole row, for cells that need more than their own field. */
|
|
70
275
|
row: T;
|
|
276
|
+
/** Index within the currently loaded page, not the full result set. */
|
|
71
277
|
rowIndex: number;
|
|
278
|
+
/** The raw value, after {@link ColumnDef.valueGetter}. */
|
|
72
279
|
value: unknown;
|
|
280
|
+
/** The display string, after {@link ColumnDef.valueFormatter}. */
|
|
73
281
|
formatted: string;
|
|
282
|
+
/** The column being rendered. */
|
|
74
283
|
column: ColumnDef<T, C>;
|
|
75
284
|
/**
|
|
76
285
|
* Arbitrary app state handed to every renderer. Put volatile things here
|
|
@@ -78,425 +287,1393 @@ interface CellRendererParams<T, C = unknown> {
|
|
|
78
287
|
* memoised on `[]` and never rebuild.
|
|
79
288
|
*/
|
|
80
289
|
context: C;
|
|
290
|
+
/** The live imperative API, for renderers that act on the grid. */
|
|
81
291
|
api: GridApi<T>;
|
|
82
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* What a cell editor receives — both the built-ins and your own.
|
|
295
|
+
*
|
|
296
|
+
* @typeParam T - The row type.
|
|
297
|
+
* @typeParam C - The {@link DataGridProps.context | context} type.
|
|
298
|
+
*/
|
|
83
299
|
interface EditorParams<T, C = unknown> {
|
|
300
|
+
/** Current draft value for this cell. */
|
|
84
301
|
value: unknown;
|
|
302
|
+
/** The row being edited, as a draft copy. */
|
|
85
303
|
row: T;
|
|
304
|
+
/** The column being edited. */
|
|
86
305
|
column: ColumnDef<T, C>;
|
|
306
|
+
/** The grid's {@link DataGridProps.context | context}. */
|
|
87
307
|
context: C;
|
|
88
308
|
/** Writes into the row draft. Never hits the network. */
|
|
89
309
|
onChange: (value: unknown) => void;
|
|
90
|
-
/** Commit the whole row. */
|
|
310
|
+
/** Commit the whole row, invoking {@link DataGridProps.onRowCommit}. */
|
|
91
311
|
onCommit: () => void;
|
|
312
|
+
/** Abandon the edit and restore the original row. */
|
|
92
313
|
onCancel: () => void;
|
|
314
|
+
/** Server-supplied message for this field, if the last commit was rejected. */
|
|
93
315
|
error?: string;
|
|
316
|
+
/** True for the first editable cell in the row. */
|
|
94
317
|
autoFocus?: boolean;
|
|
95
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* A custom cell editor.
|
|
321
|
+
*
|
|
322
|
+
* @typeParam T - The row type.
|
|
323
|
+
* @typeParam C - The context type.
|
|
324
|
+
*
|
|
325
|
+
* @example A trimming text editor
|
|
326
|
+
* ```tsx
|
|
327
|
+
* const TrimmedEditor: EditorComponent<Person> = ({ value, onChange, onCommit, onCancel }) => (
|
|
328
|
+
* <input
|
|
329
|
+
* autoFocus
|
|
330
|
+
* value={String(value ?? '')}
|
|
331
|
+
* onChange={(e) => onChange(e.target.value.trim())}
|
|
332
|
+
* onKeyDown={(e) => {
|
|
333
|
+
* if (e.key === 'Enter') onCommit();
|
|
334
|
+
* if (e.key === 'Escape') onCancel();
|
|
335
|
+
* }}
|
|
336
|
+
* />
|
|
337
|
+
* );
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
96
340
|
type EditorComponent<T, C = unknown> = (params: EditorParams<T, C>) => ReactNode;
|
|
341
|
+
/**
|
|
342
|
+
* Names of the editors that ship with the grid.
|
|
343
|
+
*
|
|
344
|
+
* @see {@link BUILTIN_EDITORS} for the components these map to.
|
|
345
|
+
*/
|
|
97
346
|
type BuiltinEditor = 'text' | 'number' | 'select' | 'date' | 'checkbox';
|
|
347
|
+
/** One choice offered by the `select` editor. */
|
|
98
348
|
interface SelectOption {
|
|
349
|
+
/** Shown to the user. */
|
|
99
350
|
label: string;
|
|
351
|
+
/** Written into the row draft. */
|
|
100
352
|
value: unknown;
|
|
101
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* One column. This is the main thing you write when using the grid.
|
|
356
|
+
*
|
|
357
|
+
* @typeParam T - The row type.
|
|
358
|
+
* @typeParam C - The {@link DataGridProps.context | context} type.
|
|
359
|
+
*
|
|
360
|
+
* @example A representative set of columns
|
|
361
|
+
* ```tsx
|
|
362
|
+
* const columns: ColumnDef<Person>[] = [
|
|
363
|
+
* { field: 'id', header: 'ID', width: 90, filter: 'number' },
|
|
364
|
+
* { field: 'name', header: 'Name', flex: 1, filter: 'text', editable: true },
|
|
365
|
+
* {
|
|
366
|
+
* field: 'status',
|
|
367
|
+
* header: 'Status',
|
|
368
|
+
* filter: 'set',
|
|
369
|
+
* filterParams: { values: () => fetch('/api/statuses').then((r) => r.json()) },
|
|
370
|
+
* editable: true,
|
|
371
|
+
* editor: 'select',
|
|
372
|
+
* editorParams: { options: [{ label: 'Active', value: 'ACTIVE' }] },
|
|
373
|
+
* },
|
|
374
|
+
* {
|
|
375
|
+
* colId: 'fullName',
|
|
376
|
+
* header: 'Full name',
|
|
377
|
+
* sortable: false,
|
|
378
|
+
* valueGetter: (row) => `${row.first} ${row.last}`,
|
|
379
|
+
* },
|
|
380
|
+
* ];
|
|
381
|
+
* ```
|
|
382
|
+
*
|
|
383
|
+
* @remarks
|
|
384
|
+
* Define columns as a module constant or memoise on `[]`. Anything volatile
|
|
385
|
+
* belongs in {@link DataGridProps.context} instead, which reaches every
|
|
386
|
+
* renderer without rebuilding a single definition.
|
|
387
|
+
*/
|
|
102
388
|
interface ColumnDef<T, C = unknown> {
|
|
103
|
-
/**
|
|
389
|
+
/**
|
|
390
|
+
* Stable identity, used as the key in the sort and filter models and in
|
|
391
|
+
* persisted layout. Falls back to {@link ColumnDef.field | field} when
|
|
392
|
+
* omitted; one of the two is required.
|
|
393
|
+
*/
|
|
104
394
|
colId?: string;
|
|
105
|
-
/**
|
|
395
|
+
/**
|
|
396
|
+
* Dotted path into the row (`'customer.name'`), and the key sent to the
|
|
397
|
+
* server for sorting and filtering.
|
|
398
|
+
*
|
|
399
|
+
* Omit it for purely derived columns and supply `colId` plus
|
|
400
|
+
* {@link ColumnDef.valueGetter | valueGetter} instead.
|
|
401
|
+
*/
|
|
106
402
|
field?: string;
|
|
403
|
+
/** Header content. Any node — an icon, a tooltip wrapper, anything. */
|
|
107
404
|
header: ReactNode;
|
|
108
|
-
/**
|
|
405
|
+
/**
|
|
406
|
+
* Plain-text header for exports and aria labels. Required in practice
|
|
407
|
+
* whenever `header` is a node rather than a string.
|
|
408
|
+
*/
|
|
109
409
|
headerName?: string;
|
|
410
|
+
/**
|
|
411
|
+
* Starting width in pixels.
|
|
412
|
+
* @defaultValue 150
|
|
413
|
+
*/
|
|
110
414
|
width?: number;
|
|
415
|
+
/**
|
|
416
|
+
* Floor for both `flex` and user resizing.
|
|
417
|
+
* @defaultValue 60
|
|
418
|
+
*/
|
|
111
419
|
minWidth?: number;
|
|
420
|
+
/** Ceiling for user resizing. */
|
|
112
421
|
maxWidth?: number;
|
|
113
|
-
/**
|
|
422
|
+
/**
|
|
423
|
+
* Share of the leftover horizontal space, like `flex-grow`. A column with
|
|
424
|
+
* `flex: 2` takes twice the slack of one with `flex: 1`.
|
|
425
|
+
*/
|
|
114
426
|
flex?: number;
|
|
427
|
+
/** Stick this column to an edge while the rest scroll horizontally. */
|
|
115
428
|
pinned?: Pinned;
|
|
429
|
+
/** Start hidden. The user can still reveal it from the columns panel. */
|
|
116
430
|
hide?: boolean;
|
|
431
|
+
/**
|
|
432
|
+
* Allow click-to-sort on the header.
|
|
433
|
+
* @defaultValue true
|
|
434
|
+
*/
|
|
117
435
|
sortable?: boolean;
|
|
436
|
+
/**
|
|
437
|
+
* Allow drag-to-resize.
|
|
438
|
+
* @defaultValue true
|
|
439
|
+
*/
|
|
118
440
|
resizable?: boolean;
|
|
119
441
|
/** Prevent the user dragging this column out of position. */
|
|
120
442
|
lockPosition?: boolean;
|
|
443
|
+
/**
|
|
444
|
+
* Which filter UI to offer, or `false` for none.
|
|
445
|
+
*
|
|
446
|
+
* @defaultValue undefined (no filter)
|
|
447
|
+
*/
|
|
121
448
|
filter?: FilterKind | false;
|
|
449
|
+
/** Extra options for the filter named by {@link ColumnDef.filter}. */
|
|
122
450
|
filterParams?: {
|
|
123
|
-
/**
|
|
451
|
+
/**
|
|
452
|
+
* Options for a `set` filter: a static list, or a function called the first
|
|
453
|
+
* time the popover opens so the list can come from an API.
|
|
454
|
+
*/
|
|
124
455
|
values?: string[] | (() => Promise<string[]>);
|
|
125
456
|
/** Hide the always-visible filter input under the header for this column. */
|
|
126
457
|
suppressFloatingFilter?: boolean;
|
|
127
458
|
};
|
|
128
|
-
/**
|
|
459
|
+
/**
|
|
460
|
+
* Alternative flat keys to try when the server flattens nested fields — some
|
|
461
|
+
* backends return `{"customer.name": x}` rather than a nested object, and
|
|
462
|
+
* change the prefix when grouping is on.
|
|
463
|
+
*/
|
|
129
464
|
fieldAliases?: string[];
|
|
465
|
+
/**
|
|
466
|
+
* Compute the cell value instead of reading `field`. Takes precedence over
|
|
467
|
+
* every other lookup.
|
|
468
|
+
*/
|
|
130
469
|
valueGetter?: (row: T) => unknown;
|
|
470
|
+
/**
|
|
471
|
+
* Turn the raw value into its display string. Also used for exports unless
|
|
472
|
+
* {@link ColumnDef.exportValue} is given.
|
|
473
|
+
*/
|
|
131
474
|
valueFormatter?: (value: unknown, row: T) => string;
|
|
475
|
+
/**
|
|
476
|
+
* Render the cell as markup. Presentation only — sorting and filtering still
|
|
477
|
+
* use `field`, so a decorated cell keeps behaving like a plain one.
|
|
478
|
+
*/
|
|
132
479
|
cellRenderer?: (params: CellRendererParams<T, C>) => ReactNode;
|
|
480
|
+
/** Whether the cell can be edited, optionally per row. */
|
|
133
481
|
editable?: boolean | ((row: T) => boolean);
|
|
482
|
+
/**
|
|
483
|
+
* Which editor to use: a {@link BuiltinEditor} name or your own component.
|
|
484
|
+
* @defaultValue 'text'
|
|
485
|
+
*/
|
|
134
486
|
editor?: BuiltinEditor | EditorComponent<T, C>;
|
|
487
|
+
/** Extra options for the editor named by {@link ColumnDef.editor}. */
|
|
135
488
|
editorParams?: {
|
|
489
|
+
/** Choices for the `select` editor. */
|
|
136
490
|
options?: SelectOption[];
|
|
491
|
+
/** Placeholder for the `text` and `number` editors. */
|
|
137
492
|
placeholder?: string;
|
|
138
493
|
};
|
|
494
|
+
/**
|
|
495
|
+
* The flat string written to CSV and the clipboard. Supply this whenever
|
|
496
|
+
* {@link ColumnDef.cellRenderer} produces markup.
|
|
497
|
+
*/
|
|
139
498
|
exportValue?: (row: T) => string;
|
|
499
|
+
/** Leave this column out of CSV and clipboard output entirely. */
|
|
140
500
|
suppressExport?: boolean;
|
|
501
|
+
/** Extra classes on every cell, optionally per row. */
|
|
141
502
|
cellClassName?: string | ((row: T) => string);
|
|
503
|
+
/** Extra classes on the header cell. */
|
|
142
504
|
headerClassName?: string;
|
|
143
|
-
/**
|
|
505
|
+
/**
|
|
506
|
+
* Horizontal alignment of the cell content.
|
|
507
|
+
* @defaultValue 'left'
|
|
508
|
+
*/
|
|
144
509
|
align?: 'left' | 'center' | 'right';
|
|
145
510
|
}
|
|
146
|
-
/**
|
|
511
|
+
/**
|
|
512
|
+
* A {@link ColumnDef} with every optional default filled in.
|
|
513
|
+
*
|
|
514
|
+
* Produced by {@link resolveColumn}. Mostly internal, but exported because the
|
|
515
|
+
* exporter helpers and the columns panel take it.
|
|
516
|
+
*
|
|
517
|
+
* @typeParam T - The row type.
|
|
518
|
+
* @typeParam C - The context type.
|
|
519
|
+
*/
|
|
147
520
|
interface ResolvedColumn<T, C = unknown> extends ColumnDef<T, C> {
|
|
521
|
+
/** Always present — `colId`, or `field` when `colId` was omitted. */
|
|
148
522
|
colId: string;
|
|
523
|
+
/** Resolved width, never below `minWidth`. */
|
|
149
524
|
width: number;
|
|
525
|
+
/** Resolved minimum width. */
|
|
150
526
|
minWidth: number;
|
|
527
|
+
/** Resolved sortability. */
|
|
151
528
|
sortable: boolean;
|
|
529
|
+
/** Resolved resizability. */
|
|
152
530
|
resizable: boolean;
|
|
153
531
|
}
|
|
154
|
-
/**
|
|
532
|
+
/**
|
|
533
|
+
* Geometry for one visible column, computed once per layout change.
|
|
534
|
+
*
|
|
535
|
+
* @typeParam T - The row type.
|
|
536
|
+
* @typeParam C - The context type.
|
|
537
|
+
*/
|
|
155
538
|
interface ColumnLayoutItem<T, C = unknown> {
|
|
539
|
+
/** The column this geometry belongs to. */
|
|
156
540
|
column: ResolvedColumn<T, C>;
|
|
541
|
+
/** Convenience copy of `column.colId`. */
|
|
157
542
|
colId: string;
|
|
543
|
+
/** Final pixel width, after `flex` distribution and user resizing. */
|
|
158
544
|
width: number;
|
|
159
545
|
/** Offset from the left edge of the full (unscrolled) column strip. */
|
|
160
546
|
left: number;
|
|
547
|
+
/** Which edge this column is pinned to, if any. */
|
|
161
548
|
pinned?: Pinned;
|
|
162
549
|
/** `left`/`right` offset to use for `position: sticky` on pinned columns. */
|
|
163
550
|
stickyOffset: number;
|
|
164
551
|
}
|
|
552
|
+
/**
|
|
553
|
+
* The measured layout of every visible column.
|
|
554
|
+
*
|
|
555
|
+
* @typeParam T - The row type.
|
|
556
|
+
* @typeParam C - The context type.
|
|
557
|
+
*/
|
|
165
558
|
interface ColumnLayout<T, C = unknown> {
|
|
559
|
+
/** Visible columns in display order, each with its geometry. */
|
|
166
560
|
items: ColumnLayoutItem<T, C>[];
|
|
561
|
+
/** Combined width of all visible columns. */
|
|
167
562
|
totalWidth: number;
|
|
563
|
+
/** Combined width of the left-pinned columns. */
|
|
168
564
|
leftPinnedWidth: number;
|
|
565
|
+
/** Combined width of the right-pinned columns. */
|
|
169
566
|
rightPinnedWidth: number;
|
|
170
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* The outcome of {@link DataGridProps.onRowCommit}.
|
|
570
|
+
*
|
|
571
|
+
* Returning `ok: false` keeps the row in edit mode and paints each message onto
|
|
572
|
+
* the cell whose column id it is keyed by — which is how server-side validation
|
|
573
|
+
* reaches the user without being mirrored in the client.
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```ts
|
|
577
|
+
* async function onRowCommit(draft: Person): Promise<RowCommitResult> {
|
|
578
|
+
* const response = await fetch(`/api/people/${draft.id}`, {
|
|
579
|
+
* method: 'PATCH',
|
|
580
|
+
* body: JSON.stringify(draft),
|
|
581
|
+
* });
|
|
582
|
+
* if (response.status === 422) {
|
|
583
|
+
* const { errors, message } = await response.json();
|
|
584
|
+
* return { ok: false, errors, message };
|
|
585
|
+
* }
|
|
586
|
+
* return { ok: true, row: await response.json() };
|
|
587
|
+
* }
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
171
590
|
type RowCommitResult = {
|
|
591
|
+
/** Discriminant: the row was saved. */
|
|
172
592
|
ok: true;
|
|
593
|
+
/**
|
|
594
|
+
* The server's canonical copy, which replaces the row in place. Useful
|
|
595
|
+
* when the server fills in derived fields.
|
|
596
|
+
*/
|
|
173
597
|
row?: unknown;
|
|
174
598
|
} | {
|
|
599
|
+
/** Discriminant: the row was rejected and stays open. */
|
|
175
600
|
ok: false;
|
|
601
|
+
/** Messages keyed by column id, painted onto the offending cells. */
|
|
176
602
|
errors: Record<string, string>;
|
|
603
|
+
/** A single message for the whole row. */
|
|
177
604
|
message?: string;
|
|
178
605
|
};
|
|
606
|
+
/**
|
|
607
|
+
* Schema version for {@link PersistedGridState}.
|
|
608
|
+
*
|
|
609
|
+
* Saved state carrying a different version is discarded rather than migrated:
|
|
610
|
+
* the layout is a convenience, and a bad restore is worse than starting from
|
|
611
|
+
* the column defaults.
|
|
612
|
+
*/
|
|
179
613
|
declare const GRID_STATE_VERSION = 1;
|
|
614
|
+
/**
|
|
615
|
+
* What the grid writes to `localStorage` under
|
|
616
|
+
* {@link DataGridProps.storageKey}.
|
|
617
|
+
*
|
|
618
|
+
* Stored under the key `hxg:<storageKey>`.
|
|
619
|
+
*/
|
|
180
620
|
interface PersistedGridState {
|
|
621
|
+
/** Schema version. Compared against {@link GRID_STATE_VERSION} on read. */
|
|
181
622
|
v: number;
|
|
623
|
+
/** Column layout the user arranged. */
|
|
182
624
|
columns: {
|
|
625
|
+
/** Column ids in display order. */
|
|
183
626
|
order: string[];
|
|
627
|
+
/** Ids of columns the user hid. */
|
|
184
628
|
hidden: string[];
|
|
629
|
+
/** User-resized widths, by column id. */
|
|
185
630
|
widths: Record<string, number>;
|
|
631
|
+
/** User-pinned columns, by column id. */
|
|
186
632
|
pinned: Record<string, Pinned>;
|
|
187
633
|
};
|
|
634
|
+
/** The sort model at the time of saving. */
|
|
188
635
|
sort: SortModelItem[];
|
|
636
|
+
/** The filter model at the time of saving. */
|
|
189
637
|
filters: FilterModelMap;
|
|
638
|
+
/** Paging preferences. */
|
|
190
639
|
pagination: {
|
|
640
|
+
/** Rows per page the user chose. */
|
|
191
641
|
pageSize: number;
|
|
192
642
|
};
|
|
193
643
|
}
|
|
644
|
+
/** Options for {@link GridApi.exportCsv}. */
|
|
194
645
|
interface ExportCsvOptions {
|
|
646
|
+
/**
|
|
647
|
+
* Export only the selected rows rather than the whole loaded page.
|
|
648
|
+
* @defaultValue false
|
|
649
|
+
*/
|
|
195
650
|
onlySelected?: boolean;
|
|
651
|
+
/**
|
|
652
|
+
* File name, with or without the `.csv` suffix.
|
|
653
|
+
* @defaultValue the grid's `exportFileName` prop
|
|
654
|
+
*/
|
|
196
655
|
fileName?: string;
|
|
197
|
-
/**
|
|
656
|
+
/**
|
|
657
|
+
* Field separator.
|
|
658
|
+
* @defaultValue ','
|
|
659
|
+
*/
|
|
198
660
|
separator?: string;
|
|
199
661
|
}
|
|
662
|
+
/**
|
|
663
|
+
* The imperative handle onto a live grid.
|
|
664
|
+
*
|
|
665
|
+
* Reach it either through {@link DataGridProps.apiRef} or as
|
|
666
|
+
* {@link DataGridProps.toolbar}'s argument.
|
|
667
|
+
*
|
|
668
|
+
* @typeParam T - The row type.
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```tsx
|
|
672
|
+
* const apiRef = useRef<GridApi<Person>>(null);
|
|
673
|
+
*
|
|
674
|
+
* <DataGrid
|
|
675
|
+
* apiRef={apiRef}
|
|
676
|
+
* toolbar={(api) => (
|
|
677
|
+
* <button onClick={() => api.exportCsv({ onlySelected: true })}>
|
|
678
|
+
* Export selection
|
|
679
|
+
* </button>
|
|
680
|
+
* )}
|
|
681
|
+
* {...rest}
|
|
682
|
+
* />
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
200
685
|
interface GridApi<T> {
|
|
201
|
-
/**
|
|
686
|
+
/**
|
|
687
|
+
* Re-fetch the current page.
|
|
688
|
+
*
|
|
689
|
+
* @param options - `purge: true` drops every cached block first, so nothing
|
|
690
|
+
* stale can survive; otherwise cached neighbouring pages are kept.
|
|
691
|
+
*/
|
|
202
692
|
refresh(options?: {
|
|
203
693
|
purge?: boolean;
|
|
204
694
|
}): void;
|
|
695
|
+
/** The rows currently loaded for this page, in display order. */
|
|
205
696
|
getDisplayedRows(): T[];
|
|
697
|
+
/** The selected rows that are on the current page. */
|
|
206
698
|
getSelectedRows(): T[];
|
|
699
|
+
/** Ids of every selected row, including those on other pages. */
|
|
207
700
|
getSelectedIds(): Array<string | number>;
|
|
701
|
+
/** Deselect everything. */
|
|
208
702
|
clearSelection(): void;
|
|
703
|
+
/** Select every row on the current page. */
|
|
209
704
|
selectAll(): void;
|
|
705
|
+
/** Download the rows as CSV, honouring each column's `exportValue`. */
|
|
210
706
|
exportCsv(options?: ExportCsvOptions): void;
|
|
707
|
+
/** Copy the selection to the clipboard as TSV, which spreadsheets expect. */
|
|
211
708
|
copySelectionToClipboard(): Promise<void>;
|
|
709
|
+
/** The active filters. */
|
|
212
710
|
getFilterModel(): FilterModelMap;
|
|
711
|
+
/** Replace every filter at once, triggering one refetch. */
|
|
213
712
|
setFilterModel(model: FilterModelMap): void;
|
|
713
|
+
/** The active sorts, primary first. */
|
|
214
714
|
getSortModel(): SortModelItem[];
|
|
715
|
+
/** Replace the sort model, triggering one refetch. */
|
|
215
716
|
setSortModel(model: SortModelItem[]): void;
|
|
717
|
+
/** Discard the user's column layout and return to the definitions' defaults. */
|
|
216
718
|
resetColumns(): void;
|
|
217
|
-
/**
|
|
719
|
+
/**
|
|
720
|
+
* Patch rows already on screen, matched by `getRowId`, without a round trip.
|
|
721
|
+
*
|
|
722
|
+
* Ids that are not on the current page are ignored, so a live feed can push
|
|
723
|
+
* everything it has without the client filtering first. Scroll position,
|
|
724
|
+
* selection, sort and any open editor are all preserved.
|
|
725
|
+
*
|
|
726
|
+
* @param rows - Whole replacement rows, not partials.
|
|
727
|
+
*/
|
|
218
728
|
updateRows(rows: T[]): void;
|
|
729
|
+
/**
|
|
730
|
+
* Open the row editor programmatically.
|
|
731
|
+
* @param rowId - The id, as returned by `getRowId`.
|
|
732
|
+
*/
|
|
219
733
|
startEditing(rowId: string | number): void;
|
|
734
|
+
/** Close the editor, abandoning any uncommitted draft. */
|
|
220
735
|
stopEditing(): void;
|
|
221
736
|
}
|
|
222
737
|
|
|
738
|
+
/**
|
|
739
|
+
* A row's stable identity, as returned by `getRowId`.
|
|
740
|
+
*
|
|
741
|
+
* Selection, editing and {@link GridApi.updateRows} all key off this.
|
|
742
|
+
*/
|
|
223
743
|
type RowId = string | number;
|
|
744
|
+
/**
|
|
745
|
+
* What {@link useSelectionModel} returns.
|
|
746
|
+
*
|
|
747
|
+
* @typeParam T - The row type.
|
|
748
|
+
*/
|
|
224
749
|
interface UseSelectionModelResult<T> {
|
|
750
|
+
/** Every selected id, including rows on pages that are not loaded. */
|
|
225
751
|
selectedIds: Set<RowId>;
|
|
752
|
+
/** Whether one id is selected. */
|
|
226
753
|
isSelected: (id: RowId) => boolean;
|
|
227
754
|
/** True when every row currently on screen is selected. */
|
|
228
755
|
allVisibleSelected: boolean;
|
|
756
|
+
/** True when some, but not all, visible rows are selected. */
|
|
229
757
|
someVisibleSelected: boolean;
|
|
758
|
+
/**
|
|
759
|
+
* Toggle one row.
|
|
760
|
+
* @param id - The row to toggle.
|
|
761
|
+
* @param index - Its index in the loaded page, used as the shift anchor.
|
|
762
|
+
* @param shiftKey - Extend from the last toggled row instead of toggling one.
|
|
763
|
+
*/
|
|
230
764
|
toggleRow: (id: RowId, index: number, shiftKey: boolean) => void;
|
|
765
|
+
/** Select every visible row, or deselect them if all are already selected. */
|
|
231
766
|
toggleAllVisible: () => void;
|
|
767
|
+
/** Deselect everything, including rows on other pages. */
|
|
232
768
|
clear: () => void;
|
|
769
|
+
/** Select every row on the current page. */
|
|
233
770
|
selectAllVisible: () => void;
|
|
771
|
+
/** The selected rows that are currently loaded. */
|
|
234
772
|
getSelectedRows: () => T[];
|
|
235
773
|
}
|
|
236
774
|
/**
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
775
|
+
* Multi-row selection with shift-range support.
|
|
776
|
+
*
|
|
777
|
+
* Selection survives paging: ids stay selected even when their rows are not
|
|
778
|
+
* loaded, which is why `getSelectedRows` returns only the loaded subset while
|
|
779
|
+
* `selectedIds` holds everything.
|
|
780
|
+
*
|
|
781
|
+
* @typeParam T - The row type.
|
|
782
|
+
* @param rows - The currently loaded page.
|
|
783
|
+
* @param getRowId - Stable identity for a row.
|
|
784
|
+
* @param onSelectionChanged - Called with every selected id after each change.
|
|
785
|
+
* @returns The selection state and its mutators.
|
|
240
786
|
*/
|
|
241
787
|
declare function useSelectionModel<T>(rows: T[], getRowId: (row: T) => RowId, onSelectionChanged?: (ids: RowId[]) => void): UseSelectionModelResult<T>;
|
|
242
788
|
|
|
789
|
+
/**
|
|
790
|
+
* Props for {@link DataGrid}.
|
|
791
|
+
*
|
|
792
|
+
* @typeParam T - The row type.
|
|
793
|
+
* @typeParam C - The {@link DataGridProps.context | context} type. Inferred
|
|
794
|
+
* from `context`; defaults to `unknown`.
|
|
795
|
+
*/
|
|
243
796
|
interface DataGridProps<T, C = unknown> {
|
|
797
|
+
/**
|
|
798
|
+
* The columns to render.
|
|
799
|
+
*
|
|
800
|
+
* @remarks
|
|
801
|
+
* Define these as a module constant or memoise on `[]` — anything volatile
|
|
802
|
+
* belongs in {@link DataGridProps.context} instead.
|
|
803
|
+
*/
|
|
244
804
|
columns: ColumnDef<T, C>[];
|
|
805
|
+
/**
|
|
806
|
+
* Where rows come from. Memoise it; a new identity causes a refetch.
|
|
807
|
+
*
|
|
808
|
+
* @see {@link HxDataSource}
|
|
809
|
+
*/
|
|
245
810
|
dataSource: HxDataSource<T>;
|
|
811
|
+
/**
|
|
812
|
+
* Stable identity for a row, used for selection, editing and
|
|
813
|
+
* {@link GridApi.updateRows}. Must be stable across refetches.
|
|
814
|
+
*/
|
|
246
815
|
getRowId: (row: T) => RowId;
|
|
247
|
-
/**
|
|
816
|
+
/**
|
|
817
|
+
* Volatile app state handed to every cell renderer.
|
|
818
|
+
*
|
|
819
|
+
* This is the escape hatch that keeps `columns` static: put in-flight ids,
|
|
820
|
+
* permission checks and event handlers here, and changing them re-renders
|
|
821
|
+
* cells without rebuilding a single column definition.
|
|
822
|
+
*/
|
|
248
823
|
context?: C;
|
|
249
|
-
/**
|
|
824
|
+
/**
|
|
825
|
+
* `localStorage` key for column layout, sort, filters and page size.
|
|
826
|
+
*
|
|
827
|
+
* Omit it and nothing is persisted. Stored under `hxg:<storageKey>`.
|
|
828
|
+
*
|
|
829
|
+
* @see {@link PersistedGridState}
|
|
830
|
+
*/
|
|
250
831
|
storageKey?: string;
|
|
832
|
+
/**
|
|
833
|
+
* Row height in pixels. Fixed for every row — that is what keeps
|
|
834
|
+
* virtualization O(1).
|
|
835
|
+
* @defaultValue 36
|
|
836
|
+
*/
|
|
251
837
|
rowHeight?: number;
|
|
838
|
+
/**
|
|
839
|
+
* Header height in pixels.
|
|
840
|
+
* @defaultValue 36
|
|
841
|
+
*/
|
|
252
842
|
headerHeight?: number;
|
|
253
|
-
/**
|
|
843
|
+
/**
|
|
844
|
+
* Show the always-visible filter inputs under the header.
|
|
845
|
+
* @defaultValue true
|
|
846
|
+
*/
|
|
254
847
|
floatingFilter?: boolean;
|
|
848
|
+
/**
|
|
849
|
+
* Show the checkbox selection column.
|
|
850
|
+
* @defaultValue true
|
|
851
|
+
*/
|
|
255
852
|
selectable?: boolean;
|
|
853
|
+
/**
|
|
854
|
+
* Rows per page before the user changes it. A persisted preference wins.
|
|
855
|
+
* @defaultValue 20
|
|
856
|
+
*/
|
|
256
857
|
defaultPageSize?: number;
|
|
858
|
+
/**
|
|
859
|
+
* Page sizes offered in the pager.
|
|
860
|
+
* @defaultValue [10, 20, 50, 100]
|
|
861
|
+
*/
|
|
257
862
|
pageSizeOptions?: number[];
|
|
258
|
-
/**
|
|
863
|
+
/**
|
|
864
|
+
* Enables row editing. Called when the user commits a row.
|
|
865
|
+
*
|
|
866
|
+
* Return `{ ok: false, errors }` to keep the row open and paint each message
|
|
867
|
+
* onto the cell whose column id it is keyed by.
|
|
868
|
+
*
|
|
869
|
+
* @param draft - The edited copy.
|
|
870
|
+
* @param original - The row as it was before editing.
|
|
871
|
+
* @see {@link RowCommitResult}
|
|
872
|
+
*/
|
|
259
873
|
onRowCommit?: (draft: T, original: T) => Promise<RowCommitResult> | RowCommitResult;
|
|
874
|
+
/**
|
|
875
|
+
* Called whenever the selection changes.
|
|
876
|
+
* @param ids - Every selected row id, including rows on other pages.
|
|
877
|
+
*/
|
|
260
878
|
onSelectionChanged?: (ids: RowId[]) => void;
|
|
261
879
|
/** Enables dropping files onto a row (e.g. to attach documents to it). */
|
|
262
880
|
onRowFilesDropped?: (row: T, files: File[]) => void;
|
|
881
|
+
/**
|
|
882
|
+
* Called when a fetch or a commit throws. Aborted requests are not reported.
|
|
883
|
+
*/
|
|
263
884
|
onError?: (error: unknown) => void;
|
|
264
|
-
/**
|
|
885
|
+
/**
|
|
886
|
+
* Rendered into the toolbar strip above the header, left of the built-in
|
|
887
|
+
* Columns and Export CSV buttons.
|
|
888
|
+
*
|
|
889
|
+
* @param api - The live imperative API.
|
|
890
|
+
*/
|
|
265
891
|
toolbar?: (api: GridApi<T>) => ReactNode;
|
|
892
|
+
/**
|
|
893
|
+
* Shown when a query returns no rows.
|
|
894
|
+
* @defaultValue 'No rows'
|
|
895
|
+
*/
|
|
266
896
|
emptyMessage?: ReactNode;
|
|
897
|
+
/**
|
|
898
|
+
* Base file name for CSV export, without the extension.
|
|
899
|
+
* @defaultValue 'export'
|
|
900
|
+
*/
|
|
267
901
|
exportFileName?: string;
|
|
902
|
+
/** Extra classes on the grid's outer frame. */
|
|
268
903
|
className?: string;
|
|
269
|
-
/**
|
|
904
|
+
/**
|
|
905
|
+
* Height of the whole grid. Any CSS length; a number is treated as pixels.
|
|
906
|
+
* @defaultValue '70vh'
|
|
907
|
+
*/
|
|
270
908
|
height?: number | string;
|
|
909
|
+
/**
|
|
910
|
+
* Receives the imperative {@link GridApi}. Accepts a ref object or a
|
|
911
|
+
* callback ref.
|
|
912
|
+
*/
|
|
271
913
|
apiRef?: Ref<GridApi<T>>;
|
|
272
914
|
}
|
|
915
|
+
/**
|
|
916
|
+
* A virtualized, server-driven data grid.
|
|
917
|
+
*
|
|
918
|
+
* Paging, sorting and filtering are all resolved by your
|
|
919
|
+
* {@link HxDataSource | data source} — the grid holds one page at a time and
|
|
920
|
+
* never filters or sorts locally. Rows are windowed at a fixed height, so the
|
|
921
|
+
* DOM stays small regardless of the result set.
|
|
922
|
+
*
|
|
923
|
+
* @typeParam T - The row type.
|
|
924
|
+
* @typeParam C - The context type, inferred from the `context` prop.
|
|
925
|
+
*
|
|
926
|
+
* @example Minimal usage
|
|
927
|
+
* ```tsx
|
|
928
|
+
* const columns: ColumnDef<Person>[] = [
|
|
929
|
+
* { field: 'name', header: 'Name', flex: 1, filter: 'text' },
|
|
930
|
+
* { field: 'email', header: 'Email', flex: 1 },
|
|
931
|
+
* ];
|
|
932
|
+
*
|
|
933
|
+
* function People() {
|
|
934
|
+
* const dataSource = useMemo(
|
|
935
|
+
* () => ({ getRows: (request, signal) => api.list(request, signal) }),
|
|
936
|
+
* []
|
|
937
|
+
* );
|
|
938
|
+
*
|
|
939
|
+
* return (
|
|
940
|
+
* <DataGrid
|
|
941
|
+
* columns={columns}
|
|
942
|
+
* dataSource={dataSource}
|
|
943
|
+
* getRowId={(row) => row.id}
|
|
944
|
+
* />
|
|
945
|
+
* );
|
|
946
|
+
* }
|
|
947
|
+
* ```
|
|
948
|
+
*
|
|
949
|
+
* @example With editing, persistence and the imperative API
|
|
950
|
+
* ```tsx
|
|
951
|
+
* const apiRef = useRef<GridApi<Person>>(null);
|
|
952
|
+
*
|
|
953
|
+
* <DataGrid
|
|
954
|
+
* columns={columns}
|
|
955
|
+
* dataSource={dataSource}
|
|
956
|
+
* getRowId={(row) => row.id}
|
|
957
|
+
* storageKey="people"
|
|
958
|
+
* apiRef={apiRef}
|
|
959
|
+
* onRowCommit={async (draft) => {
|
|
960
|
+
* const result = await api.save(draft);
|
|
961
|
+
* return result.ok ? { ok: true } : { ok: false, errors: result.errors };
|
|
962
|
+
* }}
|
|
963
|
+
* toolbar={(api) => (
|
|
964
|
+
* <button onClick={() => api.refresh({ purge: true })}>Refresh</button>
|
|
965
|
+
* )}
|
|
966
|
+
* />
|
|
967
|
+
* ```
|
|
968
|
+
*
|
|
969
|
+
* @remarks
|
|
970
|
+
* Styling is plain Tailwind utility classes — there is no stylesheet to import.
|
|
971
|
+
* Tailwind skips `node_modules` when detecting content, so point it at the
|
|
972
|
+
* shipped bundle explicitly:
|
|
973
|
+
*
|
|
974
|
+
* ```css
|
|
975
|
+
* @import "tailwindcss";
|
|
976
|
+
* @source "../node_modules/@helix-x/datagrid-ui/dist/index.js";
|
|
977
|
+
* ```
|
|
978
|
+
*
|
|
979
|
+
* @see {@link DataGridProps} for every option.
|
|
980
|
+
* @see {@link GridApi} for what `apiRef` and `toolbar` receive.
|
|
981
|
+
*/
|
|
273
982
|
declare function DataGrid<T, C = unknown>({ columns, dataSource, getRowId, context, storageKey, rowHeight, headerHeight, floatingFilter, selectable, defaultPageSize, pageSizeOptions, onRowCommit, onSelectionChanged, onRowFilesDropped, onError, toolbar, emptyMessage, exportFileName, className, height, apiRef, }: DataGridProps<T, C>): react.JSX.Element;
|
|
274
983
|
|
|
984
|
+
/** Props for {@link GridPagination}. */
|
|
275
985
|
interface GridPaginationProps {
|
|
986
|
+
/** Zero-based current page. */
|
|
276
987
|
page: number;
|
|
988
|
+
/** Rows per page. */
|
|
277
989
|
pageSize: number;
|
|
990
|
+
/** Total across all pages. `-1` when the server reported it as unknown. */
|
|
278
991
|
totalRows: number;
|
|
992
|
+
/** Page sizes to offer in the selector. */
|
|
279
993
|
pageSizeOptions: number[];
|
|
994
|
+
/** Disables the controls while a fetch is in flight. */
|
|
280
995
|
isLoading: boolean;
|
|
996
|
+
/** Called with the new zero-based page index. */
|
|
281
997
|
onPageChange: (page: number) => void;
|
|
998
|
+
/** Called with the new page size. */
|
|
282
999
|
onPageSizeChange: (pageSize: number) => void;
|
|
283
1000
|
}
|
|
1001
|
+
/**
|
|
1002
|
+
* The grid's pager: range summary, page size selector and navigation.
|
|
1003
|
+
*
|
|
1004
|
+
* {@link DataGrid} renders this itself. It is exported for apps that build a
|
|
1005
|
+
* custom surface on the same hooks.
|
|
1006
|
+
*/
|
|
284
1007
|
declare function GridPagination({ page, pageSize, totalRows, pageSizeOptions, isLoading, onPageChange, onPageSizeChange, }: GridPaginationProps): react.JSX.Element;
|
|
285
1008
|
|
|
1009
|
+
/** Props for {@link GridOverlay}. */
|
|
286
1010
|
interface GridOverlayProps {
|
|
1011
|
+
/** Which state to show. */
|
|
287
1012
|
kind: 'loading' | 'empty' | 'error';
|
|
1013
|
+
/** Message body. Falls back to a default per `kind`. */
|
|
288
1014
|
message?: ReactNode;
|
|
289
1015
|
}
|
|
290
1016
|
/**
|
|
291
|
-
*
|
|
292
|
-
*
|
|
1017
|
+
* The loading, empty and error states shown over the row area.
|
|
1018
|
+
*
|
|
1019
|
+
* Overlays rather than replaces, so the header and column widths stay put while
|
|
1020
|
+
* a refetch is in flight.
|
|
1021
|
+
*
|
|
1022
|
+
* @param props - Which state to show, and the message.
|
|
293
1023
|
*/
|
|
294
1024
|
declare function GridOverlay({ kind, message }: GridOverlayProps): react.JSX.Element;
|
|
295
1025
|
|
|
1026
|
+
/**
|
|
1027
|
+
* Props for {@link ColumnsPanel}.
|
|
1028
|
+
*
|
|
1029
|
+
* @typeParam T - The row type.
|
|
1030
|
+
* @typeParam C - The context type.
|
|
1031
|
+
*/
|
|
296
1032
|
interface ColumnsPanelProps<T, C> {
|
|
1033
|
+
/** Every column, including hidden ones. */
|
|
297
1034
|
columns: ResolvedColumn<T, C>[];
|
|
1035
|
+
/** Whether a column is currently hidden. */
|
|
298
1036
|
isHidden: (colId: string) => boolean;
|
|
1037
|
+
/** Show or hide one column. */
|
|
299
1038
|
onToggle: (colId: string, hidden: boolean) => void;
|
|
1039
|
+
/** Move a column to a new index. */
|
|
300
1040
|
onMove: (colId: string, toIndex: number) => void;
|
|
1041
|
+
/** Pin a column, or `undefined` to unpin. */
|
|
301
1042
|
onPin: (colId: string, pinned: Pinned | undefined) => void;
|
|
1043
|
+
/** Discard the user's layout. */
|
|
302
1044
|
onReset: () => void;
|
|
1045
|
+
/** Dismiss the panel. */
|
|
303
1046
|
onClose: () => void;
|
|
304
1047
|
}
|
|
305
|
-
/**
|
|
1048
|
+
/**
|
|
1049
|
+
* The side panel for showing, hiding, reordering and pinning columns, with the
|
|
1050
|
+
* "reset my preferences" escape hatch.
|
|
1051
|
+
*
|
|
1052
|
+
* {@link DataGrid} renders this from its toolbar; exported for custom surfaces.
|
|
1053
|
+
*/
|
|
306
1054
|
declare function ColumnsPanel<T, C>({ columns, isHidden, onToggle, onMove, onPin, onReset, onClose, }: ColumnsPanelProps<T, C>): react.JSX.Element;
|
|
307
1055
|
|
|
1056
|
+
/** Props for {@link FilterPopover}. */
|
|
308
1057
|
interface FilterPopoverProps {
|
|
1058
|
+
/** Which filter UI to render. */
|
|
309
1059
|
kind: FilterKind;
|
|
1060
|
+
/** The column's current filter, or `undefined` when unfiltered. */
|
|
310
1061
|
value: HxFilterModel | undefined;
|
|
1062
|
+
/**
|
|
1063
|
+
* Options for a `set` filter: a static list, or a loader called the first
|
|
1064
|
+
* time the popover opens.
|
|
1065
|
+
*/
|
|
311
1066
|
setValues?: string[] | (() => Promise<string[]>);
|
|
1067
|
+
/** Called with the new filter, or `null` to clear the column's filter. */
|
|
312
1068
|
onApply: (filter: HxFilterModel | null) => void;
|
|
1069
|
+
/** Dismiss the popover. */
|
|
313
1070
|
onClose: () => void;
|
|
314
1071
|
}
|
|
315
1072
|
/** Header filter menu. Emits the wire-format model directly. */
|
|
1073
|
+
/**
|
|
1074
|
+
* The per-column filter editor, covering all four
|
|
1075
|
+
* {@link FilterKind | filter kinds}.
|
|
1076
|
+
*
|
|
1077
|
+
* {@link DataGrid} opens this from the header; exported for custom surfaces.
|
|
1078
|
+
*/
|
|
316
1079
|
declare function FilterPopover({ kind, value, setValues, onApply, onClose, }: FilterPopoverProps): react.JSX.Element;
|
|
317
1080
|
|
|
1081
|
+
/**
|
|
1082
|
+
* Single-line text input. The default editor when a column sets
|
|
1083
|
+
* `editable: true` without naming one.
|
|
1084
|
+
*
|
|
1085
|
+
* Reads `editorParams.placeholder`.
|
|
1086
|
+
*/
|
|
318
1087
|
declare function TextEditor<T, C>({ value, onChange, onCommit, onCancel, error, autoFocus, column, }: EditorParams<T, C>): react.JSX.Element;
|
|
1088
|
+
/**
|
|
1089
|
+
* Numeric input. Writes a `number`, or `null` when the field is cleared, so an
|
|
1090
|
+
* empty cell is never stored as `NaN` or `''`.
|
|
1091
|
+
*
|
|
1092
|
+
* Reads `editorParams.placeholder`.
|
|
1093
|
+
*/
|
|
319
1094
|
declare function NumberEditor<T, C>({ value, onChange, onCommit, onCancel, error, autoFocus, }: EditorParams<T, C>): react.JSX.Element;
|
|
1095
|
+
/**
|
|
1096
|
+
* Native date input. Reads and writes `YYYY-MM-DD` strings, matching
|
|
1097
|
+
* {@link DateFilterModel}.
|
|
1098
|
+
*/
|
|
320
1099
|
declare function DateEditor<T, C>({ value, onChange, onCommit, onCancel, error, autoFocus, }: EditorParams<T, C>): react.JSX.Element;
|
|
1100
|
+
/**
|
|
1101
|
+
* Dropdown over `editorParams.options`. Values round-trip by identity, so a
|
|
1102
|
+
* non-string option value is preserved rather than stringified.
|
|
1103
|
+
*/
|
|
321
1104
|
declare function SelectEditor<T, C>({ value, onChange, onCommit, onCancel, error, autoFocus, column, }: EditorParams<T, C>): react.JSX.Element;
|
|
1105
|
+
/** Boolean checkbox. Writes `true` or `false`, never `undefined`. */
|
|
322
1106
|
declare function CheckboxEditor<T, C>({ value, onChange, onCommit, onCancel, autoFocus, }: EditorParams<T, C>): react.JSX.Element;
|
|
323
1107
|
|
|
324
|
-
/**
|
|
1108
|
+
/**
|
|
1109
|
+
* Maps a {@link BuiltinEditor} name to its component.
|
|
1110
|
+
*
|
|
1111
|
+
* Look one up to reuse it inside a custom editor, or to check which names are
|
|
1112
|
+
* available.
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```tsx
|
|
1116
|
+
* const Base = BUILTIN_EDITORS.text;
|
|
1117
|
+
* const UppercaseEditor: EditorComponent<Row> = (params) => (
|
|
1118
|
+
* <Base {...params} onChange={(v) => params.onChange(String(v).toUpperCase())} />
|
|
1119
|
+
* );
|
|
1120
|
+
* ```
|
|
1121
|
+
*/
|
|
325
1122
|
declare const BUILTIN_EDITORS: {
|
|
1123
|
+
/** Single-line text input. See {@link TextEditor}. */
|
|
326
1124
|
readonly text: typeof TextEditor;
|
|
1125
|
+
/** Numeric input that writes `null` when cleared. See {@link NumberEditor}. */
|
|
327
1126
|
readonly number: typeof NumberEditor;
|
|
1127
|
+
/** Native date input over `YYYY-MM-DD`. See {@link DateEditor}. */
|
|
328
1128
|
readonly date: typeof DateEditor;
|
|
1129
|
+
/** Dropdown over `editorParams.options`. See {@link SelectEditor}. */
|
|
329
1130
|
readonly select: typeof SelectEditor;
|
|
1131
|
+
/** Boolean checkbox. See {@link CheckboxEditor}. */
|
|
330
1132
|
readonly checkbox: typeof CheckboxEditor;
|
|
331
1133
|
};
|
|
332
1134
|
|
|
1135
|
+
/** What {@link useGridState} returns. */
|
|
333
1136
|
interface UseGridStateResult {
|
|
334
|
-
/**
|
|
1137
|
+
/**
|
|
1138
|
+
* The restored state, read once on mount and never re-read — so it is safe
|
|
1139
|
+
* to use as a `useState` initial value. `undefined` when nothing was saved
|
|
1140
|
+
* or the saved schema version did not match.
|
|
1141
|
+
*/
|
|
335
1142
|
initial: PersistedGridState | undefined;
|
|
1143
|
+
/** Persist the column layout. */
|
|
336
1144
|
saveColumns: (columns: PersistedGridState['columns']) => void;
|
|
1145
|
+
/** Persist the sort model. */
|
|
337
1146
|
saveSort: (sort: SortModelItem[]) => void;
|
|
1147
|
+
/** Persist the filter model. */
|
|
338
1148
|
saveFilters: (filters: FilterModelMap) => void;
|
|
1149
|
+
/** Persist the page size. */
|
|
339
1150
|
savePageSize: (pageSize: number) => void;
|
|
1151
|
+
/** Delete the saved state entirely. */
|
|
340
1152
|
clear: () => void;
|
|
1153
|
+
/** Whether anything was restored on mount. */
|
|
341
1154
|
hasSavedState: boolean;
|
|
342
1155
|
}
|
|
343
|
-
/**
|
|
1156
|
+
/**
|
|
1157
|
+
* Versioned `localStorage` persistence for one grid's layout.
|
|
1158
|
+
*
|
|
1159
|
+
* Writes go through a ref, so saving never causes a re-render. Every read and
|
|
1160
|
+
* write is wrapped: a quota error or a privacy mode degrades to not persisting
|
|
1161
|
+
* rather than throwing, and state saved under a different
|
|
1162
|
+
* {@link GRID_STATE_VERSION} is discarded rather than migrated.
|
|
1163
|
+
*
|
|
1164
|
+
* @param storageKey - Key to store under, namespaced as `hxg:<storageKey>`.
|
|
1165
|
+
* Pass `undefined` to disable persistence entirely.
|
|
1166
|
+
* @returns The restored state and its setters.
|
|
1167
|
+
*/
|
|
344
1168
|
declare function useGridState(storageKey: string | undefined): UseGridStateResult;
|
|
345
1169
|
|
|
1170
|
+
/**
|
|
1171
|
+
* Options for {@link useServerDataSource}.
|
|
1172
|
+
*
|
|
1173
|
+
* @typeParam T - The row type.
|
|
1174
|
+
*/
|
|
346
1175
|
interface UseServerDataSourceOptions<T> {
|
|
1176
|
+
/** Where rows come from. Memoise it, or every render refetches. */
|
|
347
1177
|
dataSource: HxDataSource<T>;
|
|
1178
|
+
/** Rows per page. */
|
|
348
1179
|
pageSize: number;
|
|
1180
|
+
/** Zero-based page index. */
|
|
349
1181
|
page: number;
|
|
1182
|
+
/** Active sorts, primary first. */
|
|
350
1183
|
sortModel: SortModelItem[];
|
|
1184
|
+
/** Active filters, keyed by column id. */
|
|
351
1185
|
filterModel: FilterModelMap;
|
|
352
|
-
/**
|
|
1186
|
+
/**
|
|
1187
|
+
* Blocks to keep around so paging back and forth does not refetch.
|
|
1188
|
+
* @defaultValue 3
|
|
1189
|
+
*/
|
|
353
1190
|
maxCachedBlocks?: number;
|
|
1191
|
+
/** Called when a fetch throws. Aborted requests are not reported. */
|
|
354
1192
|
onError?: (error: unknown) => void;
|
|
355
1193
|
}
|
|
1194
|
+
/**
|
|
1195
|
+
* What {@link useServerDataSource} returns.
|
|
1196
|
+
*
|
|
1197
|
+
* @typeParam T - The row type.
|
|
1198
|
+
*/
|
|
356
1199
|
interface UseServerDataSourceResult<T> {
|
|
1200
|
+
/** Rows for the current page. Empty while the first fetch is in flight. */
|
|
357
1201
|
rows: T[];
|
|
1202
|
+
/** Total across all pages, from the response's `lastRow`. */
|
|
358
1203
|
totalRows: number;
|
|
1204
|
+
/** True while a fetch is in flight. */
|
|
359
1205
|
isLoading: boolean;
|
|
1206
|
+
/** The last error, or `null`. */
|
|
360
1207
|
error: unknown;
|
|
1208
|
+
/**
|
|
1209
|
+
* Re-fetch the current page.
|
|
1210
|
+
* @param options - `purge: true` drops every cached block first.
|
|
1211
|
+
*/
|
|
361
1212
|
refresh: (options?: {
|
|
362
1213
|
purge?: boolean;
|
|
363
1214
|
}) => void;
|
|
364
|
-
/**
|
|
1215
|
+
/**
|
|
1216
|
+
* Patch loaded rows in place, matched by id. Ids that are not loaded are
|
|
1217
|
+
* ignored. No network request is made.
|
|
1218
|
+
*/
|
|
365
1219
|
patchRows: (rows: T[], getRowId: (row: T) => string | number) => void;
|
|
366
1220
|
}
|
|
367
1221
|
/**
|
|
368
1222
|
* Server-side paging with a small block cache.
|
|
369
1223
|
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
1224
|
+
* {@link DataGrid} uses this internally; call it directly only when building a
|
|
1225
|
+
* custom surface on top of the same data contract.
|
|
1226
|
+
*
|
|
1227
|
+
* @typeParam T - The row type.
|
|
1228
|
+
* @param options - Data source, page, sort and filters.
|
|
1229
|
+
* @returns The current page plus loading state and imperative helpers.
|
|
1230
|
+
*
|
|
1231
|
+
* @remarks
|
|
1232
|
+
* Every request carries an `AbortController` and a sequence number, so a slow
|
|
1233
|
+
* response for an old sort or filter can never overwrite a newer one. The cache
|
|
1234
|
+
* is dropped wholesale when the query changes, so stale blocks are never mixed
|
|
374
1235
|
* with fresh ones.
|
|
1236
|
+
*
|
|
1237
|
+
* @example
|
|
1238
|
+
* ```ts
|
|
1239
|
+
* const { rows, totalRows, isLoading, refresh } = useServerDataSource({
|
|
1240
|
+
* dataSource,
|
|
1241
|
+
* page: 0,
|
|
1242
|
+
* pageSize: 50,
|
|
1243
|
+
* sortModel: [{ colId: 'name', sort: 'asc' }],
|
|
1244
|
+
* filterModel: {},
|
|
1245
|
+
* });
|
|
1246
|
+
* ```
|
|
375
1247
|
*/
|
|
376
1248
|
declare function useServerDataSource<T>({ dataSource, pageSize, page, sortModel, filterModel, maxCachedBlocks, onError, }: UseServerDataSourceOptions<T>): UseServerDataSourceResult<T>;
|
|
377
1249
|
|
|
1250
|
+
/** The slice of rows currently worth rendering. */
|
|
378
1251
|
interface VirtualWindow {
|
|
1252
|
+
/** First row index to render, inclusive. Includes overscan. */
|
|
379
1253
|
startIndex: number;
|
|
1254
|
+
/** Index one past the last row to render, exclusive. */
|
|
380
1255
|
endIndex: number;
|
|
381
1256
|
}
|
|
1257
|
+
/** Options for {@link useVirtualRows}. */
|
|
382
1258
|
interface UseVirtualRowsOptions {
|
|
1259
|
+
/** How many rows exist in the current page. */
|
|
383
1260
|
rowCount: number;
|
|
1261
|
+
/** Fixed height of every row, in pixels. */
|
|
384
1262
|
rowHeight: number;
|
|
1263
|
+
/**
|
|
1264
|
+
* Extra rows rendered above and below the viewport, so fast scrolling does
|
|
1265
|
+
* not show blank space.
|
|
1266
|
+
* @defaultValue 6
|
|
1267
|
+
*/
|
|
385
1268
|
overscan?: number;
|
|
386
1269
|
}
|
|
1270
|
+
/** What {@link useVirtualRows} returns. */
|
|
387
1271
|
interface UseVirtualRowsResult {
|
|
1272
|
+
/** The rows to render right now. */
|
|
388
1273
|
window: VirtualWindow;
|
|
1274
|
+
/** `rowCount * rowHeight` — the spacer height that gives the correct scrollbar. */
|
|
389
1275
|
totalHeight: number;
|
|
390
|
-
/** Attach to the scrolling element
|
|
1276
|
+
/** Attach to the scrolling element's `onScroll`. */
|
|
391
1277
|
onScroll: (event: {
|
|
392
1278
|
currentTarget: HTMLElement;
|
|
393
1279
|
}) => void;
|
|
394
1280
|
/** Call when the viewport is measured or resized. */
|
|
395
1281
|
setViewportHeight: (height: number) => void;
|
|
1282
|
+
/** Live scroll offset, readable without causing a re-render. */
|
|
396
1283
|
scrollTopRef: React.RefObject<number>;
|
|
397
1284
|
}
|
|
398
1285
|
/**
|
|
399
1286
|
* Fixed-height row windowing.
|
|
400
1287
|
*
|
|
1288
|
+
* @param options - Row count, row height and overscan.
|
|
1289
|
+
* @returns The visible window plus the handlers that maintain it.
|
|
1290
|
+
*
|
|
1291
|
+
* @remarks
|
|
401
1292
|
* Fixed heights are a deliberate constraint: they make the visible range O(1)
|
|
402
1293
|
* to compute and remove the measure-then-reflow pass that variable heights
|
|
403
1294
|
* force. Scroll position is tracked in a ref and only promoted to state when
|
|
404
|
-
* the computed window actually changes, so scrolling within a row
|
|
405
|
-
* re-
|
|
1295
|
+
* the computed window actually changes, so scrolling within a single row
|
|
1296
|
+
* re-renders nothing.
|
|
1297
|
+
*
|
|
1298
|
+
* @example
|
|
1299
|
+
* ```tsx
|
|
1300
|
+
* const { window, totalHeight, onScroll, setViewportHeight } = useVirtualRows({
|
|
1301
|
+
* rowCount: rows.length,
|
|
1302
|
+
* rowHeight: 36,
|
|
1303
|
+
* });
|
|
1304
|
+
*
|
|
1305
|
+
* <div onScroll={onScroll} style={{ overflow: 'auto' }}>
|
|
1306
|
+
* <div style={{ height: totalHeight }}>
|
|
1307
|
+
* {rows.slice(window.startIndex, window.endIndex).map(renderRow)}
|
|
1308
|
+
* </div>
|
|
1309
|
+
* </div>
|
|
1310
|
+
* ```
|
|
406
1311
|
*/
|
|
407
1312
|
declare function useVirtualRows({ rowCount, rowHeight, overscan, }: UseVirtualRowsOptions): UseVirtualRowsResult;
|
|
408
1313
|
|
|
1314
|
+
/** The user's column layout, as persisted. */
|
|
409
1315
|
interface ColumnStateValue {
|
|
1316
|
+
/** Column ids in display order. */
|
|
410
1317
|
order: string[];
|
|
1318
|
+
/** Ids of hidden columns. */
|
|
411
1319
|
hidden: string[];
|
|
1320
|
+
/** Widths in pixels, by column id. */
|
|
412
1321
|
widths: Record<string, number>;
|
|
1322
|
+
/** Pinned edge, by column id. */
|
|
413
1323
|
pinned: Record<string, Pinned>;
|
|
414
1324
|
}
|
|
1325
|
+
/**
|
|
1326
|
+
* What {@link useColumnState} returns.
|
|
1327
|
+
*
|
|
1328
|
+
* @typeParam T - The row type.
|
|
1329
|
+
* @typeParam C - The context type.
|
|
1330
|
+
*/
|
|
415
1331
|
interface UseColumnStateResult<T, C> {
|
|
416
1332
|
/** Every column, in user order, including hidden ones (for the columns panel). */
|
|
417
1333
|
allColumns: ResolvedColumn<T, C>[];
|
|
1334
|
+
/** Just the visible columns, in display order. */
|
|
418
1335
|
visibleColumns: ResolvedColumn<T, C>[];
|
|
1336
|
+
/** Measured geometry for the visible columns. */
|
|
419
1337
|
layout: ColumnLayout<T, C>;
|
|
1338
|
+
/** The raw layout state, ready to persist. */
|
|
420
1339
|
state: ColumnStateValue;
|
|
1340
|
+
/** Whether a column is hidden. */
|
|
421
1341
|
isHidden: (colId: string) => boolean;
|
|
1342
|
+
/** Show or hide one column. */
|
|
422
1343
|
setHidden: (colId: string, hidden: boolean) => void;
|
|
1344
|
+
/** Resize one column. Clamped to its `minWidth` and `maxWidth`. */
|
|
423
1345
|
setWidth: (colId: string, width: number) => void;
|
|
1346
|
+
/** Pin one column to an edge, or pass `undefined` to unpin it. */
|
|
424
1347
|
setPinned: (colId: string, pinned: Pinned | undefined) => void;
|
|
1348
|
+
/** Move a column to a new index in the display order. */
|
|
425
1349
|
moveColumn: (colId: string, toIndex: number) => void;
|
|
1350
|
+
/** Discard the user's layout and return to the column definitions' defaults. */
|
|
426
1351
|
reset: () => void;
|
|
427
1352
|
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Column order, visibility, width and pinning, merged over the definitions'
|
|
1355
|
+
* defaults.
|
|
1356
|
+
*
|
|
1357
|
+
* Persisted state is merged key by key rather than replacing the defaults
|
|
1358
|
+
* wholesale — so a layout saved before a new column was added does not hide
|
|
1359
|
+
* that column, and does not discard defaults it says nothing about.
|
|
1360
|
+
*
|
|
1361
|
+
* @typeParam T - The row type.
|
|
1362
|
+
* @typeParam C - The context type.
|
|
1363
|
+
* @returns The resolved columns, their layout, and the mutators.
|
|
1364
|
+
*/
|
|
428
1365
|
declare function useColumnState<T, C>(columns: ColumnDef<T, C>[], persisted: PersistedGridState['columns'] | undefined, onChange: (state: ColumnStateValue) => void, availableWidth: number): UseColumnStateResult<T, C>;
|
|
429
1366
|
|
|
1367
|
+
/**
|
|
1368
|
+
* The row currently being edited.
|
|
1369
|
+
*
|
|
1370
|
+
* @typeParam T - The row type.
|
|
1371
|
+
*/
|
|
430
1372
|
interface EditState<T> {
|
|
1373
|
+
/** Which row is open. */
|
|
431
1374
|
rowId: RowId;
|
|
1375
|
+
/** The working copy, updated as the user types. */
|
|
432
1376
|
draft: T;
|
|
1377
|
+
/** The row as it was when editing started, for cancel and for the commit callback. */
|
|
433
1378
|
original: T;
|
|
1379
|
+
/** Server-supplied messages from the last rejected commit, keyed by column id. */
|
|
434
1380
|
errors: Record<string, string>;
|
|
1381
|
+
/** True while a commit is in flight. */
|
|
435
1382
|
isSaving: boolean;
|
|
436
1383
|
}
|
|
1384
|
+
/**
|
|
1385
|
+
* What {@link useEditModel} returns.
|
|
1386
|
+
*
|
|
1387
|
+
* @typeParam T - The row type.
|
|
1388
|
+
*/
|
|
437
1389
|
interface UseEditModelResult<T> {
|
|
1390
|
+
/** The open row, or `null` when nothing is being edited. */
|
|
438
1391
|
edit: EditState<T> | null;
|
|
1392
|
+
/** Whether a given row is the one currently open. */
|
|
439
1393
|
isEditing: (rowId: RowId) => boolean;
|
|
1394
|
+
/** Open a row for editing, replacing any row already open. */
|
|
440
1395
|
start: (rowId: RowId, row: T) => void;
|
|
1396
|
+
/**
|
|
1397
|
+
* Write one field into the draft. Accepts a dotted path, creating
|
|
1398
|
+
* intermediate objects as needed.
|
|
1399
|
+
*/
|
|
441
1400
|
setField: (field: string, value: unknown) => void;
|
|
1401
|
+
/** Close without saving, discarding the draft. */
|
|
442
1402
|
cancel: () => void;
|
|
1403
|
+
/** Run the commit callback. Keeps the row open if it returns `ok: false`. */
|
|
443
1404
|
commit: () => Promise<void>;
|
|
444
1405
|
}
|
|
445
1406
|
/**
|
|
446
1407
|
* Row-level editing against a draft copy.
|
|
447
1408
|
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
1409
|
+
* @typeParam T - The row type.
|
|
1410
|
+
* @param onCommit - Owns validation and persistence. Return
|
|
1411
|
+
* `{ ok: false, errors }` to keep the row open with per-field messages.
|
|
1412
|
+
* @returns The edit state and its mutators.
|
|
1413
|
+
*
|
|
1414
|
+
* @remarks
|
|
1415
|
+
* The draft never touches the data source, and editors never call an API — the
|
|
1416
|
+
* single commit callback owns both, so an app can plug in whatever schema
|
|
1417
|
+
* library it uses without the grid knowing about it.
|
|
1418
|
+
*
|
|
1419
|
+
* @see {@link RowCommitResult}
|
|
451
1420
|
*/
|
|
452
1421
|
declare function useEditModel<T>(onCommit: (draft: T, original: T) => Promise<RowCommitResult> | RowCommitResult): UseEditModelResult<T>;
|
|
453
1422
|
|
|
454
1423
|
/**
|
|
455
|
-
* Resolves a cell value.
|
|
1424
|
+
* Resolves a cell's raw value from its row.
|
|
1425
|
+
*
|
|
1426
|
+
* Tries, in order: {@link ColumnDef.valueGetter}, the dotted `field` path, the
|
|
1427
|
+
* literal flat key, then each {@link ColumnDef.fieldAliases | alias}.
|
|
1428
|
+
*
|
|
1429
|
+
* @remarks
|
|
1430
|
+
* The fallbacks exist because servers that flatten joined relations hand back
|
|
1431
|
+
* `{"customer.businessName": x}` rather than a nested object — and some change
|
|
1432
|
+
* the prefix when grouping is on.
|
|
456
1433
|
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
1434
|
+
* @param row - The row to read from.
|
|
1435
|
+
* @param column - The column describing what to read.
|
|
1436
|
+
* @returns The raw value, or `undefined` if nothing matched.
|
|
1437
|
+
*
|
|
1438
|
+
* @example
|
|
1439
|
+
* ```ts
|
|
1440
|
+
* resolveValue({ customer: { name: 'Acme' } }, { field: 'customer.name', header: 'C' });
|
|
1441
|
+
* // 'Acme'
|
|
1442
|
+
* ```
|
|
461
1443
|
*/
|
|
462
1444
|
declare function resolveValue<T>(row: T, column: ColumnDef<T, never>): unknown;
|
|
463
|
-
/**
|
|
1445
|
+
/**
|
|
1446
|
+
* The display string for a cell, independent of any custom renderer.
|
|
1447
|
+
*
|
|
1448
|
+
* Uses {@link ColumnDef.valueFormatter} when present. Otherwise `null` and
|
|
1449
|
+
* `undefined` become `''`, `Date` becomes `YYYY-MM-DD`, booleans become
|
|
1450
|
+
* `Yes`/`No`, and everything else is stringified.
|
|
1451
|
+
*
|
|
1452
|
+
* @param value - The raw value, usually from {@link resolveValue}.
|
|
1453
|
+
* @param row - The row it came from, passed to the formatter.
|
|
1454
|
+
* @param column - The column being formatted.
|
|
1455
|
+
* @returns The display string.
|
|
1456
|
+
*/
|
|
464
1457
|
declare function formatValue<T>(value: unknown, row: T, column: ColumnDef<T, never>): string;
|
|
465
|
-
/**
|
|
1458
|
+
/**
|
|
1459
|
+
* The string written to CSV and the clipboard for a cell.
|
|
1460
|
+
*
|
|
1461
|
+
* Prefers {@link ColumnDef.exportValue}, falling back to {@link formatValue} —
|
|
1462
|
+
* which is why a column with a markup `cellRenderer` should supply one.
|
|
1463
|
+
*
|
|
1464
|
+
* @param row - The row to export.
|
|
1465
|
+
* @param column - The column being exported.
|
|
1466
|
+
* @returns The flat string for this cell.
|
|
1467
|
+
*/
|
|
466
1468
|
declare function exportValue<T>(row: T, column: ColumnDef<T, never>): string;
|
|
467
|
-
/**
|
|
1469
|
+
/**
|
|
1470
|
+
* Plain-text header, for exports and aria labels.
|
|
1471
|
+
*
|
|
1472
|
+
* Prefers {@link ColumnDef.headerName}, then a string or numeric `header`, then
|
|
1473
|
+
* falls back to the column id.
|
|
1474
|
+
*
|
|
1475
|
+
* @param column - The column to label.
|
|
1476
|
+
* @returns The header as plain text, or `''` if nothing usable was found.
|
|
1477
|
+
*/
|
|
468
1478
|
declare function headerText<T>(column: ColumnDef<T, never>): string;
|
|
1479
|
+
/**
|
|
1480
|
+
* The stable id for a column: `colId`, or `field` when `colId` was omitted.
|
|
1481
|
+
*
|
|
1482
|
+
* @param column - The column to identify.
|
|
1483
|
+
* @returns The column id.
|
|
1484
|
+
* @throws If the column has neither `colId` nor `field`.
|
|
1485
|
+
*/
|
|
469
1486
|
declare function columnId<T, C>(column: ColumnDef<T, C>): string;
|
|
470
|
-
/**
|
|
1487
|
+
/**
|
|
1488
|
+
* Fills in the defaults every other module assumes are present.
|
|
1489
|
+
*
|
|
1490
|
+
* Width defaults to 150 (never below `minWidth`), `minWidth` to 60, and both
|
|
1491
|
+
* `sortable` and `resizable` to `true`.
|
|
1492
|
+
*
|
|
1493
|
+
* @param column - The column as authored.
|
|
1494
|
+
* @returns The same column with required fields resolved.
|
|
1495
|
+
*/
|
|
471
1496
|
declare function resolveColumn<T, C>(column: ColumnDef<T, C>): ResolvedColumn<T, C>;
|
|
1497
|
+
/**
|
|
1498
|
+
* Whether a specific row's cell is editable in this column.
|
|
1499
|
+
*
|
|
1500
|
+
* @param column - The column to test.
|
|
1501
|
+
* @param row - The row to test, for a predicate `editable`.
|
|
1502
|
+
* @returns `true` when the cell can be edited.
|
|
1503
|
+
*/
|
|
472
1504
|
declare function isEditable<T, C>(column: ColumnDef<T, C>, row: T): boolean;
|
|
473
1505
|
|
|
474
1506
|
/**
|
|
475
|
-
*
|
|
476
|
-
*
|
|
1507
|
+
* Builders and helpers for the wire-format filter shapes.
|
|
1508
|
+
*
|
|
1509
|
+
* Every filter the grid sends is constructed here, so the contract with the
|
|
1510
|
+
* server is defined in exactly one place.
|
|
477
1511
|
*/
|
|
1512
|
+
/** Every text operator, in the order the filter UI lists them. */
|
|
478
1513
|
declare const TEXT_FILTER_TYPES: TextFilterType[];
|
|
1514
|
+
/** Every numeric operator, in the order the filter UI lists them. */
|
|
479
1515
|
declare const NUMBER_FILTER_TYPES: NumberFilterType[];
|
|
1516
|
+
/** Every date operator, in the order the filter UI lists them. */
|
|
480
1517
|
declare const DATE_FILTER_TYPES: DateFilterType[];
|
|
1518
|
+
/**
|
|
1519
|
+
* Human-readable label for each operator, e.g. `notEqual` → `'Not equal'`.
|
|
1520
|
+
*
|
|
1521
|
+
* Replace an entry to relabel an operator throughout the filter UI.
|
|
1522
|
+
*/
|
|
481
1523
|
declare const FILTER_TYPE_LABELS: Record<string, string>;
|
|
482
|
-
/**
|
|
1524
|
+
/**
|
|
1525
|
+
* Whether an operator takes no operand — `blank` and `notBlank`.
|
|
1526
|
+
*
|
|
1527
|
+
* @param type - The operator name.
|
|
1528
|
+
* @returns `true` when no value is needed.
|
|
1529
|
+
*/
|
|
483
1530
|
declare function isUnaryFilter(type: string): boolean;
|
|
1531
|
+
/**
|
|
1532
|
+
* Whether an operator takes two operands — currently only `inRange`.
|
|
1533
|
+
*
|
|
1534
|
+
* @param type - The operator name.
|
|
1535
|
+
* @returns `true` when both bounds are needed.
|
|
1536
|
+
*/
|
|
484
1537
|
declare function isRangeFilter(type: string): boolean;
|
|
1538
|
+
/**
|
|
1539
|
+
* The operator a filter starts on when its popover is first opened.
|
|
1540
|
+
*
|
|
1541
|
+
* `contains` for text, `equals` for numbers and dates.
|
|
1542
|
+
*
|
|
1543
|
+
* @param kind - The filter kind.
|
|
1544
|
+
* @returns The default operator name.
|
|
1545
|
+
*/
|
|
485
1546
|
declare function defaultFilterType(kind: FilterKind): string;
|
|
1547
|
+
/**
|
|
1548
|
+
* Builds a text filter, or `null` when there is nothing to send.
|
|
1549
|
+
*
|
|
1550
|
+
* @param type - The operator.
|
|
1551
|
+
* @param filter - The search term. Ignored for unary operators.
|
|
1552
|
+
* @returns The filter model, or `null` if a non-unary operator got a blank term.
|
|
1553
|
+
*
|
|
1554
|
+
* @example
|
|
1555
|
+
* ```ts
|
|
1556
|
+
* buildTextFilter('contains', 'acme');
|
|
1557
|
+
* // { filterType: 'text', type: 'contains', filter: 'acme' }
|
|
1558
|
+
* buildTextFilter('contains', ' '); // null
|
|
1559
|
+
* ```
|
|
1560
|
+
*/
|
|
486
1561
|
declare function buildTextFilter(type: TextFilterType, filter: string): HxFilterModel | null;
|
|
1562
|
+
/**
|
|
1563
|
+
* Builds a numeric filter, or `null` when the input is incomplete.
|
|
1564
|
+
*
|
|
1565
|
+
* @param type - The operator.
|
|
1566
|
+
* @param filter - The operand, or lower bound for `inRange`, as typed.
|
|
1567
|
+
* @param filterTo - The upper bound. Required for `inRange`.
|
|
1568
|
+
* @returns The filter model, or `null` if a required operand is missing or not
|
|
1569
|
+
* a number.
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```ts
|
|
1573
|
+
* buildNumberFilter('inRange', '10', '100');
|
|
1574
|
+
* // { filterType: 'number', type: 'inRange', filter: 10, filterTo: 100 }
|
|
1575
|
+
* buildNumberFilter('inRange', '10'); // null — no upper bound
|
|
1576
|
+
* ```
|
|
1577
|
+
*/
|
|
487
1578
|
declare function buildNumberFilter(type: NumberFilterType, filter: string, filterTo?: string): HxFilterModel | null;
|
|
1579
|
+
/**
|
|
1580
|
+
* Builds a date filter, or `null` when the input is incomplete.
|
|
1581
|
+
*
|
|
1582
|
+
* @param type - The operator.
|
|
1583
|
+
* @param dateFrom - Lower bound, formatted `YYYY-MM-DD`.
|
|
1584
|
+
* @param dateTo - Upper bound. Required for `inRange`.
|
|
1585
|
+
* @returns The filter model, or `null` if a required bound is missing.
|
|
1586
|
+
*/
|
|
488
1587
|
declare function buildDateFilter(type: DateFilterType, dateFrom: string, dateTo?: string): HxFilterModel | null;
|
|
1588
|
+
/**
|
|
1589
|
+
* Builds a set filter, or `null` when nothing is selected.
|
|
1590
|
+
*
|
|
1591
|
+
* Returning `null` rather than an empty set is what clears the filter — see
|
|
1592
|
+
* {@link withFilter}.
|
|
1593
|
+
*
|
|
1594
|
+
* @param values - The selected values.
|
|
1595
|
+
* @returns The filter model, or `null` for an empty selection.
|
|
1596
|
+
*/
|
|
489
1597
|
declare function buildSetFilter(values: string[]): HxFilterModel | null;
|
|
490
|
-
/**
|
|
1598
|
+
/**
|
|
1599
|
+
* Sets or clears one column's filter, returning a new map.
|
|
1600
|
+
*
|
|
1601
|
+
* Never mutates the map it is given, so the result is safe to hand straight to
|
|
1602
|
+
* `setState`.
|
|
1603
|
+
*
|
|
1604
|
+
* @param model - The current filter model.
|
|
1605
|
+
* @param colId - The column to change.
|
|
1606
|
+
* @param filter - The new filter, or `null` to remove the column's entry.
|
|
1607
|
+
* @returns A new filter model.
|
|
1608
|
+
*
|
|
1609
|
+
* @example
|
|
1610
|
+
* ```ts
|
|
1611
|
+
* const next = withFilter(filterModel, 'status', buildSetFilter(['ACTIVE']));
|
|
1612
|
+
* const cleared = withFilter(filterModel, 'status', null);
|
|
1613
|
+
* ```
|
|
1614
|
+
*/
|
|
491
1615
|
declare function withFilter(model: FilterModelMap, colId: string, filter: HxFilterModel | null): FilterModelMap;
|
|
492
|
-
/**
|
|
1616
|
+
/**
|
|
1617
|
+
* A short human-readable summary of a filter, for the floating filter input and
|
|
1618
|
+
* the header's active-filter indicator.
|
|
1619
|
+
*
|
|
1620
|
+
* @param filter - The filter to describe.
|
|
1621
|
+
* @returns A short label, e.g. `'Between 10 - 100'` or `'3 selected'`.
|
|
1622
|
+
*/
|
|
493
1623
|
declare function describeFilter(filter: HxFilterModel): string;
|
|
494
1624
|
|
|
1625
|
+
/**
|
|
1626
|
+
* Serialises rows to delimited text with a header line.
|
|
1627
|
+
*
|
|
1628
|
+
* Values are quoted per RFC 4180 when they contain the separator, a quote or a
|
|
1629
|
+
* newline. Columns marked {@link ColumnDef.suppressExport} are skipped, and
|
|
1630
|
+
* lines are joined with CRLF.
|
|
1631
|
+
*
|
|
1632
|
+
* @param rows - The rows to serialise.
|
|
1633
|
+
* @param columns - Columns to include, in output order.
|
|
1634
|
+
* @param separator - The field separator.
|
|
1635
|
+
* @returns The delimited document.
|
|
1636
|
+
*/
|
|
495
1637
|
declare function toDelimited<T>(rows: T[], columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>, separator: string): string;
|
|
1638
|
+
/**
|
|
1639
|
+
* Serialises rows to CSV.
|
|
1640
|
+
*
|
|
1641
|
+
* @param rows - The rows to serialise.
|
|
1642
|
+
* @param columns - Columns to include, in output order.
|
|
1643
|
+
* @param separator - Field separator.
|
|
1644
|
+
* @returns The CSV document, without a BOM — {@link downloadCsv} adds one.
|
|
1645
|
+
*
|
|
1646
|
+
* @example
|
|
1647
|
+
* ```ts
|
|
1648
|
+
* const csv = toCsv(api.getSelectedRows(), columns);
|
|
1649
|
+
* ```
|
|
1650
|
+
*/
|
|
496
1651
|
declare function toCsv<T>(rows: T[], columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>, separator?: string): string;
|
|
497
|
-
/**
|
|
1652
|
+
/**
|
|
1653
|
+
* Serialises rows to tab-separated text, which is what spreadsheets expect to
|
|
1654
|
+
* receive from the clipboard.
|
|
1655
|
+
*
|
|
1656
|
+
* @param rows - The rows to serialise.
|
|
1657
|
+
* @param columns - Columns to include, in output order.
|
|
1658
|
+
* @returns The TSV document.
|
|
1659
|
+
*/
|
|
498
1660
|
declare function toTsv<T>(rows: T[], columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>): string;
|
|
1661
|
+
/**
|
|
1662
|
+
* Triggers a browser download of CSV content.
|
|
1663
|
+
*
|
|
1664
|
+
* A UTF-8 BOM is prepended, which is what makes Excel read the file as UTF-8
|
|
1665
|
+
* rather than ANSI. The `.csv` extension is added if missing.
|
|
1666
|
+
*
|
|
1667
|
+
* @param content - The CSV document, e.g. from {@link toCsv}.
|
|
1668
|
+
* @param fileName - File name, with or without the extension.
|
|
1669
|
+
*/
|
|
499
1670
|
declare function downloadCsv(content: string, fileName: string): void;
|
|
1671
|
+
/**
|
|
1672
|
+
* Copies text to the clipboard, falling back to a hidden `textarea` on browsers
|
|
1673
|
+
* and non-secure origins without the async clipboard API.
|
|
1674
|
+
*
|
|
1675
|
+
* @param text - The text to copy.
|
|
1676
|
+
*/
|
|
500
1677
|
declare function copyToClipboard(text: string): Promise<void>;
|
|
501
1678
|
|
|
502
|
-
export { BUILTIN_EDITORS, type BuiltinEditor, type CellRendererParams, CheckboxEditor, type ColumnDef, type ColumnLayout, type ColumnLayoutItem, ColumnsPanel, DATE_FILTER_TYPES, DataGrid, type DataGridProps, DateEditor, type DateFilterModel, type DateFilterType, type EditorComponent, type EditorParams, type ExportCsvOptions, FILTER_TYPE_LABELS, type FilterKind, type FilterModelMap, FilterPopover, GRID_STATE_VERSION, type GridApi, GridOverlay, GridPagination, type HxDataSource, type HxFilterModel, type HxRowsRequest, type HxRowsResponse, NUMBER_FILTER_TYPES, NumberEditor, type NumberFilterModel, type NumberFilterType, type PersistedGridState, type Pinned, type ResolvedColumn, type RowCommitResult, type RowId, SelectEditor, type SelectOption, type SetFilterModel, type SortDirection, type SortModelItem, TEXT_FILTER_TYPES, TextEditor, type TextFilterModel, type TextFilterType, buildDateFilter, buildNumberFilter, buildSetFilter, buildTextFilter, columnId, copyToClipboard, defaultFilterType, describeFilter, downloadCsv, exportValue, formatValue, headerText, isEditable, isRangeFilter, isUnaryFilter, resolveColumn, resolveValue, toCsv, toDelimited, toTsv, useColumnState, useEditModel, useGridState, useSelectionModel, useServerDataSource, useVirtualRows, withFilter };
|
|
1679
|
+
export { BUILTIN_EDITORS, type BuiltinEditor, type CellRendererParams, CheckboxEditor, type ColumnDef, type ColumnLayout, type ColumnLayoutItem, type ColumnStateValue, ColumnsPanel, type ColumnsPanelProps, DATE_FILTER_TYPES, DataGrid, type DataGridProps, DateEditor, type DateFilterModel, type DateFilterType, type EditState, type EditorComponent, type EditorParams, type ExportCsvOptions, FILTER_TYPE_LABELS, type FilterKind, type FilterModelMap, FilterPopover, type FilterPopoverProps, GRID_STATE_VERSION, type GridApi, GridOverlay, type GridOverlayProps, GridPagination, type GridPaginationProps, type HxDataSource, type HxFilterModel, type HxRowsRequest, type HxRowsResponse, NUMBER_FILTER_TYPES, NumberEditor, type NumberFilterModel, type NumberFilterType, type PersistedGridState, type Pinned, type ResolvedColumn, type RowCommitResult, type RowId, SelectEditor, type SelectOption, type SetFilterModel, type SortDirection, type SortModelItem, TEXT_FILTER_TYPES, TextEditor, type TextFilterModel, type TextFilterType, type UseColumnStateResult, type UseEditModelResult, type UseGridStateResult, type UseSelectionModelResult, type UseServerDataSourceOptions, type UseServerDataSourceResult, type UseVirtualRowsOptions, type UseVirtualRowsResult, type VirtualWindow, buildDateFilter, buildNumberFilter, buildSetFilter, buildTextFilter, columnId, copyToClipboard, defaultFilterType, describeFilter, downloadCsv, exportValue, formatValue, headerText, isEditable, isRangeFilter, isUnaryFilter, resolveColumn, resolveValue, toCsv, toDelimited, toTsv, useColumnState, useEditModel, useGridState, useSelectionModel, useServerDataSource, useVirtualRows, withFilter };
|