@jielga/tmdatagrid 2.0.0-beta.2 → 2.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +5 -212
  2. package/dist/index.d.ts +1664 -632
  3. package/dist/index.js +5226 -3223
  4. package/dist/index.js.map +1 -1
  5. package/dist/styles.css +1 -1
  6. package/docs/anatomy.md +102 -0
  7. package/docs/cell-selection.md +154 -0
  8. package/docs/column-layout.md +204 -0
  9. package/docs/columns.md +262 -0
  10. package/docs/components.md +304 -0
  11. package/docs/editing.md +603 -0
  12. package/docs/editors.md +250 -0
  13. package/docs/export.md +326 -0
  14. package/docs/filtering.md +358 -0
  15. package/docs/getting-started.md +123 -0
  16. package/docs/grouping.md +165 -0
  17. package/docs/loading-and-empty.md +92 -0
  18. package/docs/localization.md +79 -0
  19. package/docs/menu.md +143 -0
  20. package/docs/pagination.md +144 -0
  21. package/docs/persistence.md +111 -0
  22. package/docs/portfolio-rebalancer.md +94 -0
  23. package/docs/query-builder.md +175 -0
  24. package/docs/quick-search.md +83 -0
  25. package/docs/row-details.md +113 -0
  26. package/docs/row-interaction.md +148 -0
  27. package/docs/row-pinning.md +132 -0
  28. package/docs/row-selection.md +134 -0
  29. package/docs/row-styling.md +133 -0
  30. package/docs/scrolling.md +111 -0
  31. package/docs/server-query.md +246 -0
  32. package/docs/server-side.md +206 -0
  33. package/docs/sorting.md +101 -0
  34. package/docs/styling.md +126 -0
  35. package/docs/summary-row.md +76 -0
  36. package/docs/testing.md +309 -0
  37. package/docs/toolbar.md +161 -0
  38. package/docs/use-tm-data-grid.md +361 -0
  39. package/package.json +21 -45
  40. package/skills/appearance/SKILL.md +70 -17
  41. package/skills/cell-selection/SKILL.md +70 -76
  42. package/skills/columns/SKILL.md +131 -32
  43. package/skills/data/SKILL.md +100 -23
  44. package/skills/editing/SKILL.md +217 -96
  45. package/skills/editing/references/common-mistakes.md +111 -24
  46. package/skills/editing/references/editing-api.md +63 -39
  47. package/skills/editing/references/editors-and-validation.md +77 -19
  48. package/skills/filtering/SKILL.md +148 -40
  49. package/skills/getting-started/SKILL.md +18 -16
  50. package/skills/grouping/SKILL.md +32 -15
  51. package/skills/options/SKILL.md +39 -9
  52. package/skills/rows/SKILL.md +22 -18
  53. package/skills/server-side/SKILL.md +170 -17
  54. package/skills/testing/SKILL.md +10 -7
  55. package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +7 -19
  56. package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +7 -1
  57. package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +39 -23
  58. package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +106 -38
  59. package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
  60. package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
  61. package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +4 -4
  62. package/src/components/TMDataGridDraftActions.tsx +307 -0
  63. package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +58 -50
  64. package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +150 -115
  65. package/src/components/TMDataGridExportPicker.module.css +77 -0
  66. package/src/components/TMDataGridExportPicker.tsx +234 -0
  67. package/src/components/TMDataGridFilterPanel.module.css +54 -0
  68. package/src/components/TMDataGridFilterPanel.tsx +348 -0
  69. package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +7 -5
  70. package/src/components/TMDataGridFilterSurface.module.css +54 -0
  71. package/src/components/TMDataGridFilterSurface.tsx +167 -0
  72. package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -13
  73. package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +4 -3
  74. package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +10 -0
  75. package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +100 -28
  76. package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
  77. package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
  78. package/src/components/TMDataGridMenu.tsx +354 -0
  79. package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +12 -7
  80. package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +90 -67
  81. package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +678 -156
  82. package/src/components/TMDataGridToolbar.module.css +21 -0
  83. package/src/components/TMDataGridToolbar.tsx +181 -0
  84. package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
  85. package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
  86. package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
  87. package/src/components/editors/TMDataGridNumberEditor.tsx +70 -0
  88. package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
  89. package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
  90. package/src/{tmdatagrid/components → components}/editors/editorShared.ts +17 -31
  91. package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
  92. package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
  93. package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
  94. package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
  95. package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
  96. package/src/components/filters/controlLayout.ts +32 -0
  97. package/src/components/filters/filterControlFor.ts +65 -0
  98. package/src/{tmdatagrid/components → components}/icons.ts +1 -0
  99. package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
  100. package/src/components/useHideableColumns.ts +52 -0
  101. package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
  102. package/src/{tmdatagrid/core → core}/capabilities.ts +14 -6
  103. package/src/{tmdatagrid/core → core}/columnOptions.ts +46 -0
  104. package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
  105. package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
  106. package/src/core/controlledState.ts +179 -0
  107. package/src/core/controlledStateSync.ts +108 -0
  108. package/src/core/deletedRows.ts +34 -0
  109. package/src/core/dom.ts +74 -0
  110. package/src/core/editEngine.ts +2476 -0
  111. package/src/{tmdatagrid/core → core}/editorFocus.ts +8 -4
  112. package/src/core/export.ts +843 -0
  113. package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
  114. package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
  115. package/src/core/filterSurface.ts +99 -0
  116. package/src/{tmdatagrid/core → core}/labels.ts +66 -8
  117. package/src/{tmdatagrid/core → core}/labelsSv.ts +26 -3
  118. package/src/core/pageReset.ts +120 -0
  119. package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
  120. package/src/core/resizePreview.ts +141 -0
  121. package/src/core/summary.ts +59 -0
  122. package/src/core/useSettledTableState.ts +36 -0
  123. package/src/{tmdatagrid/index.ts → index.ts} +75 -12
  124. package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +734 -135
  125. package/src/useTMDataGridExport.ts +78 -0
  126. package/src/tmdatagrid/components/TMDataGridEditActions.tsx +0 -162
  127. package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
  128. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
  129. package/src/tmdatagrid/components/TMDataGridToolbar.module.css +0 -12
  130. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -162
  131. package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +0 -40
  132. package/src/tmdatagrid/core/cellExport.ts +0 -320
  133. package/src/tmdatagrid/core/editEngine.ts +0 -1006
  134. package/src/tmdatagrid/core/summary.ts +0 -35
  135. /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
  136. /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
  137. /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
  138. /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
  139. /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
  140. /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
  141. /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
  142. /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
  143. /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
  144. /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
  145. /package/src/{tmdatagrid/core → core}/grouping.ts +0 -0
  146. /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
  147. /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
  148. /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
  149. /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
  150. /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
package/dist/index.d.ts CHANGED
@@ -1,89 +1,9 @@
1
- import { Cell, Column, ColumnPinningState, ExpandedState, Header, Row, RowData, RowSelectionState, Table, TableFeatures, TableOptions, TableState, aggregationFns } from "@tanstack/react-table";
1
+ import { BoxProps, MantineSize, MenuProps } from "@mantine/core";
2
2
  import { CSSProperties, ComponentType, MouseEvent, MutableRefObject, ReactNode } from "react";
3
- import { MantineSize, MenuProps } from "@mantine/core";
3
+ import { Cell, Column, ColumnFiltersState, ColumnPinningState, ExpandedState, Header, Row, RowData, RowSelectionState, Table, TableFeatures, TableOptions, TableState, aggregationFns } from "@tanstack/react-table";
4
4
  import { Store } from "@tanstack/store";
5
5
  import { AnyFieldApi, AnyFormApi, StandardSchemaV1 } from "@tanstack/react-form";
6
6
  import { RankingInfo } from "@tanstack/match-sorter-utils";
7
- //#region .types-tmp/components/TMDataGridColumnsPanel.d.ts
8
- /**
9
- * The "Manage columns" surface. Reachable from every column header menu and
10
- * from the grid's burger menu, so it lives on its own and is rendered by
11
- * `TMDataGrid.ColumnsButton`.
12
- */
13
- declare function TMDataGridColumnsPanel(): import("react").JSX.Element;
14
- //#endregion
15
- //#region .types-tmp/components/TMDataGridEditActions.d.ts
16
- /** What the edit chrome is showing. */
17
- type TMDataGridEditActionsState = {
18
- /** Rows with unsaved work: dirty edits, entry rows, and deletion marks. */
19
- pendingCount: number;
20
- /** Whether a submit is in flight. */
21
- isSubmitting: boolean;
22
- };
23
- /** What the edit chrome can do. */
24
- type TMDataGridEditActionsActions = {
25
- /** Commits every open row. Resolves `false` when a row stayed open. */
26
- save: () => Promise<boolean>;
27
- /** Drops every draft. */
28
- discard: () => void;
29
- };
30
- /** The pre-bound pieces of the built-in edit chrome. */
31
- type TMDataGridEditActionsControls = {
32
- /** Save, with the pending count, disabled while nothing is pending. */
33
- Save: () => ReactNode;
34
- /** Discard, disabled while nothing is pending. */
35
- Discard: () => ReactNode;
36
- };
37
- /** What {@link TMDataGridEditActionsProps.renderActions} is handed. */
38
- type TMDataGridEditActionsSlotArgs = {
39
- state: TMDataGridEditActionsState;
40
- actions: TMDataGridEditActionsActions;
41
- Controls: TMDataGridEditActionsControls;
42
- };
43
- type TMDataGridEditActionsProps = {
44
- /**
45
- * Replaces the built-in Save/Discard pair, and is handed the pieces of it.
46
- *
47
- * ```tsx
48
- * <TMDataGrid.EditActions
49
- * renderActions={({ state, Controls }) => (
50
- * <Group>
51
- * {state.pendingCount > 0 && <Badge>{state.pendingCount}</Badge>}
52
- * <Controls.Save />
53
- * <Controls.Discard />
54
- * </Group>
55
- * )}
56
- * />
57
- * ```
58
- */
59
- renderActions?: (args: TMDataGridEditActionsSlotArgs) => ReactNode;
60
- };
61
- /**
62
- * Draft mode's toolbar chrome: Save with the dirty-row count, and Discard.
63
- * Both read the edit store, so they grey out while nothing is dirty and the
64
- * Save spins while a submit is in flight. Works under any `editing.mode` - a
65
- * cellConfirm grid accumulating drafts can offer the same pair - and renders
66
- * nothing while editing is off.
67
- *
68
- * ```tsx
69
- * <TMDataGrid.Toolbar>
70
- * <TMDataGrid.SummaryCount />
71
- * <TMDataGrid.Spacer />
72
- * <TMDataGrid.EditActions />
73
- * </TMDataGrid.Toolbar>
74
- * ```
75
- */
76
- declare function TMDataGridEditActions({ renderActions }?: TMDataGridEditActionsProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
77
- //#endregion
78
- //#region .types-tmp/components/TMDataGridFilterPanel.d.ts
79
- /**
80
- * The MUI-style filter surface: one row per active column filter, each row a
81
- * column / operator / value triple. It only ever reads and writes the table's
82
- * `columnFilters` state, so a `manualFiltering` grid gets the same panel for
83
- * free - the state is forwarded to the server instead of a row model.
84
- */
85
- declare function TMDataGridFilterPanel(): import("react").JSX.Element | null;
86
- //#endregion
87
7
  //#region .types-tmp/core/sizes.d.ts
88
8
  type TMDataGridSize = MantineSize;
89
9
  declare const DEFAULT_TMDATAGRID_SIZE: TMDataGridSize;
@@ -113,28 +33,6 @@ type TMDataGridContextValue = TMDataGridApi<TMDataGridRowData> & {
113
33
  controlSize: TMDataGridSize;
114
34
  };
115
35
  declare function useTMDataGridContext(): TMDataGridContextValue;
116
- /**
117
- * What a control inside a *body* cell should put in its `tabIndex`.
118
- *
119
- * `-1` once cell selection is on, and this is what makes the promise of one tab
120
- * stop true. Without it the browser walks Tab into the checkbox of every
121
- * mounted row - a grid showing twenty rows would be twenty tab stops, and
122
- * scrolling would change how many. Enter or F2 steps into the cell instead,
123
- * which reaches a `-1` control perfectly well.
124
- *
125
- * Header controls are not covered: the header row is not part of cell
126
- * navigation, so its sort buttons and menus stay in the tab order, where they
127
- * are the only way to reach them.
128
- *
129
- * A custom cell renderer with a control in it wants the same:
130
- *
131
- * ```tsx
132
- * cell: ({ row }) => (
133
- * <Button tabIndex={useCellControlTabIndex()} onClick={...}>Open</Button>
134
- * )
135
- * ```
136
- */
137
- declare function useCellControlTabIndex(): 0 | -1;
138
36
  //#endregion
139
37
  //#region .types-tmp/core/columnOptions.d.ts
140
38
  /**
@@ -199,70 +97,23 @@ type ComboboxData = Array<ComboboxItem | {
199
97
  */
200
98
  declare function optionsToComboboxData(options: ReadonlyArray<TMDataGridOption>): ComboboxData;
201
99
  //#endregion
202
- //#region .types-tmp/core/filterOperators.d.ts
100
+ //#region .types-tmp/core/editEngine.d.ts
203
101
  /**
204
- * The value shape stored in `columnFilters` for every TMDataGrid column.
205
- *
206
- * TanStack resolves `filterFn` statically per column, so the operator travels
207
- * inside the filter *value* instead. That keeps the filter model plain,
208
- * serialisable JSON, so a server-side `manualFiltering` table can forward
209
- * `columnFilters` to the API unchanged.
102
+ * What counts as a commit - one axis, each mode a thin policy over the same
103
+ * engine. Where a commit *goes* is the other axis, `editing.draft`: out to
104
+ * the consumer, or into the draft store. See `editing` on
105
+ * `UseTMDataGridOptions`.
210
106
  *
211
- * `value` is a string array under `isAnyOf` / `isNoneOf` (the set the cell is
212
- * tested against), a `[min, max]` pair under `between` (an empty string means
213
- * that end is open), and a single string everywhere else - dates travel as
214
- * ISO `YYYY-MM-DD` strings, booleans as `"true"` / `"false"`. Still plain
215
- * JSON.
216
- */
217
- type TMDataGridFilterValue = {
218
- operator: TMDataGridFilterOperator;
219
- value: string | ReadonlyArray<string>;
220
- };
221
- type TMDataGridColumnType = "string" | "number" | "boolean" | "date" | "select" | "multiSelect";
222
- type TMDataGridFilterOperator = "contains" | "equals" | "notEquals" | "startsWith" | "endsWith" | "greaterThan" | "greaterThanOrEqual" | "lessThan" | "lessThanOrEqual" | "between" | "before" | "after" | "onOrBefore" | "onOrAfter" | "isAnyOf" | "isNoneOf" | "isEmpty" | "isNotEmpty";
223
- declare const FILTER_OPERATOR_LABELS: Record<TMDataGridFilterOperator, string>;
224
- declare function getOperatorsForType(type: TMDataGridColumnType): readonly TMDataGridFilterOperator[];
225
- declare function getDefaultOperator(type: TMDataGridColumnType): TMDataGridFilterOperator;
226
- declare function operatorNeedsValue(operator: TMDataGridFilterOperator): boolean;
227
- /** Whether the operator's value is a string array - `isAnyOf` / `isNoneOf`. */
228
- declare function operatorTakesArrayValue(operator: TMDataGridFilterOperator): boolean;
229
- /** Whether the operator's value is a `[min, max]` pair - `between`. */
230
- declare function operatorTakesRangeValue(operator: TMDataGridFilterOperator): boolean;
231
- /** The untouched value a fresh filter starts with - the operator's shape, empty. */
232
- declare function emptyValueForOperator(operator: TMDataGridFilterOperator): string | ReadonlyArray<string>;
233
- /**
234
- * A filter only narrows the row set once it has something to compare against.
235
- * Half-typed filters stay in state (so the panel keeps rendering their row) but
236
- * are treated as inactive for the funnel indicator and for row matching.
237
- */
238
- declare function isFilterActive(value: unknown): boolean;
239
- /**
240
- * One-line description of a single filter, as shown on a filter pill.
107
+ * | Mode | Enter | Tab | Focus leaves | Escape |
108
+ * | ---- | ----- | --- | ------------ | ------ |
109
+ * | `"cell"` | commits | commits, caret moves on | commits | cancels |
110
+ * | `"cellConfirm"` | commits | keeps the draft, caret moves on | keeps the draft | cancels |
111
+ * | `"row"` | commits the row | the browser's, along the row | nothing | cancels the row |
241
112
  *
242
- * The type's default operator is left implicit - "First name: Sofia" reads the
243
- * way a person would say it - while any other operator is spelled out, since
244
- * that is the part a reader cannot guess.
113
+ * An entry row is row-shaped in every mode - every editable cell open at
114
+ * once, the browser's Tab between them, and an explicit ✓.
245
115
  */
246
- declare function formatFilterLabel({ label, type, filter, operatorLabels }: {
247
- label: string;
248
- type: TMDataGridColumnType;
249
- filter: TMDataGridFilterValue;
250
- /** Localized operator names - `labels.operators`. Defaults to English. */
251
- operatorLabels?: Record<TMDataGridFilterOperator, string>;
252
- }): string;
253
- /**
254
- * The single filter function every TMDataGrid column uses. It dispatches on the
255
- * operator carried by the filter value, which is what lets one column offer
256
- * "contains" / "does not equal" / "is empty" without redefining the column.
257
- */
258
- declare function tmDataGridFilterFn<TFeatures extends TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown): boolean;
259
- //#endregion
260
- //#region .types-tmp/core/editEngine.d.ts
261
- /**
262
- * How commits happen - one axis, each mode a thin policy over the same
263
- * engine. See `editMode` on `UseTMDataGridOptions`.
264
- */
265
- type TMDataGridEditMode = "cell" | "cellConfirm" | "row" | "draft";
116
+ type TMDataGridEditMode = "cell" | "cellConfirm" | "row";
266
117
  /**
267
118
  * One editing row's live form. TanStack Form's `FormApi`, not a wrapper: the
268
119
  * engine is a form library, and everything mid-edit - values, dirty state,
@@ -315,6 +166,41 @@ type TMDataGridRowValidators = {
315
166
  onSubmitAsync?: TMDataGridValidator;
316
167
  onSubmitAsyncDebounceMs?: number;
317
168
  };
169
+ /** What `editing.tableValidators` is handed for one commit. */
170
+ type TMDataGridTableValidateArgs<TData extends RowData = TMDataGridRowData> = {
171
+ /** The committing row, as drafted. */
172
+ value: TData;
173
+ /** Its id - `addRow`'s temp id for an entry row. */
174
+ rowId: string;
175
+ /** Whether the row is an entry row, not yet in `data`. */
176
+ isNew: boolean;
177
+ /**
178
+ * The collection as it would stand if this commit landed: every data row
179
+ * overlaid with its draft where one is held (this row's `value` included),
180
+ * entry rows appended, deletion-marked rows removed. Unfiltered - a rule
181
+ * sees the whole collection whatever the view shows.
182
+ */
183
+ rows: ReadonlyArray<{
184
+ rowId: string;
185
+ value: TData;
186
+ }>;
187
+ };
188
+ /**
189
+ * `editing.tableValidators` - rules that need the other rows: no duplicate
190
+ * keys, no overlapping ranges, allocations summing to a total. Run at every
191
+ * commit, after the row's own validators, and again per committed row during
192
+ * `saveDrafts`, the only rules that run there - a committed row a later edit
193
+ * invalidated is reopened with the error and the save resolves `false`.
194
+ *
195
+ * Return nothing to pass, a message, or Form's `{ form, fields }` shape;
196
+ * pathed issues land on the committing row's cells, pathless ones on the row.
197
+ * `onSubmit` runs first, and its failure stands without `onSubmitAsync`
198
+ * running.
199
+ */
200
+ type TMDataGridTableValidators<TData extends RowData = TMDataGridRowData> = {
201
+ onSubmit?: (args: TMDataGridTableValidateArgs<TData>) => unknown;
202
+ onSubmitAsync?: (args: TMDataGridTableValidateArgs<TData>) => unknown | Promise<unknown>;
203
+ };
318
204
  /** One field's before/after across a commit. */
319
205
  type TMDataGridEditChange = {
320
206
  /** Column the field maps back to, for consumers thinking in columns. */
@@ -339,8 +225,20 @@ type TMDataGridEditCommitArgs<TData extends RowData> = {
339
225
  type TMDataGridEditRowProjection = {
340
226
  /** Field names whose value differs from the original. */
341
227
  dirtyFields: ReadonlyArray<string>;
342
- /** Field names carrying a validation error. */
228
+ /** Field names carrying a validation error, live or from a failed commit. */
343
229
  errorFields: ReadonlyArray<string>;
230
+ /**
231
+ * Those errors as text: what each cell editor is showing, plus what the
232
+ * row's last failed commit found. The second half is the reason this
233
+ * exists - Form clears a field's errors when its editor unmounts, so a row
234
+ * left invalid would go back to looking like an ordinary edited row. Such
235
+ * a message is dropped as soon as its field's value moves: the fix is what
236
+ * clears the mark.
237
+ */
238
+ errorMessages: ReadonlyArray<{
239
+ field: string;
240
+ message: string;
241
+ }>;
344
242
  /** A row-level error - a pathless `.refine()`, or a rejected commit. */
345
243
  hasRowError: boolean;
346
244
  isSubmitting: boolean;
@@ -368,26 +266,58 @@ type TMDataGridEditState = {
368
266
  columnId: string | null;
369
267
  } | null;
370
268
  /**
371
- * Rows with a live form. In cell mode at most one; in row, cellConfirm and
372
- * draft, as many as the user opened - which rows are editing.
269
+ * Every row the grid is holding work for: open rows, whose form is still
270
+ * undecided, and committed rows, whose values wait in the draft store. In
271
+ * the order the rows first entered; a reopen keeps a row's place. A row is
272
+ * *open* when it is in here and not in {@link committedRowIds}, or, for an
273
+ * entry row, not flagged `committed` in {@link newRows}.
373
274
  */
374
275
  openRowIds: ReadonlyArray<string>;
375
276
  rows: Record<string, TMDataGridEditRowProjection>;
376
277
  /**
377
- * Rows being created, not yet in `data`. `confirmed` is draft mode's
378
- * "entered, awaiting Save all": the entry row renders as a value row until
379
- * `begin` re-opens it. Under the immediate modes a confirm commits through
380
- * `onRowAdd` and the entry is dropped, so there it never turns `true`.
278
+ * The draft store's edit slice: existing rows that passed their commit and
279
+ * wait for `saveDrafts`. A committed row is data, not a form: its values
280
+ * are in {@link committedValues}, and `begin` on one of these builds a
281
+ * fresh form from them and takes the row back out.
282
+ *
283
+ * Only `editing.draft` commits into the store. Without it a commit goes
284
+ * straight to the consumer, so this stays empty.
285
+ */
286
+ committedRowIds: ReadonlyArray<string>;
287
+ /**
288
+ * The draft store's values, per row - what a committed row *is* to the
289
+ * table. Snapshotted when a row commits (existing and entry rows alike)
290
+ * and kept across a reopen until the row commits again or is dropped, so
291
+ * a row keeps its place in the sort while a second cell is being typed
292
+ * into. The hook feeds these into the table's `data` in place of the
293
+ * consumer's records, which is how sorting, filtering, grouping and
294
+ * aggregates see a draft.
295
+ */
296
+ committedValues: Readonly<Record<string, TMDataGridRowData>>;
297
+ /**
298
+ * Rows being created, not yet in `data`. `committed` is the draft store's
299
+ * add slice: the entry row passed its submit and renders as a value row
300
+ * from {@link committedValues} until `begin` re-opens it. Without
301
+ * `editing.draft` a commit adds through `onRowAdd` and the entry is
302
+ * dropped, so it never turns `true`.
381
303
  */
382
304
  newRows: ReadonlyArray<{
383
305
  tempId: string;
384
- confirmed: boolean;
306
+ committed: boolean;
385
307
  }>;
386
- /** Rows marked deleted under draft mode. */
308
+ /** The draft store's delete slice: rows marked deleted, awaiting the save. */
387
309
  deletedRowIds: ReadonlyArray<string>;
310
+ /**
311
+ * `true` while `saveDrafts` is in flight - from the call until the
312
+ * consumer's callbacks (`onSaveDrafts`, or the per-row `onCommit` /
313
+ * `onRowAdd` / `onRowDelete` loop) have settled. Concurrent `saveDrafts`
314
+ * calls join the same run, so it flips once per run. It stays `false` for
315
+ * a save that finds nothing to send.
316
+ */
317
+ isSaving: boolean;
388
318
  };
389
- type ErasedRow = Row<TMDataGridFeatures, TMDataGridRowData>;
390
- type ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;
319
+ type ErasedRow$1 = Row<TMDataGridFeatures, TMDataGridRowData>;
320
+ type ErasedColumn$1 = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;
391
321
  /**
392
322
  * What a cell editor is handed - deliberately both vocabularies at once. The
393
323
  * form side is TanStack Form's real `field` API (`field.state.value`,
@@ -405,8 +335,8 @@ type TMDataGridEditorArgs = {
405
335
  /** The whole row form, for the rare editor that reads sibling fields. */
406
336
  form: TMDataGridRowEditForm;
407
337
  cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;
408
- row: ErasedRow;
409
- column: ErasedColumn;
338
+ row: ErasedRow$1;
339
+ column: ErasedColumn$1;
410
340
  table: TMDataGridTable<TMDataGridRowData>;
411
341
  /** What Enter would do - commit the edit. For the editor's own UI. */
412
342
  commit: () => Promise<boolean>;
@@ -431,8 +361,8 @@ type TMDataGridEditValueMapArgs = {
431
361
  value: unknown;
432
362
  /** What the field held before this write - for length-aware masks. */
433
363
  previous: unknown;
434
- row: ErasedRow;
435
- column: ErasedColumn;
364
+ row: ErasedRow$1;
365
+ column: ErasedColumn$1;
436
366
  table: TMDataGridTable<TMDataGridRowData>;
437
367
  };
438
368
  /**
@@ -493,7 +423,7 @@ type TMDataGridColumnEditOptions = {
493
423
  */
494
424
  mapValue?: TMDataGridEditValueMap;
495
425
  };
496
- /** A new row being committed - `onRowAdd`, and `submitAll`'s `added`. */
426
+ /** A new row being committed - `onRowAdd`, and `saveDrafts`'s `created`. */
497
427
  type TMDataGridRowAddArgs<TData extends RowData> = {
498
428
  /** The engine's placeholder id; the real id is the consumer's to mint. */
499
429
  tempId: string;
@@ -504,15 +434,51 @@ type TMDataGridRowDeleteArgs<TData extends RowData> = {
504
434
  rowId: string;
505
435
  row: Row<TMDataGridFeatures, TData>;
506
436
  };
507
- /** What `submitAll` hands `onEditCommitDrafts` - everything pending at once. */
508
- type TMDataGridEditCommitDraftsArgs<TData extends RowData> = {
509
- /** Every valid dirty existing row. */
510
- rows: Array<TMDataGridEditCommitArgs<TData>>;
511
- /** Every valid new row from the entry block. */
512
- added: Array<TMDataGridRowAddArgs<TData>>;
437
+ /**
438
+ * The draft store, flushed - what `saveDrafts` hands `onSaveDrafts`. Every
439
+ * committed change at once, so a server can apply it as one transaction.
440
+ * Rows still open (undecided form state) are not in here and stay open.
441
+ */
442
+ type TMDataGridSaveDraftsArgs<TData extends RowData> = {
443
+ /** Committed edits to existing rows; each entry carries its `rowId`. */
444
+ updated: Array<TMDataGridEditCommitArgs<TData>>;
445
+ /** Committed new rows from the entry block; each entry carries its `tempId`. */
446
+ created: Array<TMDataGridRowAddArgs<TData>>;
513
447
  /** Ids marked deleted while the drafts accumulated. */
514
448
  deleted: Array<string>;
449
+ /** @deprecated Renamed to {@link updated}. Removed in a later beta. */
450
+ rows: Array<TMDataGridEditCommitArgs<TData>>;
451
+ /** @deprecated Renamed to {@link created}. Removed in a later beta. */
452
+ added: Array<TMDataGridRowAddArgs<TData>>;
453
+ };
454
+ /**
455
+ * Which entries of one bucket saved. `true`, or an id the map does not name,
456
+ * saved and is dropped from the draft store; `false` failed and keeps its
457
+ * draft. A bare boolean answers for the whole bucket.
458
+ */
459
+ type TMDataGridSaveOutcomes = boolean | Record<string, boolean>;
460
+ /**
461
+ * What `onSaveDrafts` may return to save part of the store.
462
+ *
463
+ * Returning nothing saves everything, and throwing saves nothing. Between
464
+ * those, name the ids that failed: they keep their drafts, committed and
465
+ * ready for the next save, while the rest are dropped. The grid marks them
466
+ * with nothing beyond the state itself - a failed edit keeps `data-draft`,
467
+ * a failed deletion keeps `data-deleted` - so the display is the consumer's.
468
+ */
469
+ type TMDataGridSaveDraftsResult = {
470
+ /** Keyed by `rowId`. */
471
+ updated?: TMDataGridSaveOutcomes;
472
+ /** Keyed by `tempId`. */
473
+ created?: TMDataGridSaveOutcomes;
474
+ /** Keyed by `rowId`. */
475
+ deleted?: TMDataGridSaveOutcomes;
515
476
  };
477
+ /**
478
+ * @deprecated Renamed to {@link TMDataGridSaveDraftsArgs} - the payload is
479
+ * the draft store being saved, not a commit. Removed in a later beta.
480
+ */
481
+ type TMDataGridEditCommitDraftsArgs<TData extends RowData> = TMDataGridSaveDraftsArgs<TData>;
516
482
  /**
517
483
  * The data path a column edits, or `null` for a column that has none.
518
484
  *
@@ -534,27 +500,83 @@ declare function getEditFieldName(column: {
534
500
  }): string | null;
535
501
  /** What Delete writes into a cell - the type's honest empty value. */
536
502
  declare function clearedValueForType(type: TMDataGridColumnType): unknown;
503
+ /** `edit.addRows` options. */
504
+ type TMDataGridAddRowsOptions = {
505
+ /**
506
+ * Submit each row as it is added instead of leaving it open. Defaults to
507
+ * `false` - the rows open as editable entry rows, as `addRow` does.
508
+ */
509
+ commit?: boolean;
510
+ };
511
+ /** What `edit.addRows` reports back. Every added row is in exactly one list. */
512
+ type TMDataGridAddRowsResult = {
513
+ /** Temp ids that committed - parked as drafts, or added outright. */
514
+ committed: Array<string>;
515
+ /**
516
+ * Temp ids still open in the entry block: everything, when `commit` was
517
+ * not asked for; the rows that failed validation, when it was.
518
+ */
519
+ open: Array<string>;
520
+ };
521
+ /** One row of {@link TMDataGridEditApi.getRows}. */
522
+ type TMDataGridEditRowSnapshot<TData extends RowData = TMDataGridRowData> = {
523
+ /** The row's id - `addRow`'s temp id for an entry row. */
524
+ rowId: string;
525
+ /** The row as shown: its draft where a form holds one, else `data`'s value. */
526
+ value: TData;
527
+ /** An entry row, not yet in `data`. */
528
+ isNew: boolean;
529
+ /** Marked deleted, awaiting `saveDrafts`. */
530
+ deleted: boolean;
531
+ };
537
532
  /**
538
533
  * The engine plus its store - `api.edit`.
539
534
  *
540
- * "One row, one form": `getForm` hands out the same `FormApi` the inline
541
- * editors write through, so a consumer can render it in a drawer or a detail
542
- * panel and share values, dirty state and errors with the cells.
535
+ * "One row, one form" while a row is open: `getForm` hands out the same
536
+ * `FormApi` the inline editors write through, so a consumer can render it in
537
+ * a drawer or a detail panel and share values, dirty state and errors with
538
+ * the cells. A committed row has no form - it is data in the draft store -
539
+ * so `getForm` returns `undefined` for it until `begin` reopens it.
543
540
  */
544
- type TMDataGridEditApi = {
541
+ type TMDataGridEditApi<TData extends RowData = TMDataGridRowData> = {
545
542
  /** The projection store - subscribe with `useSelector(edit.store, …)`. */
546
543
  store: Store<TMDataGridEditState>;
547
544
  /** Current snapshot, for reads outside React. */
548
545
  readonly state: TMDataGridEditState;
549
- /** rowId → live form. The source of truth for everything mid-edit. */
546
+ /**
547
+ * rowId → the open row's live form, the source of truth for everything
548
+ * mid-edit. `undefined` for a row that is not open, a committed row
549
+ * included; `begin` reopens one.
550
+ */
550
551
  getForm: (rowId: string) => TMDataGridRowEditForm | undefined;
552
+ /**
553
+ * The row as shown: its draft values where the grid holds any - an open
554
+ * form's, or the committed values in the draft store - else what `data`
555
+ * says. `undefined` when no such row exists. A deletion mark does not
556
+ * change the answer; check `state.deletedRowIds` for that.
557
+ */
558
+ getRowValues: (rowId: string) => TData | undefined;
559
+ /**
560
+ * Every row as shown, nothing filtered out: data rows overlaid with their
561
+ * drafts, entry rows appended, deletion-marked rows included and flagged.
562
+ * Built from the core row model, so it is unfiltered, unsorted and never
563
+ * contains group rows. Filter on `deleted` / `isNew` for the set you want.
564
+ */
565
+ getRows: () => ReadonlyArray<TMDataGridEditRowSnapshot<TData>>;
551
566
  /**
552
567
  * Whether this cell may open an editor: the column maps to a field, nothing
553
568
  * switched it off, and the row takes edits at all.
554
569
  */
555
- canEditCell: (row: ErasedRow, column: ErasedColumn) => boolean;
570
+ canEditCell: (row: ErasedRow$1, column: ErasedColumn$1) => boolean;
556
571
  /** Whether the row takes edits at all - the edit lane's pencil gate. */
557
- canEditRow: (row: ErasedRow) => boolean;
572
+ canEditRow: (row: ErasedRow$1) => boolean;
573
+ /**
574
+ * Whether the column takes edits at all, with no row in hand: it maps to a
575
+ * field, `editing.columns` lists it if that option is set, and
576
+ * `meta.edit.enabled` is not `false`. A per-row `enabled` predicate is the
577
+ * row's half of the question - `canEditCell` asks both.
578
+ */
579
+ isColumnEditable: (column: ErasedColumn$1) => boolean;
558
580
  /**
559
581
  * Opens an editor. In row mode the whole row opens either way and `columnId`
560
582
  * only says which cell takes the caret; `null` (the lane's pencil) leaves it
@@ -577,26 +599,102 @@ type TMDataGridEditApi = {
577
599
  * `"cellConfirm"`, where the dirty cell keeps waiting for its ✓.
578
600
  */
579
601
  deactivate: () => void;
580
- /** Drops every draft. */
602
+ /** Drops every draft - open form state and the draft store alike. */
581
603
  cancelAll: () => void;
582
- /** Commits every open row - draft mode's save. `true` when all landed. */
604
+ /**
605
+ * Submits every open row, as if each had been OK'd: a row that validates
606
+ * commits (into the draft store with `editing.draft` on, straight to the
607
+ * consumer without it), a row that fails stays open with its errors.
608
+ * `true` when every row committed. Under `editing.draft` it sends nothing
609
+ * to the consumer by itself - that is `saveDrafts`.
610
+ */
611
+ commitAll: () => Promise<boolean>;
612
+ /**
613
+ * Flushes the draft store: every committed edit, added row and deletion
614
+ * mark reaches the consumer, through `onSaveDrafts` in one call when it is
615
+ * set, or row by row through `onCommit` / `onRowAdd` / `onRowDelete`.
616
+ *
617
+ * Rows still open are left alone - they keep their form state and stay
618
+ * open. `true` when everything landed; a rejected save keeps every draft.
619
+ */
620
+ saveDrafts: () => Promise<boolean>;
621
+ /**
622
+ * @deprecated Split into {@link commitAll} and {@link saveDrafts}, which is
623
+ * exactly what this now does. Removed in a later beta.
624
+ */
583
625
  submitAll: () => Promise<boolean>;
584
626
  /** Writes the type's empty value into a cell and commits it - Delete. */
585
627
  clearCell: (rowId: string, columnId: string) => Promise<boolean>;
628
+ /**
629
+ * Writes one cell and commits the row - a typed edit without the typing,
630
+ * for toolbar actions and bulk fills. Under `editing.draft` the row parks
631
+ * in the draft store exactly as a hand-made edit does, so it carries the
632
+ * same change markers and the same per-row revert.
633
+ *
634
+ * The row need not be mounted; a row inside a collapsed group takes the
635
+ * write. Resolves `false` when the cell takes no edit - no such row or
636
+ * column, `editing.columns` excludes it, `meta.edit.enabled` is off, or the
637
+ * row is not editable - and when validation refuses the value, which leaves
638
+ * the row open carrying its errors.
639
+ *
640
+ * `value` is the stored value: no editor runs, so `meta.edit.mapValue`
641
+ * does not either. `meta.edit.validate` does.
642
+ */
643
+ setCellValue: (rowId: string, columnId: string, value: unknown) => Promise<boolean>;
644
+ /**
645
+ * {@link setCellValue} for several cells of one row, in a single commit -
646
+ * one consumer call and one draft entry rather than one per column. Keys
647
+ * are column ids.
648
+ *
649
+ * All or nothing: if any named cell takes no edit, nothing is written and
650
+ * this resolves `false`.
651
+ */
652
+ setRowValues: (rowId: string, values: Record<string, unknown>) => Promise<boolean>;
586
653
  /**
587
654
  * Opens a new entry row (the sticky block under the header) seeded from
588
- * `newRowDefaults`. Returns its temporary id - a form with no backing row
589
- * yet. Committing it calls `onRowAdd` (immediate modes) or joins
590
- * `submitAll`'s `added` (draft).
655
+ * `newRowDefaults`. `values` overrides that seed key by key, so
656
+ * `addRow()` opens a blank row and `addRow({ status: "draft" })` opens one
657
+ * that starts filled in. Returns its temporary id - a form with no backing
658
+ * row yet. Committing it calls `onRowAdd`, or parks it for `saveDrafts`
659
+ * under `editing.draft`.
660
+ */
661
+ addRow: (values?: Partial<TData>) => string;
662
+ /**
663
+ * Opens entry rows for a list of records at once - one publish for the
664
+ * batch, where a loop over `addRow` is one per row. Each row is seeded over
665
+ * `newRowDefaults` exactly as `addRow` does.
666
+ *
667
+ * `commit: true` submits the rows too, which is what an import wants: rows
668
+ * that validate commit, and rows that fail stay open in the entry block
669
+ * carrying their errors, for the user to fix. The result says which went
670
+ * which way. Under `editing.draft` the rows validate together and land in
671
+ * the draft store in the same publish as the add - the grid renders once,
672
+ * whatever the count. Without it each valid row goes out through
673
+ * `onRowAdd`, one at a time and in order.
591
674
  */
592
- addRow: () => string;
675
+ addRows: (rows: ReadonlyArray<Partial<TData>>, options?: TMDataGridAddRowsOptions) => Promise<TMDataGridAddRowsResult>;
593
676
  /**
594
- * Deletes a row: `onRowDelete` straight away under the immediate modes;
595
- * under draft it toggles the id in `deletedRowIds` - the row renders
596
- * struck through until `submitAll` reports it. On an uncommitted entry
597
- * row it just discards the entry.
677
+ * Deletes a row: `onRowDelete` straight away, or under `editing.draft` a
678
+ * mark in `deletedRowIds` - the row renders struck through until
679
+ * `saveDrafts` reports it. Idempotent: deleting a marked row again leaves
680
+ * it marked, and {@link restoreRow} is the undo. On an entry row,
681
+ * committed or not, it just discards the entry; an id the grid does not
682
+ * know is a no-op.
598
683
  */
599
684
  deleteRow: (rowId: string) => void;
685
+ /**
686
+ * {@link deleteRow} for several rows in one call - one notification for
687
+ * the batch, for a bulk action over a selection. Because `deleteRow` is
688
+ * idempotent and ignores unknown ids, the list may be passed exactly as
689
+ * the selection stands - already-marked rows stay marked, duplicates and
690
+ * stale ids do nothing.
691
+ */
692
+ deleteRows: (rowIds: ReadonlyArray<string>) => void;
693
+ /**
694
+ * Removes a row's deletion mark - the lane's Restore. A no-op on a row
695
+ * that is not marked, and outside `editing.draft`, where no marks exist.
696
+ */
697
+ restoreRow: (rowId: string) => void;
600
698
  /** Whether delete chrome makes sense - the lane's trash gate. */
601
699
  canDeleteRows: () => boolean;
602
700
  };
@@ -619,13 +717,15 @@ declare function normalizeFieldValidate(validate: TMDataGridFieldValidate | unde
619
717
  type TMDataGridLabels = {
620
718
  /** Filter operator names, as shown in the operator dropdown and on pills. */
621
719
  operators: Record<TMDataGridFilterOperator, string>;
622
- /** "Manage columns" - the burger button and the header menu item. */
623
- manageColumns: string;
624
720
  /** "Filters" - the funnel button and the filter panel's title. */
625
721
  filters: string;
626
722
  searchPlaceholder: string;
627
723
  searchLabel: string;
628
724
  clearSearch: string;
725
+ /** Tooltip and `aria-label` of `TMDataGrid.Menu`'s burger trigger. */
726
+ menuButton: string;
727
+ /** "Manage columns" - the header menu's submenu. */
728
+ manageColumns: string;
629
729
  columnsSearchPlaceholder: string;
630
730
  columnsNoMatch: (search: string) => string;
631
731
  columnsShowHideAll: string;
@@ -656,6 +756,8 @@ type TMDataGridLabels = {
656
756
  clearAllFilters: string;
657
757
  closeFilters: string;
658
758
  removeFilter: string;
759
+ /** Names the operator button in a column's header filter control. */
760
+ filterOperatorFor: (column: string) => string;
659
761
  activeFilters: string;
660
762
  clearFilter: (column: string) => string;
661
763
  sortAsc: string;
@@ -681,6 +783,11 @@ type TMDataGridLabels = {
681
783
  to: number;
682
784
  total: number;
683
785
  }) => string;
786
+ /** `pageCount` is `-1` when a manual grid declares an unknown total. */
787
+ pageNumber: (args: {
788
+ page: number;
789
+ pageCount: number;
790
+ }) => string;
684
791
  groupedAllRows: (total: number) => string;
685
792
  pagingSuspendedHint: string;
686
793
  previousPage: string;
@@ -703,10 +810,15 @@ type TMDataGridLabels = {
703
810
  cancelRowEdit: string;
704
811
  /** Save tooltip when field errors block the row, with no row message. */
705
812
  editRowErrors: string;
706
- /** `EditActions`' Save, with the dirty-row count. */
813
+ /** `DraftActions`' Save, with the count of rows in the draft store. */
707
814
  saveAllEdits: (rows: number) => string;
708
- /** `EditActions`' Discard. */
815
+ /** `DraftActions`' Discard. */
709
816
  discardAllEdits: string;
817
+ /**
818
+ * `DraftActions`' note about rows still open - edited but not committed, so
819
+ * not part of the save. Shown only while there are any.
820
+ */
821
+ editRowsStillOpen: (rows: number) => string;
710
822
  /** The entry row's ✓ - commit the add. */
711
823
  confirmNewRow: string;
712
824
  /** The entry row's ✕ - drop the entry. */
@@ -725,8 +837,24 @@ type TMDataGridLabels = {
725
837
  rowStateDeleted: string;
726
838
  cellCount: (count: number) => string;
727
839
  copy: string;
728
- exportCsv: string;
840
+ exportCells: string;
841
+ /** @deprecated Use `exportCells`. Read as its fallback for one beta. */
842
+ exportCsv?: string;
729
843
  includeHeaders: string;
844
+ exportAll: string;
845
+ exportSelected: (count: number) => string;
846
+ /** Title of the column picker `columns="custom"` opens; `format` is the file extension in upper case, "CSV". */
847
+ exportPickerTitle: (format: string) => string;
848
+ /** The line under the title; `selected` is the selected row count, or `null` for an export of all rows. */
849
+ exportPickerHint: (selected: number | null) => string;
850
+ exportPickerConfirm: string;
851
+ exportPickerCancel: string;
852
+ /** The select-all row over the picker's list. */
853
+ exportPickerSelectAll: string;
854
+ /** The "3 of 12" count beside it. */
855
+ exportPickerCount: (checked: number, total: number) => string;
856
+ /** Marks a column the grid hides at the moment. */
857
+ exportPickerHidden: string;
730
858
  selectColumnLabel: string;
731
859
  selectAllRows: string;
732
860
  selectRow: string;
@@ -781,7 +909,30 @@ type TMDataGridFilterControlArgs = {
781
909
  options: ReadonlyArray<TMDataGridOption>;
782
910
  size: TMDataGridSize;
783
911
  labels: TMDataGridLabels;
912
+ /**
913
+ * How much room the control has, and whether it names itself. The same
914
+ * vocabulary as `TMDataGrid.FilterPanel`'s own `layout` prop, plus the one
915
+ * value only a header cell can be in.
916
+ *
917
+ * | Layout | Where | Field |
918
+ * | --- | --- | --- |
919
+ * | `"row"` | A filter row laid out side by side | Labelled, fixed width |
920
+ * | `"stacked"` | A filter row in a narrow host - the sidebar | Labelled, full width |
921
+ * | `"header"` | One header cell, under `filters.inHeader` | `aria-label`, full width |
922
+ *
923
+ * Every built-in control honours it. A custom control that ignores it still
924
+ * works - it will simply look the same everywhere.
925
+ */
926
+ layout: TMDataGridFilterControlLayout;
784
927
  };
928
+ /** How much room a filter control has. See `layout`. */
929
+ type TMDataGridFilterControlLayout = "row" | "stacked" | "header";
930
+ /**
931
+ * The two a filter *panel* can be in - {@link TMDataGridFilterControlLayout}
932
+ * without the header cell, which is not a panel. `TMDataGrid.FilterPanel`'s
933
+ * `layout` prop.
934
+ */
935
+ type TMDataGridFilterPanelLayout = Exclude<TMDataGridFilterControlLayout, "header">;
785
936
  /**
786
937
  * `meta.filter.control` - replaces the built-in value control for this column.
787
938
  * Rendered as JSX, never invoked as a bare function, so hooks are legal
@@ -802,10 +953,19 @@ type TMDataGridFilterControlComponent = ComponentType<TMDataGridFilterControlArg
802
953
  * declaration of each feeds the filter panel and the cell editor alike.
803
954
  */
804
955
  type TMDataGridColumnFilterOptions = {
956
+ /**
957
+ * The operators this column offers, a subset of the type's own. For a
958
+ * column backed by an endpoint that answers only some of them - `contains`
959
+ * and `equals`, say - so the panel and the header funnel never offer an
960
+ * operator the query cannot express. Kept in the type's order; one the type
961
+ * does not offer is ignored, and a list that leaves nothing falls back to
962
+ * the type's full set.
963
+ */
964
+ operators?: readonly TMDataGridFilterOperator[];
805
965
  /**
806
966
  * The operator a fresh filter on this column starts with, instead of the
807
967
  * type's default - a salary column can open on `"between"`. Must be one of
808
- * the type's own operators.
968
+ * the operators the column offers.
809
969
  */
810
970
  defaultOperator?: TMDataGridFilterOperator;
811
971
  /**
@@ -815,6 +975,83 @@ type TMDataGridColumnFilterOptions = {
815
975
  control?: TMDataGridFilterControlComponent;
816
976
  };
817
977
  //#endregion
978
+ //#region .types-tmp/core/filterSurface.d.ts
979
+ /**
980
+ * Where the grid puts its filter controls.
981
+ *
982
+ * | Surface | Where it renders |
983
+ * | --- | --- |
984
+ * | `"popup"` | Floating over the first body rows, under the header |
985
+ * | `"sidebar"` | Beside the table, inside the grid frame |
986
+ * | `"none"` | Nowhere - the grid renders no panel of its own |
987
+ *
988
+ * Header filters are not one of these: they are a second row of controls in
989
+ * the header, always visible, and they coexist with any of the three. See
990
+ * {@link TMDataGridFiltersOptions.inHeader}.
991
+ */
992
+ type TMDataGridFilterSurface = "popup" | "sidebar" | "none";
993
+ /** Which side of the table the sidebar surface renders on. */
994
+ type TMDataGridFilterSidebarSide = "left" | "right";
995
+ /**
996
+ * `filters` on `useTMDataGrid` - everything about where the filter controls
997
+ * are, as opposed to what they do.
998
+ *
999
+ * Named for the option key, the way `editing` has `TMDataGridEditingOptions`.
1000
+ * Not to be confused with `TMDataGridColumnFilterOptions`, which is one
1001
+ * column's `meta.filter`.
1002
+ *
1003
+ * ```tsx
1004
+ * useTMDataGrid({ data, columns, filters: { surface: "sidebar" } });
1005
+ * ```
1006
+ */
1007
+ type TMDataGridFiltersOptions = {
1008
+ /**
1009
+ * Which surface `TMDataGrid.Table` renders and `TMDataGrid.FilterButton`
1010
+ * toggles. Defaults to `"popup"`.
1011
+ *
1012
+ * Under `"none"` the table renders no panel and the filter button renders
1013
+ * nothing. That is what a grid running header filters alone wants, and it is
1014
+ * also what frees a hand-placed `<TMDataGrid.FilterPanel />` to be the only
1015
+ * panel on the page - mounted, it is always visible, so drive it off
1016
+ * `ui.state.filterPanelOpen` if it belongs behind a control of your own.
1017
+ */
1018
+ surface?: TMDataGridFilterSurface;
1019
+ /** Which side the `"sidebar"` surface sits on. Defaults to `"right"`. */
1020
+ sidebarSide?: TMDataGridFilterSidebarSide;
1021
+ /** Width of the `"sidebar"` surface, any CSS length. Defaults to `"280px"`. */
1022
+ sidebarWidth?: string;
1023
+ /**
1024
+ * Whether the popup or the sidebar starts open. Read once, at mount, like
1025
+ * `initialState`.
1026
+ *
1027
+ * Defaults to `true` under `"sidebar"` and `false` everywhere else: a
1028
+ * sidebar is a layout choice, so asking for one and getting an empty strip
1029
+ * until the funnel is clicked is not what it reads like, while a popup that
1030
+ * greets you open is in the way.
1031
+ *
1032
+ * Under `"none"` it is simply the starting value of
1033
+ * `ui.state.filterPanelOpen`, which a control of your own can read.
1034
+ */
1035
+ defaultOpen?: boolean;
1036
+ /**
1037
+ * A second header row holding one value control per filterable column,
1038
+ * always visible. Off by default.
1039
+ *
1040
+ * Independent of `surface` - a grid may have header filters and a popup at
1041
+ * once. What it does change is the column chrome: the header's funnel
1042
+ * indicator and the column menu's "Filter" item both come off, because
1043
+ * their only job was to reveal a control that is now already on screen.
1044
+ *
1045
+ * A header cell has room for a value and an operator button, not for the
1046
+ * panel's column / operator / value triple. Everything else about a filter
1047
+ * is unchanged - the same operators, the same `meta.filter.control`, the
1048
+ * same `columnFilters` state.
1049
+ */
1050
+ inHeader?: boolean;
1051
+ };
1052
+ /** {@link TMDataGridFiltersOptions} with every default filled in. */
1053
+ type TMDataGridFiltersSettings = Required<TMDataGridFiltersOptions>;
1054
+ //#endregion
818
1055
  //#region .types-tmp/core/quickSearch.d.ts
819
1056
  /** How the quick search matches - see `quickSearchMode` on the hook options. */
820
1057
  type TMDataGridQuickSearchMode = "fuzzy" | "contains";
@@ -1005,13 +1242,20 @@ type TMDataGridFeatureFlags = {
1005
1242
  grouping: boolean;
1006
1243
  /** Whether cells can be edited at all - the `editing` option was set. */
1007
1244
  editing: boolean;
1008
- /** The commit policy, or `null` while editing is off. */
1245
+ /** What counts as a commit, or `null` while editing is off. */
1009
1246
  editMode: TMDataGridEditMode | null;
1010
1247
  /**
1011
- * Whether a confirmed entry row stays pinned in the sticky entry block
1012
- * until Save all - `editing.newRowsSticky`, draft mode only. Off by
1013
- * default: a confirmed row joins the scrolling flow instead, so entering
1014
- * many rows cannot fill the viewport with sticky chrome.
1248
+ * Where a commit goes - `editing.draft`. On, commits park in the grid's
1249
+ * draft store and leave through `edit.saveDrafts()`; off, each one reaches
1250
+ * the consumer as it happens.
1251
+ */
1252
+ editDraft: boolean;
1253
+ /**
1254
+ * Whether a committed entry row stays pinned in the sticky entry block
1255
+ * until the draft store is saved - `editing.newRowsSticky`, which needs
1256
+ * `editing.draft`. Off by default: a committed row joins the body rows
1257
+ * instead, sorted and filtered with them, so entering many rows cannot
1258
+ * fill the viewport with sticky chrome.
1015
1259
  */
1016
1260
  editNewRowsSticky: boolean;
1017
1261
  /** The generated row-number gutter - `enableRowNumbers`. Off by default. */
@@ -1182,27 +1426,361 @@ declare function boundsEdges(bounds: TMDataGridRangeBounds | null, rowIndex: num
1182
1426
  right: boolean;
1183
1427
  } | null;
1184
1428
  //#endregion
1185
- //#region .types-tmp/useTMDataGrid.d.ts
1429
+ //#region .types-tmp/core/export.d.ts
1430
+ type ErasedRow = Row<TMDataGridFeatures, TMDataGridRowData>;
1431
+ type ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;
1186
1432
  /**
1187
- * Per-column configuration the grid's own components read.
1433
+ * What an export writes: the exported columns in render order, their labels,
1434
+ * and one array of raw values per row.
1188
1435
  *
1189
- * The filter and edit stages each get a namespace, `filter` and `edit`,
1190
- * mirroring the feature's runtime API. What the column *is* stays flat:
1191
- * `label`, `type`, `options`, `align`, `flex`, `autoSize`, `enableOrdering`.
1192
- * `type` and `options` are read by both stages, so one declaration of each
1193
- * feeds the filter panel and the cell editor, which is why they sit outside
1194
- * both namespaces.
1436
+ * Raw values rather than text, so a format decides how a number, a date or an
1437
+ * array is written - JSON keeps a number a number, and a spreadsheet format
1438
+ * can write a typed cell.
1195
1439
  */
1196
- type TMDataGridColumnMeta = {
1197
- /** Name shown in menus and the column manager. Falls back to a string header. */
1198
- label?: string;
1440
+ type TMDataGridExportData = {
1441
+ columnIds: Array<string>;
1442
+ /** `getColumnLabel` per column: `meta.label`, a string header, or the id. */
1443
+ headers: Array<string>;
1444
+ rows: Array<Array<unknown>>;
1445
+ };
1446
+ type TMDataGridExportWriteOptions = {
1447
+ /** Whether the format writes the column labels as its first row. */
1448
+ includeHeaders: boolean;
1449
+ };
1450
+ /**
1451
+ * A file format an export can be written in.
1452
+ *
1453
+ * The grid ships `csvExcelFormat`, `csvFormat`, `tsvFormat` and `jsonFormat`;
1454
+ * an addon package or your own code adds one by implementing this shape.
1455
+ * `write` may be async and may answer a `Blob`, which is what a binary format
1456
+ * such as xlsx needs.
1457
+ */
1458
+ type TMDataGridExportFormat = {
1459
+ /** Identifies the format, for a menu or a test. */
1460
+ id: string;
1461
+ /** File extension without the dot, appended to the file name. */
1462
+ extension: string;
1463
+ /** The `Blob` type the download is served under. */
1464
+ mimeType: string;
1199
1465
  /**
1200
- * Drives which filter operators are offered and, once editing is on, which
1201
- * editor the cell opens. Defaults to `"string"`.
1466
+ * The decimal mark this format writes, when it writes text. Ctrl+C follows
1467
+ * it, so what is copied matches what is exported. Unset means the Nordic
1468
+ * default, a comma.
1202
1469
  */
1203
- type?: TMDataGridColumnType;
1204
- /**
1205
- * The choices of a `select` / `multiSelect` column - one declaration feeding
1470
+ decimalComma?: boolean;
1471
+ write: (data: TMDataGridExportData, options: TMDataGridExportWriteOptions) => string | Blob | Promise<string | Blob>;
1472
+ };
1473
+ /**
1474
+ * Which columns an export takes: the visible ones, every exportable column
1475
+ * hidden or not, or a list of column ids. The generated lanes and columns
1476
+ * with `meta.enableExport: false` are never taken, whatever is asked for.
1477
+ */
1478
+ type TMDataGridExportColumns = "visible" | "all" | ReadonlyArray<string>;
1479
+ /** How the grid exports: the format, the file name and whether headers go in. */
1480
+ type TMDataGridExportOptions = {
1481
+ /** Defaults to `csvExcelFormat()`. */
1482
+ format?: TMDataGridExportFormat;
1483
+ /** Without extension. Defaults to `"export"`. */
1484
+ fileName?: string;
1485
+ /** Column labels as the first row. Defaults to `true`. */
1486
+ includeHeaders?: boolean;
1487
+ /** Defaults to `"visible"`. See {@link TMDataGridExportColumns}. */
1488
+ columns?: TMDataGridExportColumns;
1489
+ };
1490
+ /**
1491
+ * What the column picker was opened for: which rows, and the options of the
1492
+ * item that opened it. Held in `ui.state.exportPicker` while it is open.
1493
+ */
1494
+ type TMDataGridExportPickerRequest = {
1495
+ rows: "all" | "selected";
1496
+ options: TMDataGridExportOptions;
1497
+ };
1498
+ /** `TMDataGridExportOptions` with every default filled in. */
1499
+ type TMDataGridExportSettings = Required<TMDataGridExportOptions>;
1500
+ /**
1501
+ * The value written for a cell, in place of `row.getValue(column.id)`. See
1502
+ * `meta.exportValue`.
1503
+ */
1504
+ type TMDataGridExportValueGetter = (args: {
1505
+ value: unknown;
1506
+ row: ErasedRow;
1507
+ column: ErasedColumn;
1508
+ }) => unknown;
1509
+ /**
1510
+ * Which rows an export takes: every filtered and sorted row across all pages,
1511
+ * the selected ones among those, or a list of your own.
1512
+ */
1513
+ type TMDataGridExportRows<TData extends RowData> = "all" | "selected" | ReadonlyArray<Row<TMDataGridFeatures, TData>>;
1514
+ /**
1515
+ * One value as text.
1516
+ *
1517
+ * Deliberately not the rendered cell: what a cell renders is React, and often a
1518
+ * badge, a link or an icon rather than the value. The value is what a
1519
+ * spreadsheet wants, and it is the one thing every column is guaranteed to
1520
+ * have. `meta.exportValue` is where a column substitutes something else.
1521
+ */
1522
+ declare function formatExportValue(value: unknown, { decimalComma }: {
1523
+ decimalComma: boolean;
1524
+ }): string;
1525
+ /**
1526
+ * Keeps a spreadsheet from running a cell as a formula.
1527
+ *
1528
+ * Excel and Sheets evaluate a cell that starts with `=`, `+`, `-` or `@`, so a
1529
+ * value one user typed into the grid would run in another user's spreadsheet
1530
+ * when the file is opened. The defence is the standard one: a leading
1531
+ * apostrophe, which every spreadsheet reads as "text follows".
1532
+ *
1533
+ * Text that parses as a number is left alone - `-5` and `+4670123456` are
1534
+ * numbers to the spreadsheet too, and an apostrophe would turn them into text.
1535
+ * A phone number written with spaces (`+46 70 123 45 67`) does not parse and
1536
+ * is prefixed; `escapeFormulas: false` on the format is the way out for a grid
1537
+ * whose data is trusted.
1538
+ */
1539
+ declare function guardFormula(text: string): string;
1540
+ type TMDataGridCsvFormatOptions = {
1541
+ /** Between fields. `csvExcelFormat` defaults to `";"`, `csvFormat` to `","`. */
1542
+ separator?: string;
1543
+ /** Write numbers as `1,5` rather than `1.5`. `csvExcelFormat` defaults to `true`, `csvFormat` to `false`. */
1544
+ decimalComma?: boolean;
1545
+ /** Prefix text that a spreadsheet would run as a formula. Defaults to `true`. See {@link guardFormula}. */
1546
+ escapeFormulas?: boolean;
1547
+ };
1548
+ /**
1549
+ * A CSV that opens straight into columns in Excel.
1550
+ *
1551
+ * Three things make that true, and all three are needed:
1552
+ *
1553
+ * | Part | Why |
1554
+ * | ---- | --- |
1555
+ * | `sep=;` first line | Excel's own directive - it stops guessing and uses this |
1556
+ * | UTF-8 BOM | without it Excel reads the file as ANSI, and å ä ö arrive broken |
1557
+ * | CRLF line endings | what Excel writes, and what its importer is happiest with |
1558
+ *
1559
+ * The defaults are the Nordic ones, because they are the ones that need
1560
+ * choosing: an Excel running a Swedish, Norwegian, Danish or Finnish locale
1561
+ * reads `;` as its list separator and `,` as its decimal mark, and a file
1562
+ * written the other way opens as one column of text.
1563
+ *
1564
+ * The `sep=` line is Excel's alone; Sheets and Numbers show it as a first row.
1565
+ * `csvFormat` is the one for them.
1566
+ */
1567
+ declare function csvExcelFormat({ separator, decimalComma, escapeFormulas }?: TMDataGridCsvFormatOptions): TMDataGridExportFormat;
1568
+ /**
1569
+ * Plain CSV as RFC 4180 has it: commas, a dot as the decimal mark, CRLF, and a
1570
+ * UTF-8 BOM so that Excel too reads it as UTF-8. No `sep=` line, so Google
1571
+ * Sheets, Numbers and every tool that reads CSV take it as is.
1572
+ */
1573
+ declare function csvFormat({ separator, decimalComma, escapeFormulas }?: TMDataGridCsvFormatOptions): TMDataGridExportFormat;
1574
+ type TMDataGridTsvFormatOptions = Omit<TMDataGridCsvFormatOptions, "separator">;
1575
+ /**
1576
+ * Tab-separated text, the clipboard shape as a file: tabs between fields, CRLF
1577
+ * between rows, a UTF-8 BOM. Every spreadsheet opens it into columns without
1578
+ * a separator to guess.
1579
+ */
1580
+ declare function tsvFormat({ decimalComma, escapeFormulas }?: TMDataGridTsvFormatOptions): TMDataGridExportFormat;
1581
+ type TMDataGridJsonFormatOptions = {
1582
+ /** Indentation passed to `JSON.stringify`. Defaults to `2`. */
1583
+ space?: number;
1584
+ };
1585
+ /**
1586
+ * An array with one object per row, keyed by the column labels, values as the
1587
+ * data holds them. Two columns with the same label collapse into one key, the
1588
+ * later column winning. `includeHeaders` has no meaning here and is ignored.
1589
+ */
1590
+ declare function jsonFormat({ space }?: TMDataGridJsonFormatOptions): TMDataGridExportFormat;
1591
+ declare const DEFAULT_EXPORT_OPTIONS: TMDataGridExportSettings;
1592
+ /**
1593
+ * The defaults with each override folded over them in turn. Field by field,
1594
+ * so an override that spells a field as `undefined` leaves the earlier value
1595
+ * rather than blanking it.
1596
+ */
1597
+ declare function resolveExportOptions(...overrides: Array<TMDataGridExportOptions | undefined>): TMDataGridExportSettings;
1598
+ /**
1599
+ * Every column an export could take, in render order: the data columns minus
1600
+ * the generated lanes and `meta.enableExport: false`, hidden ones included.
1601
+ * What the column picker lists; `column.getIsVisible()` says which of them a
1602
+ * `"visible"` export would take.
1603
+ */
1604
+ declare function getExportableColumns<TData extends RowData>(table: TMDataGridTable<TData>): Array<Column<TMDataGridFeatures, TData, unknown>>;
1605
+ /**
1606
+ * How many rows `rows: "selected"` would export: the ticked rows of the
1607
+ * current view. Not the size of the selection map, which keeps rows the
1608
+ * filters have since hidden. Free while nothing is selected.
1609
+ */
1610
+ declare function countSelectedExportRows<TData extends RowData>(table: TMDataGridTable<TData>): number;
1611
+ type BuildExportDataArgs<TData extends RowData> = {
1612
+ table: TMDataGridTable<TData>;
1613
+ /** Defaults to `"all"`. */
1614
+ rows?: TMDataGridExportRows<TData>;
1615
+ /** Defaults to `"visible"`. Ignored under `bounds`. */
1616
+ columns?: TMDataGridExportColumns;
1617
+ /**
1618
+ * A rectangle over `rows` and the visible columns, both by index - the
1619
+ * cell-range path. `rows` is then the list the indices refer to, usually
1620
+ * the displayed rows.
1621
+ */
1622
+ bounds?: TMDataGridRangeBounds;
1623
+ };
1624
+ /**
1625
+ * What an export writes, before any format touches it.
1626
+ *
1627
+ * Columns are `"visible"` (the data columns on screen, in render order),
1628
+ * `"all"` (every exportable column, hidden or not) or a list of ids; the
1629
+ * generated lanes and any column with `meta.enableExport: false` are left out
1630
+ * whichever is asked for. Rows are `"all"` (every filtered and sorted row
1631
+ * across every page, group rows flattened to their records), `"selected"`
1632
+ * (those of them the user has ticked, in the same order - the selection map
1633
+ * is walked through the row list rather than the other way round, because
1634
+ * TanStack's selected row models ignore filtering and sorting), or a list of
1635
+ * your own.
1636
+ */
1637
+ declare function buildExportData<TData extends RowData>({ table, rows, columns: which, bounds }: BuildExportDataArgs<TData>): TMDataGridExportData;
1638
+ /**
1639
+ * Writes `data` in the format and downloads it. Awaits the format, since a
1640
+ * binary format builds its file asynchronously.
1641
+ */
1642
+ declare function writeExportFile(data: TMDataGridExportData, { format, fileName, includeHeaders }: TMDataGridExportSettings): Promise<void>;
1643
+ type ExportGridArgs<TData extends RowData> = {
1644
+ table: TMDataGridTable<TData>;
1645
+ /** Defaults to `"all"`. See {@link TMDataGridExportRows}. */
1646
+ rows?: TMDataGridExportRows<TData>;
1647
+ /** Merged over `DEFAULT_EXPORT_OPTIONS`. */
1648
+ options?: TMDataGridExportOptions;
1649
+ };
1650
+ /**
1651
+ * Downloads the grid as a file: {@link buildExportData} through the format's
1652
+ * `write` and a download.
1653
+ *
1654
+ * Inside the grid, `useTMDataGridExport` and the `TMDataGrid.Menu.Export*`
1655
+ * items call this with the grid's own `exportOptions`; this is the entry point
1656
+ * for code that holds the table and nothing else.
1657
+ *
1658
+ * Nothing is downloaded when no column is exportable. A grid with no rows
1659
+ * still downloads its header row, since an empty file is the honest answer to
1660
+ * an empty view.
1661
+ *
1662
+ * Async because a format may be. Safari refuses a download that starts after
1663
+ * the click gesture has ended, which a format that takes long enough to build
1664
+ * can run into; the text formats resolve synchronously and never do.
1665
+ */
1666
+ declare function exportGrid<TData extends RowData>({ table, rows, options }: ExportGridArgs<TData>): Promise<void>;
1667
+ type TMDataGridClipboardTextOptions = {
1668
+ /** Defaults to `true`, the Nordic mark. */
1669
+ decimalComma?: boolean;
1670
+ /** Defaults to `true`. See {@link guardFormula}. */
1671
+ escapeFormulas?: boolean;
1672
+ };
1673
+ /**
1674
+ * The clipboard format spreadsheets read: tab between cells, CRLF between rows,
1675
+ * values only.
1676
+ *
1677
+ * Tabs rather than commas because that is what Excel, Sheets and Numbers all
1678
+ * put on the clipboard themselves - paste it and the cells land in cells. A
1679
+ * comma-separated string pastes into a single column, which is the thing this
1680
+ * exists to avoid. No header row: Excel's own copy carries none either, and a
1681
+ * header pasted into the middle of a sheet is a row of text where numbers
1682
+ * were expected.
1683
+ *
1684
+ * Also accepts an already-formatted string matrix, for callers of the
1685
+ * deprecated `buildCellMatrix`.
1686
+ */
1687
+ declare function toClipboardText(data: TMDataGridExportData | TMDataGridCellMatrix, { decimalComma, escapeFormulas }?: TMDataGridClipboardTextOptions): string;
1688
+ /**
1689
+ * Puts text on the clipboard, reporting whether it landed.
1690
+ *
1691
+ * The async clipboard API only resolves for a document that has the focus and a
1692
+ * user gesture behind it - both true when this runs off Ctrl+C or a menu item.
1693
+ * It is still allowed to reject (a permissions policy, a page that lost focus
1694
+ * mid-copy), so the result is a boolean the caller can act on.
1695
+ */
1696
+ declare function writeClipboardText(text: string): Promise<boolean>;
1697
+ /**
1698
+ * Downloads a file, through the one mechanism a library can use: an anchor
1699
+ * with an object URL behind it, clicked. Revoked on the next frame -
1700
+ * immediately would race the browser's own read of it.
1701
+ */
1702
+ declare function downloadFile({ fileName, content, mimeType }: {
1703
+ fileName: string;
1704
+ content: string | Blob;
1705
+ mimeType: string;
1706
+ }): void;
1707
+ /** @deprecated Use {@link TMDataGridExportData}; the matrix is text, the data holds values. */
1708
+ type TMDataGridCellMatrix = Array<Array<string>>;
1709
+ /** @deprecated Use {@link TMDataGridExportOptions} with `csvExcelFormat({ separator, decimalComma })`. */
1710
+ type TMDataGridCellExportOptions = {
1711
+ /** CSV field separator. Defaults to `";"`. */
1712
+ separator?: string;
1713
+ /** Write numbers as `1,5` rather than `1.5`. Defaults to `true`. */
1714
+ decimalComma?: boolean;
1715
+ /** Column labels as the first row. Defaults to `true`. */
1716
+ includeHeaders?: boolean;
1717
+ /** Without extension. Defaults to `"export"`. */
1718
+ fileName?: string;
1719
+ };
1720
+ /** @deprecated Use {@link DEFAULT_EXPORT_OPTIONS}. */
1721
+ declare const DEFAULT_CELL_EXPORT_OPTIONS: Required<TMDataGridCellExportOptions>;
1722
+ /**
1723
+ * The old options as the new: separator and decimal mark become a
1724
+ * `csvExcelFormat`, the rest carries over. Shared by the deprecated
1725
+ * `cellExport` Table prop and {@link exportGridToCsv}.
1726
+ *
1727
+ * @deprecated Write {@link TMDataGridExportOptions} directly.
1728
+ */
1729
+ declare function fromCellExportOptions(options: TMDataGridCellExportOptions): TMDataGridExportOptions;
1730
+ /** @deprecated Use {@link BuildExportDataArgs}. */
1731
+ type BuildCellMatrixArgs = {
1732
+ rows: ReadonlyArray<ErasedRow>;
1733
+ /** Every visible column, in render order - the same list the bounds index into. */
1734
+ columns: ReadonlyArray<ErasedColumn>;
1735
+ bounds: TMDataGridRangeBounds;
1736
+ includeHeaders: boolean;
1737
+ decimalComma: boolean;
1738
+ };
1739
+ /** @deprecated Use {@link buildExportData} with `bounds`, and a format to write it. */
1740
+ declare function buildCellMatrix({ rows, columns, bounds, includeHeaders, decimalComma }: BuildCellMatrixArgs): TMDataGridCellMatrix;
1741
+ /** @deprecated Use {@link buildExportData}. */
1742
+ declare function buildGridCellMatrix<TData extends RowData>({ table, includeHeaders, decimalComma }: {
1743
+ table: TMDataGridTable<TData>;
1744
+ includeHeaders?: boolean;
1745
+ decimalComma?: boolean;
1746
+ }): TMDataGridCellMatrix;
1747
+ /** @deprecated Use {@link csvExcelFormat} - its `write` is this over export data. */
1748
+ declare function toExcelCsv(matrix: TMDataGridCellMatrix, { separator }: {
1749
+ separator: string;
1750
+ }): string;
1751
+ /** @deprecated Use {@link exportGrid}. */
1752
+ declare function exportGridToCsv<TData extends RowData>({ table, options }: {
1753
+ table: TMDataGridTable<TData>;
1754
+ options?: TMDataGridCellExportOptions;
1755
+ }): void;
1756
+ /** @deprecated Use {@link downloadFile}. */
1757
+ declare function downloadTextFile({ fileName, text, mimeType }: {
1758
+ fileName: string;
1759
+ text: string;
1760
+ mimeType?: string;
1761
+ }): void;
1762
+ //#endregion
1763
+ //#region .types-tmp/useTMDataGrid.d.ts
1764
+ /**
1765
+ * Per-column configuration the grid's own components read.
1766
+ *
1767
+ * The filter and edit stages each get a namespace, `filter` and `edit`,
1768
+ * mirroring the feature's runtime API. What the column *is* stays flat:
1769
+ * `label`, `type`, `options`, `align`, `flex`, `autoSize`, `enableOrdering`.
1770
+ * `type` and `options` are read by both stages, so one declaration of each
1771
+ * feeds the filter panel and the cell editor, which is why they sit outside
1772
+ * both namespaces.
1773
+ */
1774
+ type TMDataGridColumnMeta = {
1775
+ /** Name shown in menus and the column manager. Falls back to a string header. */
1776
+ label?: string;
1777
+ /**
1778
+ * Drives which filter operators are offered and, once editing is on, which
1779
+ * editor the cell opens. Defaults to `"string"`.
1780
+ */
1781
+ type?: TMDataGridColumnType;
1782
+ /**
1783
+ * The choices of a `select` / `multiSelect` column - one declaration feeding
1206
1784
  * the filter panel's value control and the cell editor alike. A static
1207
1785
  * array, `"faceted"` (the distinct values present in the data), or a
1208
1786
  * function of the table, column and, for editors, the row. See
@@ -1225,8 +1803,8 @@ type TMDataGridColumnMeta = {
1225
1803
  */
1226
1804
  enableOrdering?: boolean;
1227
1805
  /**
1228
- * How this column filters: the operator a fresh filter starts with, and the
1229
- * value control the filter panel renders for it.
1806
+ * How this column filters: which operators it offers, the operator a fresh
1807
+ * filter starts with, and the value control the filter panel renders for it.
1230
1808
  *
1231
1809
  * ```tsx
1232
1810
  * meta: {
@@ -1253,6 +1831,25 @@ type TMDataGridColumnMeta = {
1253
1831
  * See {@link TMDataGridColumnEditOptions}.
1254
1832
  */
1255
1833
  edit?: TMDataGridColumnEditOptions;
1834
+ /**
1835
+ * `false` leaves the column out of every export and out of Ctrl+C - for a
1836
+ * column of buttons, or one whose value means nothing outside the grid.
1837
+ * Defaults to `true`.
1838
+ */
1839
+ enableExport?: boolean;
1840
+ /**
1841
+ * The value an export writes for this column, in place of
1842
+ * `row.getValue(column.id)`. The export otherwise writes the value, never
1843
+ * what the cell renders, so this is where a status code becomes its label
1844
+ * or a nested object becomes one field.
1845
+ *
1846
+ * ```tsx
1847
+ * meta: {
1848
+ * exportValue: ({ value }) => STATUS_LABELS[value as Status],
1849
+ * }
1850
+ * ```
1851
+ */
1852
+ exportValue?: TMDataGridExportValueGetter;
1256
1853
  };
1257
1854
  /** Grid-wide configuration passed through `options.meta`. */
1258
1855
  type TMDataGridTableMeta = {
@@ -1283,6 +1880,7 @@ declare const tmDataGridFeatures: {
1283
1880
  columnResizingFeature: import("@tanstack/table-core").TableFeature;
1284
1881
  columnFacetingFeature: import("@tanstack/table-core").TableFeature;
1285
1882
  columnGroupingFeature: import("@tanstack/table-core").TableFeature;
1883
+ rowAggregationFeature: import("@tanstack/table-core").TableFeature;
1286
1884
  rowExpandingFeature: import("@tanstack/table-core").TableFeature;
1287
1885
  rowPinningFeature: import("@tanstack/table-core").TableFeature;
1288
1886
  filteredRowModel: (table: Table<any, any>) => () => import("@tanstack/table-core").RowModel<any, any>;
@@ -1294,62 +1892,47 @@ declare const tmDataGridFeatures: {
1294
1892
  facetedMinMaxValues: (table: Table<import("@tanstack/table-core").TableFeatures, any>, columnId: string) => () => undefined | [number, number];
1295
1893
  facetedUniqueValues: (table: Table<import("@tanstack/table-core").TableFeatures, any>, columnId: string) => () => Map<any, number>;
1296
1894
  filterFns: {
1297
- arrIncludes: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
1298
- autoRemove: (val: any) => boolean;
1299
- };
1300
- arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
1301
- autoRemove: (val: any) => boolean;
1302
- };
1303
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
1304
- arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
1305
- autoRemove: (val: any) => boolean;
1306
- };
1307
- between: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValues: [unknown, unknown]) => boolean) & {
1308
- autoRemove: (val: any) => boolean;
1309
- };
1310
- betweenInclusive: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValues: [unknown, unknown]) => boolean) & {
1311
- autoRemove: (val: any) => boolean;
1312
- };
1313
- equals: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown) => boolean) & {
1314
- autoRemove: (val: any) => boolean;
1315
- };
1316
- equalsString: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown) => boolean) & {
1317
- autoRemove: (val: any) => boolean;
1318
- };
1319
- inNumberRange: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: [number, number]) => boolean) & {
1320
- resolveFilterValue: (val: [any, any]) => readonly [number, number];
1321
- autoRemove: (val: any) => boolean;
1322
- };
1323
- includesString: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown) => boolean) & {
1324
- autoRemove: (val: any) => boolean;
1325
- };
1326
- includesStringSensitive: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown) => boolean) & {
1327
- autoRemove: (val: any) => boolean;
1328
- };
1329
- weakEquals: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown) => boolean) & {
1330
- autoRemove: (val: any) => boolean;
1331
- };
1895
+ arrIncludes: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1896
+ arrIncludesAll: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1897
+ arrHas: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1898
+ arrIncludesSome: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1899
+ between: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1900
+ betweenInclusive: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1901
+ empty: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1902
+ endsWith: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1903
+ equals: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1904
+ equalsString: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1905
+ equalsStringSensitive: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1906
+ inDateRange: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1907
+ inNumberRange: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1908
+ includesString: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1909
+ includesStringSensitive: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1910
+ notEmpty: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1911
+ startsWith: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1912
+ weakEquals: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1332
1913
  tmDataGrid: typeof tmDataGridFilterFn;
1333
1914
  tmDataGridFuzzy: typeof fuzzyGlobalFilterFn;
1334
1915
  };
1335
1916
  sortFns: {
1336
- alphanumeric: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(rowA: Row<TFeatures, TData>, rowB: Row<TFeatures, TData>, columnId: string) => number;
1337
- alphanumericCaseSensitive: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(rowA: Row<TFeatures, TData>, rowB: Row<TFeatures, TData>, columnId: string) => number;
1338
- basic: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(rowA: Row<TFeatures, TData>, rowB: Row<TFeatures, TData>, columnId: string) => 0 | 1 | -1;
1339
- datetime: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(rowA: Row<TFeatures, TData>, rowB: Row<TFeatures, TData>, columnId: string) => 0 | 1 | -1;
1340
- text: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(rowA: Row<TFeatures, TData>, rowB: Row<TFeatures, TData>, columnId: string) => 0 | 1 | -1;
1341
- textCaseSensitive: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(rowA: Row<TFeatures, TData>, rowB: Row<TFeatures, TData>, columnId: string) => 0 | 1 | -1;
1917
+ alphanumeric: import("@tanstack/table-core").CreatedSortFn<any, any>;
1918
+ alphanumericCaseSensitive: import("@tanstack/table-core").CreatedSortFn<any, any>;
1919
+ basic: import("@tanstack/table-core").CreatedSortFn<any, any>;
1920
+ datetime: import("@tanstack/table-core").CreatedSortFn<any, any>;
1921
+ text: import("@tanstack/table-core").CreatedSortFn<any, any>;
1922
+ textCaseSensitive: import("@tanstack/table-core").CreatedSortFn<any, any>;
1342
1923
  };
1343
1924
  aggregationFns: {
1344
- sum: typeof import("@tanstack/table-core").aggregationFn_sum;
1345
- min: typeof import("@tanstack/table-core").aggregationFn_min;
1346
- max: typeof import("@tanstack/table-core").aggregationFn_max;
1347
- extent: typeof import("@tanstack/table-core").aggregationFn_extent;
1348
- mean: typeof import("@tanstack/table-core").aggregationFn_mean;
1349
- median: typeof import("@tanstack/table-core").aggregationFn_median;
1350
- unique: typeof import("@tanstack/table-core").aggregationFn_unique;
1351
- uniqueCount: typeof import("@tanstack/table-core").aggregationFn_uniqueCount;
1352
- count: typeof import("@tanstack/table-core").aggregationFn_count;
1925
+ sum: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number>;
1926
+ min: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, (number | Date) | undefined>;
1927
+ max: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, (number | Date) | undefined>;
1928
+ extent: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, [(number | Date) | undefined, (number | Date) | undefined]>;
1929
+ mean: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number | undefined>;
1930
+ median: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number | undefined>;
1931
+ unique: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, unknown[]>;
1932
+ uniqueCount: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number>;
1933
+ count: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number>;
1934
+ first: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, unknown>;
1935
+ last: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, unknown>;
1353
1936
  };
1354
1937
  tableMeta: TMDataGridTableMeta;
1355
1938
  columnMeta: TMDataGridColumnMeta;
@@ -1369,6 +1952,7 @@ declare function createTMDataGridColumnHelper<TData extends RowData>(): import("
1369
1952
  columnResizingFeature: import("@tanstack/table-core").TableFeature;
1370
1953
  columnFacetingFeature: import("@tanstack/table-core").TableFeature;
1371
1954
  columnGroupingFeature: import("@tanstack/table-core").TableFeature;
1955
+ rowAggregationFeature: import("@tanstack/table-core").TableFeature;
1372
1956
  rowExpandingFeature: import("@tanstack/table-core").TableFeature;
1373
1957
  rowPinningFeature: import("@tanstack/table-core").TableFeature;
1374
1958
  filteredRowModel: (table: Table<any, any>) => () => import("@tanstack/table-core").RowModel<any, any>;
@@ -1380,62 +1964,47 @@ declare function createTMDataGridColumnHelper<TData extends RowData>(): import("
1380
1964
  facetedMinMaxValues: (table: Table<import("@tanstack/table-core").TableFeatures, any>, columnId: string) => () => undefined | [number, number];
1381
1965
  facetedUniqueValues: (table: Table<import("@tanstack/table-core").TableFeatures, any>, columnId: string) => () => Map<any, number>;
1382
1966
  filterFns: {
1383
- arrIncludes: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: Array<unknown>) => boolean) & {
1384
- autoRemove: (val: any) => boolean;
1385
- };
1386
- arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: Array<unknown>) => boolean) & {
1387
- autoRemove: (val: any) => boolean;
1388
- };
1389
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: Array<unknown>) => boolean;
1390
- arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: Array<unknown>) => boolean) & {
1391
- autoRemove: (val: any) => boolean;
1392
- };
1393
- between: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValues: [unknown, unknown]) => boolean) & {
1394
- autoRemove: (val: any) => boolean;
1395
- };
1396
- betweenInclusive: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValues: [unknown, unknown]) => boolean) & {
1397
- autoRemove: (val: any) => boolean;
1398
- };
1399
- equals: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: unknown) => boolean) & {
1400
- autoRemove: (val: any) => boolean;
1401
- };
1402
- equalsString: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: unknown) => boolean) & {
1403
- autoRemove: (val: any) => boolean;
1404
- };
1405
- inNumberRange: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: [number, number]) => boolean) & {
1406
- resolveFilterValue: (val: [any, any]) => readonly [number, number];
1407
- autoRemove: (val: any) => boolean;
1408
- };
1409
- includesString: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: unknown) => boolean) & {
1410
- autoRemove: (val: any) => boolean;
1411
- };
1412
- includesStringSensitive: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: unknown) => boolean) & {
1413
- autoRemove: (val: any) => boolean;
1414
- };
1415
- weakEquals: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(row: Row<TFeatures, TData_1>, columnId: string, filterValue: unknown) => boolean) & {
1416
- autoRemove: (val: any) => boolean;
1417
- };
1967
+ arrIncludes: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1968
+ arrIncludesAll: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1969
+ arrHas: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1970
+ arrIncludesSome: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1971
+ between: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1972
+ betweenInclusive: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1973
+ empty: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1974
+ endsWith: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1975
+ equals: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1976
+ equalsString: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1977
+ equalsStringSensitive: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1978
+ inDateRange: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1979
+ inNumberRange: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1980
+ includesString: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1981
+ includesStringSensitive: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1982
+ notEmpty: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1983
+ startsWith: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1984
+ weakEquals: import("@tanstack/table-core").CreatedFilterFn<any, any>;
1418
1985
  tmDataGrid: typeof tmDataGridFilterFn;
1419
1986
  tmDataGridFuzzy: typeof fuzzyGlobalFilterFn;
1420
1987
  };
1421
1988
  sortFns: {
1422
- alphanumeric: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(rowA: Row<TFeatures, TData_1>, rowB: Row<TFeatures, TData_1>, columnId: string) => number;
1423
- alphanumericCaseSensitive: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(rowA: Row<TFeatures, TData_1>, rowB: Row<TFeatures, TData_1>, columnId: string) => number;
1424
- basic: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(rowA: Row<TFeatures, TData_1>, rowB: Row<TFeatures, TData_1>, columnId: string) => 0 | 1 | -1;
1425
- datetime: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(rowA: Row<TFeatures, TData_1>, rowB: Row<TFeatures, TData_1>, columnId: string) => 0 | 1 | -1;
1426
- text: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(rowA: Row<TFeatures, TData_1>, rowB: Row<TFeatures, TData_1>, columnId: string) => 0 | 1 | -1;
1427
- textCaseSensitive: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData_1 extends RowData>(rowA: Row<TFeatures, TData_1>, rowB: Row<TFeatures, TData_1>, columnId: string) => 0 | 1 | -1;
1989
+ alphanumeric: import("@tanstack/table-core").CreatedSortFn<any, any>;
1990
+ alphanumericCaseSensitive: import("@tanstack/table-core").CreatedSortFn<any, any>;
1991
+ basic: import("@tanstack/table-core").CreatedSortFn<any, any>;
1992
+ datetime: import("@tanstack/table-core").CreatedSortFn<any, any>;
1993
+ text: import("@tanstack/table-core").CreatedSortFn<any, any>;
1994
+ textCaseSensitive: import("@tanstack/table-core").CreatedSortFn<any, any>;
1428
1995
  };
1429
1996
  aggregationFns: {
1430
- sum: typeof import("@tanstack/table-core").aggregationFn_sum;
1431
- min: typeof import("@tanstack/table-core").aggregationFn_min;
1432
- max: typeof import("@tanstack/table-core").aggregationFn_max;
1433
- extent: typeof import("@tanstack/table-core").aggregationFn_extent;
1434
- mean: typeof import("@tanstack/table-core").aggregationFn_mean;
1435
- median: typeof import("@tanstack/table-core").aggregationFn_median;
1436
- unique: typeof import("@tanstack/table-core").aggregationFn_unique;
1437
- uniqueCount: typeof import("@tanstack/table-core").aggregationFn_uniqueCount;
1438
- count: typeof import("@tanstack/table-core").aggregationFn_count;
1997
+ sum: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number>;
1998
+ min: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, (number | Date) | undefined>;
1999
+ max: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, (number | Date) | undefined>;
2000
+ extent: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, [(number | Date) | undefined, (number | Date) | undefined]>;
2001
+ mean: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number | undefined>;
2002
+ median: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number | undefined>;
2003
+ unique: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, unknown[]>;
2004
+ uniqueCount: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number>;
2005
+ count: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, number>;
2006
+ first: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, unknown>;
2007
+ last: import("@tanstack/table-core").AggregationFnDef<any, any, unknown, unknown>;
1439
2008
  };
1440
2009
  tableMeta: TMDataGridTableMeta;
1441
2010
  columnMeta: TMDataGridColumnMeta;
@@ -1454,9 +2023,20 @@ type TMDataGridDetailsRenderer<TData extends RowData> = (args: TMDataGridDetails
1454
2023
  */
1455
2024
  type TMDataGridUiState = {
1456
2025
  filterPanelOpen: boolean;
1457
- columnsPanelOpen: boolean;
1458
- /** Column whose filter row should be focused when the panel opens. */
2026
+ /**
2027
+ * Column whose *panel* row should take the focus. Cleared once the row has
2028
+ * taken it, so pointing at the same column twice focuses twice.
2029
+ */
1459
2030
  filterPanelColumnId: string | null;
2031
+ /**
2032
+ * Column whose *header filter* control should take the focus, under
2033
+ * `filters.inHeader`. Cleared once taken, like the one above.
2034
+ *
2035
+ * Its own slot rather than a second reader of `filterPanelColumnId`: a grid
2036
+ * can have header filters and a panel at once, and two controls racing to
2037
+ * answer one id means whichever mounted last wins the caret.
2038
+ */
2039
+ headerFilterColumnId: string | null;
1460
2040
  /**
1461
2041
  * Column being dragged by its header, if any. Held here rather than read from
1462
2042
  * `dataTransfer`, which browsers keep unreadable until the drop.
@@ -1495,12 +2075,32 @@ type TMDataGridUiState = {
1495
2075
  * describe different places.
1496
2076
  */
1497
2077
  cellRange: TMDataGridCellRange | null;
2078
+ /**
2079
+ * The export column picker, while it is open: which rows it exports and the
2080
+ * options of the item that opened it. `null` while closed. Held here rather
2081
+ * than in the menu item, which unmounts with the dropdown the moment it is
2082
+ * clicked.
2083
+ */
2084
+ exportPicker: TMDataGridExportPickerRequest | null;
1498
2085
  };
1499
2086
  type TMDataGridUiActions = {
1500
2087
  openFilterPanel: (columnId?: string | null) => void;
1501
2088
  closeFilterPanel: () => void;
1502
- setColumnsPanelOpen: (open: boolean) => void;
1503
- toggleColumnsPanel: () => void;
2089
+ /** Opens the export column picker for `request`. See `TMDataGrid.Menu.Export`'s `columns="custom"`. */
2090
+ openExportPicker: (request: TMDataGridExportPickerRequest) => void;
2091
+ closeExportPicker: () => void;
2092
+ /**
2093
+ * Points at a column's row in the filter panel without opening anything.
2094
+ * `openFilterPanel` does this as well as opening; this is the half a panel
2095
+ * that is already showing needs.
2096
+ */
2097
+ focusPanelFilter: (columnId: string | null) => void;
2098
+ /**
2099
+ * Points at a column's header filter control - what `openColumnFilter` does
2100
+ * under `filters.inHeader`, where there is no panel to open. The header row
2101
+ * scrolls the column into view and focuses it.
2102
+ */
2103
+ focusHeaderFilter: (columnId: string | null) => void;
1504
2104
  startColumnDrag: (columnId: string) => void;
1505
2105
  endColumnDrag: () => void;
1506
2106
  /**
@@ -1541,12 +2141,27 @@ type TMDataGridApi<TData extends RowData> = {
1541
2141
  /**
1542
2142
  * The edit engine - open forms, dirty/error projections, and the verbs
1543
2143
  * (`begin`, `commit`, `cancel`, `submitAll`). `edit.getForm(rowId)` hands
1544
- * out the same TanStack Form the inline editors write through, so a drawer
1545
- * or detail panel can share a row's draft. Inert until `editing` is set.
2144
+ * out the same TanStack Form the inline editors write through while a row
2145
+ * is open, so a drawer or detail panel can share a row's draft; a
2146
+ * committed row has no form until `begin` reopens it. Inert until
2147
+ * `editing` is set.
1546
2148
  */
1547
- edit: TMDataGridEditApi;
2149
+ edit: TMDataGridEditApi<TData>;
1548
2150
  /** Table-level feature switches, re-read from options on every render. */
1549
2151
  features: TMDataGridFeatureFlags;
2152
+ /**
2153
+ * Where the filter controls live, the `filters` option with its defaults
2154
+ * filled in. On the api rather than in a component's props because the
2155
+ * pills, the column menu and `openColumnFilter` all have to agree with the
2156
+ * table about which surface is on.
2157
+ */
2158
+ filters: TMDataGridFiltersSettings;
2159
+ /**
2160
+ * How the grid exports, the `exportOptions` option with its defaults filled
2161
+ * in. Read by `useTMDataGridExport`, the `TMDataGrid.Menu.Export*` items and
2162
+ * the cell-range menu, so every export of the grid agrees on the format.
2163
+ */
2164
+ exportOptions: TMDataGridExportSettings;
1550
2165
  /** Every string the chrome renders, `labels` merged over the English defaults. */
1551
2166
  labels: TMDataGridLabels;
1552
2167
  /** The detail renderer, when row details are on. See `renderDetails`. */
@@ -1608,6 +2223,27 @@ type TMDataGridEditingCallbacks<TData extends RowData> = {
1608
2223
  * Pathed issues land on the matching columns; pathless ones on the row.
1609
2224
  */
1610
2225
  rowValidators?: TMDataGridRowValidators;
2226
+ /**
2227
+ * Rules that need the other rows - no duplicate keys, no overlapping
2228
+ * ranges, allocations summing to a total. Handed the committing row and
2229
+ * `rows`, the collection as it would stand if the commit landed: every
2230
+ * draft overlaid, entry rows appended, deletion-marked rows removed.
2231
+ *
2232
+ * ```tsx
2233
+ * tableValidators: {
2234
+ * onSubmit: ({ value, rowId, rows }) =>
2235
+ * rows.some((r) => r.rowId !== rowId && r.value.code === value.code)
2236
+ * ? { fields: { code: "Duplicate code" } }
2237
+ * : undefined,
2238
+ * }
2239
+ * ```
2240
+ *
2241
+ * Runs at every commit, after the row's own validators, and again per
2242
+ * parked row during `saveDrafts` - a draft another edit has invalidated
2243
+ * blocks the save. Pathed issues land on the committing row's cells,
2244
+ * pathless ones on the row.
2245
+ */
2246
+ tableValidators?: TMDataGridTableValidators<TData>;
1611
2247
  /** Rows the pencil skips - `false` keeps a row read-only in every mode. */
1612
2248
  isRowEditable?: (row: Row<TMDataGridFeatures, TData>) => boolean;
1613
2249
  /**
@@ -1624,38 +2260,47 @@ type TMDataGridEditingCallbacks<TData extends RowData> = {
1624
2260
  /**
1625
2261
  * Seed values for `edit.addRow()` - the entry row's starting point. A
1626
2262
  * function is called per added row (fresh timestamps, empty arrays).
2263
+ * `edit.addRow(values)` overrides this key by key for that one row.
1627
2264
  */
1628
2265
  newRowDefaults?: TData | (() => TData);
1629
2266
  /**
1630
- * Called when an entry row commits: `Enter` or the lane's ✓ under the
1631
- * immediate modes, `submitAll` under draft. Create the record and let it
1632
- * arrive back through `data`; the engine's `tempId` never leaves the grid.
2267
+ * Called when an entry row commits: `Enter` or the lane's ✓, or
2268
+ * `saveDrafts` under `editing.draft`. Create the record and let it arrive
2269
+ * back through `data`; the engine's `tempId` never leaves the grid.
1633
2270
  */
1634
2271
  onRowAdd?: (args: TMDataGridRowAddArgs<TData>) => void | Promise<void>;
1635
2272
  /**
1636
- * Called by `edit.deleteRow` under the immediate modes - confirmation, if
1637
- * any, belongs in here. Under draft, deletions accumulate in
1638
- * `edit.state.deletedRowIds` instead and are reported by `submitAll`.
1639
- * Setting this also puts the trash can in the edit lane.
2273
+ * Called by `edit.deleteRow` - confirmation, if any, belongs in here. Under
2274
+ * `editing.draft` deletions accumulate in `edit.state.deletedRowIds`
2275
+ * instead and are reported by `saveDrafts`. Setting this also puts the
2276
+ * trash can in the edit lane.
1640
2277
  */
1641
2278
  onRowDelete?: (args: TMDataGridRowDeleteArgs<TData>) => void | Promise<void>;
1642
2279
  };
1643
2280
  /**
1644
2281
  * The `editing` option: one object that turns editing on and holds
1645
- * everything about it. `mode` picks what counts as a commit and which
1646
- * controls trigger it; the other members act within that mode.
2282
+ * everything about it. Two axes, and they are independent: `mode` picks what
2283
+ * counts as a commit, `draft` picks where that commit goes.
2284
+ *
2285
+ * | Mode | Commit | Cancel | Controls |
2286
+ * | ---- | ------ | ------ | -------- |
2287
+ * | `"cell"` | Enter, Tab, blur - Sheets | Escape | none |
2288
+ * | `"cellConfirm"` | ✓ or Enter; Tab and blur keep the draft | ✕ or Escape | ✓ / ✕ beside the input |
2289
+ * | `"row"` | Save in the edit lane, or Enter | Cancel, or Escape | generated edit lane |
2290
+ *
2291
+ * | `draft` | Where a commit goes |
2292
+ * | ------- | ------------------- |
2293
+ * | `false` (default) | Out as it happens - `onCommit`, `onRowAdd`, `onRowDelete` |
2294
+ * | `true` | Into the grid's draft store; `edit.saveDrafts()` sends the lot |
1647
2295
  *
1648
- * | Mode | Commit | Cancel |
1649
- * | ---- | ------ | ------ |
1650
- * | `"cell"` | Enter, Tab, blur - Sheets | Escape |
1651
- * | `"cellConfirm"` | ✓ or Enter only; blur keeps the draft | ✕ or Escape |
1652
- * | `"row"` | Save in the edit lane, or Ctrl+Enter | Cancel, or Escape |
1653
- * | `"draft"` | `edit.submitAll()` | `edit.cancelAll()` |
2296
+ * So `{ mode: "row", draft: true }` is "edit a row, the lane's ✓ parks it,
2297
+ * the toolbar's Save sends every parked row at once", and
2298
+ * `{ mode: "cell", draft: true }` is the same store filled cell by cell.
1654
2299
  *
1655
2300
  * Setting `editing` makes `getRowId` required - drafts are keyed by row id,
1656
2301
  * and the index fallback would name a different record after any sort - and
1657
- * `onCommitDrafts` exists only under `mode: "draft"`, the one mode whose
1658
- * `submitAll` calls it.
2302
+ * `onSaveDrafts` exists only under `draft: true`, the one configuration with
2303
+ * a draft store to save.
1659
2304
  *
1660
2305
  * The object may be written inline: the callbacks are read through a ref
1661
2306
  * every render, so its identity does not matter.
@@ -1666,28 +2311,67 @@ type TMDataGridEditingCallbacks<TData extends RowData> = {
1666
2311
  * built-in editor, and `enabled`, `field`, `editor`, `validate` and `mapValue`
1667
2312
  * override the rest.
1668
2313
  */
1669
- type TMDataGridEditingOptions<TData extends RowData> = TMDataGridEditingCallbacks<TData> & ({
1670
- mode: "draft";
2314
+ type TMDataGridEditingOptions<TData extends RowData> = TMDataGridEditingCallbacks<TData> & {
2315
+ /** What counts as a commit. See the table above. */
2316
+ mode: TMDataGridEditMode;
1671
2317
  /**
1672
- * Draft mode's save, called once by `edit.submitAll()` with every
1673
- * valid dirty row. Without it, `submitAll` falls back to the per-row
1674
- * {@link TMDataGridEditingCallbacks.onCommit} loop. Rows failing
1675
- * validation stay open either way; a rejection keeps every draft.
2318
+ * The column ids that take edits, by id. Unset - the default - every
2319
+ * column mapping to a data path is editable, which is what a grid whose
2320
+ * columns are mostly the record itself wants.
2321
+ *
2322
+ * Set it for the other shape: a grid of reference data with one or two
2323
+ * columns the user maintains, where naming those is shorter and harder to
2324
+ * get wrong than switching every other column off one by one.
2325
+ *
2326
+ * This gates before `meta.edit`, never past it: a column left out takes no
2327
+ * edits whatever its own meta says, and a column listed here still answers
2328
+ * to its `meta.edit.enabled`.
1676
2329
  */
1677
- onCommitDrafts?: (args: TMDataGridEditCommitDraftsArgs<TData>) => void | Promise<void>;
2330
+ columns?: ReadonlyArray<string>;
2331
+ } & ({
1678
2332
  /**
1679
- * Keep confirmed entry rows pinned in the sticky entry block until
1680
- * Save all. Off by default: a confirmed row joins the scrolling
1681
- * flow above the body rows instead - the block a row is *typed*
1682
- * into is always sticky, but entered rows scroll, so entering many
1683
- * cannot fill the viewport with sticky chrome.
2333
+ * Commits park in the grid's draft store instead of reaching the
2334
+ * consumer, and leave together through `edit.saveDrafts()`. The
2335
+ * edit lane gains the change markers and the per-row revert, the
2336
+ * trash marks a row for deletion rather than deleting it, and
2337
+ * `TMDataGrid.DraftActions` gets something to save.
2338
+ */
2339
+ draft: true;
2340
+ /**
2341
+ * The bulk save: called once by `edit.saveDrafts()` with the
2342
+ * whole draft store - committed edits, added rows and deletion
2343
+ * marks - so a server can apply it as one transaction. Without it,
2344
+ * `saveDrafts` falls back to the per-row
2345
+ * {@link TMDataGridEditingCallbacks.onCommit} loop.
2346
+ *
2347
+ * Rows still open are not in the payload and stay open. Returning
2348
+ * nothing saves the whole store and throwing saves none of it;
2349
+ * return a {@link TMDataGridSaveDraftsResult} to save part of it.
2350
+ */
2351
+ onSaveDrafts?: (args: TMDataGridSaveDraftsArgs<TData>) => void | TMDataGridSaveDraftsResult | Promise<void | TMDataGridSaveDraftsResult>;
2352
+ /**
2353
+ * @deprecated Renamed to {@link onSaveDrafts} - it fires when the
2354
+ * draft store is saved, not when a row commits into it. Still
2355
+ * honoured; removed in a later beta.
2356
+ */
2357
+ onCommitDrafts?: (args: TMDataGridSaveDraftsArgs<TData>) => void | TMDataGridSaveDraftsResult | Promise<void | TMDataGridSaveDraftsResult>;
2358
+ /**
2359
+ * Keep committed entry rows pinned in the sticky entry block until
2360
+ * the draft store is saved, out of the body's sort. Off by default:
2361
+ * a committed row joins the body rows instead, sorted and filtered
2362
+ * with them - the block a row is *typed* into is always sticky, but
2363
+ * committed rows scroll, so entering many cannot fill the viewport
2364
+ * with sticky chrome.
1684
2365
  */
1685
2366
  newRowsSticky?: boolean;
1686
2367
  } | {
1687
- mode: Exclude<TMDataGridEditMode, "draft">;
1688
- /** Only `"draft"`'s `submitAll` ever calls it - see the other branch. */
2368
+ /** Every commit reaches the consumer as it happens. The default. */
2369
+ draft?: false;
2370
+ /** Only `draft: true` has a store to save - see the other branch. */
2371
+ onSaveDrafts?: never;
2372
+ /** @deprecated See {@link onSaveDrafts}. */
1689
2373
  onCommitDrafts?: never;
1690
- /** Confirmed entry rows exist only under `"draft"` - see there. */
2374
+ /** Parked entry rows exist only under `draft: true` - see there. */
1691
2375
  newRowsSticky?: never;
1692
2376
  });
1693
2377
  type UseTMDataGridOptions<TData extends RowData> = Omit<TableOptions<TMDataGridFeatures, TData>, "features"> & ({
@@ -1743,12 +2427,55 @@ type UseTMDataGridOptions<TData extends RowData> = Omit<TableOptions<TMDataGridF
1743
2427
  * no extra flag.
1744
2428
  */
1745
2429
  enablePagination?: boolean;
2430
+ /**
2431
+ * Sends the grid back to the first page whenever the query changes - a
2432
+ * column filter, the quick search, the sort or the grouping. On by
2433
+ * default. TanStack's own `autoResetPageIndex` is switched off by the
2434
+ * grid: it fires on any change to the `data` array, which under
2435
+ * `editing.draft` is every commit.
2436
+ *
2437
+ * Server-side, `pageIndex` is a position in a result set the grid does not
2438
+ * own: narrowing the query leaves it pointing past the last page, and the
2439
+ * next request comes back empty. The reset is applied in the same event as
2440
+ * the change, so one request goes out, for the first page of the new query.
2441
+ */
2442
+ resetPageOnQueryChange?: boolean;
1746
2443
  /**
1747
2444
  * The row-number gutter: a generated lane, outermost left, numbering the
1748
2445
  * rows of the current view - sorted, filtered, continuing across pages,
1749
2446
  * with group rows unnumbered. Off by default.
1750
2447
  */
1751
2448
  enableRowNumbers?: boolean;
2449
+ /**
2450
+ * Where the grid puts its filter controls - a popup over the rows, a sidebar
2451
+ * beside them, controls in the header row, or nowhere at all so you place
2452
+ * `TMDataGrid.FilterPanel` yourself.
2453
+ *
2454
+ * ```tsx
2455
+ * useTMDataGrid({ data, columns, filters: { surface: "sidebar", inHeader: true } });
2456
+ * ```
2457
+ *
2458
+ * Defaults to `{ surface: "popup" }` - the floating panel the grid has
2459
+ * always shown. See {@link TMDataGridFiltersOptions}.
2460
+ *
2461
+ * Read field by field, so a literal is fine here - unlike `labels` or
2462
+ * `persist`, this one does not have to be referentially stable.
2463
+ */
2464
+ filters?: TMDataGridFiltersOptions;
2465
+ /**
2466
+ * How the grid exports: the file format, the file name and whether the
2467
+ * column labels go in as the first row. Defaults to `csvExcelFormat()`,
2468
+ * `"export"` and `true`. See {@link TMDataGridExportOptions}.
2469
+ *
2470
+ * ```tsx
2471
+ * useTMDataGrid({ data, columns, exportOptions: { format: csvFormat(), fileName: "employees" } });
2472
+ * ```
2473
+ *
2474
+ * Read field by field like `filters`, so a literal is fine. A `format`
2475
+ * built inline is rebuilt every render, which costs nothing but a small
2476
+ * object; keep it at module scope when that bothers you.
2477
+ */
2478
+ exportOptions?: TMDataGridExportOptions;
1752
2479
  /**
1753
2480
  * How the quick search (`TMDataGrid.Search`) matches. `"fuzzy"` - the
1754
2481
  * default - forgives typos and skipped characters, and while it is the
@@ -1915,47 +2642,472 @@ type UseTMDataGridOptions<TData extends RowData> = Omit<TableOptions<TMDataGridF
1915
2642
  * fields or an action strip; a highlight-driven side panel has room for more
1916
2643
  * and survives scrolling. Nothing stops a grid from doing both.
1917
2644
  */
1918
- renderDetails?: TMDataGridDetailsRenderer<TData>;
2645
+ renderDetails?: TMDataGridDetailsRenderer<TData>;
2646
+ /**
2647
+ * What the virtualizer assumes an unmeasured detail panel is worth, in px.
2648
+ * Defaults to 160.
2649
+ *
2650
+ * An estimate, not a height: every mounted row is measured, so the real one
2651
+ * takes over as soon as the panel is on screen. It keeps the scrollbar
2652
+ * accurate for panels that open off screen, such as restored `expanded`
2653
+ * state. An approximate value is enough.
2654
+ */
2655
+ renderDetailsEstHeight?: number;
2656
+ /**
2657
+ * Rows the virtualizer keeps mounted above and below the viewport. Defaults
2658
+ * to 6.
2659
+ *
2660
+ * Raise it to trade memory for a scroll that stays painted - fast wheel or
2661
+ * touch flings can outrun the virtualizer and flash blank rows, and a larger
2662
+ * buffer covers the gap. Lower it when rows are expensive to render.
2663
+ */
2664
+ overscan?: number;
2665
+ };
2666
+ /**
2667
+ * Builds a TMDataGrid table plus its chrome store.
2668
+ *
2669
+ * Every `TableOptions` field passes straight through, so a server-driven grid
2670
+ * only needs `manualPagination` / `manualFiltering` / `manualSorting`,
2671
+ * `rowCount` and the matching `onXChange` callbacks - the chrome reads
2672
+ * `getRowCount()` / `getPageCount()` / `getPaginatedRowModel()`, all of which
2673
+ * already respect manual mode. `manualPagination` also switches the pagination
2674
+ * flag on, so `<TMDataGrid.Footer />` renders its pager without further
2675
+ * options.
2676
+ */
2677
+ declare function useTMDataGrid<TData extends RowData>({ persist, labels: labelsOverride, enableColumnOrdering, enablePagination, resetPageOnQueryChange, enableRowNumbers, selectionMode, showSelectedBackground, defaultHighlightedRowId, onHighlightedRowChange, cellSelection, onFocusedCellChange, filters: filterOptions, exportOptions: exportOptionsOverride, editing, renderDetails, renderDetailsEstHeight, overscan, ...options }: UseTMDataGridOptions<TData>): TMDataGridApi<TData>;
2678
+ /**
2679
+ * Sends the user to a column's filter control, seeding an empty filter when
2680
+ * the column has none yet - what "Filter" in the column menu and a click on a
2681
+ * filter pill both do.
2682
+ *
2683
+ * Which control that is follows the grid's `filters` option. Under
2684
+ * `inHeader` it is the column's header control, which is already on screen, so
2685
+ * the call focuses it and leaves the popup or sidebar closed. Otherwise it is
2686
+ * the panel's row for that column, and the call opens the surface on it.
2687
+ */
2688
+ declare function openColumnFilter<TData extends RowData>(api: TMDataGridApi<TData>, columnId: string): void;
2689
+ //#endregion
2690
+ //#region .types-tmp/core/filterOperators.d.ts
2691
+ /**
2692
+ * The value shape stored in `columnFilters` for every TMDataGrid column.
2693
+ *
2694
+ * TanStack resolves `filterFn` statically per column, so the operator travels
2695
+ * inside the filter *value* instead. That keeps the filter model plain,
2696
+ * serialisable JSON, so a server-side `manualFiltering` table can forward
2697
+ * `columnFilters` to the API unchanged.
2698
+ *
2699
+ * `value` is a string array under `isAnyOf` / `isNoneOf` (the set the cell is
2700
+ * tested against), a `[min, max]` pair under `between` (an empty string means
2701
+ * that end is open), and a single string everywhere else - dates travel as
2702
+ * ISO `YYYY-MM-DD` strings, booleans as `"true"` / `"false"`. Still plain
2703
+ * JSON.
2704
+ */
2705
+ type TMDataGridFilterValue = {
2706
+ operator: TMDataGridFilterOperator;
2707
+ value: string | ReadonlyArray<string>;
2708
+ };
2709
+ type TMDataGridColumnType = "string" | "number" | "boolean" | "date" | "select" | "multiSelect";
2710
+ type TMDataGridFilterOperator = "contains" | "equals" | "notEquals" | "startsWith" | "endsWith" | "greaterThan" | "greaterThanOrEqual" | "lessThan" | "lessThanOrEqual" | "between" | "before" | "after" | "onOrBefore" | "onOrAfter" | "isAnyOf" | "isNoneOf" | "isEmpty" | "isNotEmpty";
2711
+ declare const FILTER_OPERATOR_LABELS: Record<TMDataGridFilterOperator, string>;
2712
+ declare function getOperatorsForType(type: TMDataGridColumnType): readonly TMDataGridFilterOperator[];
2713
+ declare function getDefaultOperator(type: TMDataGridColumnType): TMDataGridFilterOperator;
2714
+ declare function operatorNeedsValue(operator: TMDataGridFilterOperator): boolean;
2715
+ /** Whether the operator's value is a string array - `isAnyOf` / `isNoneOf`. */
2716
+ declare function operatorTakesArrayValue(operator: TMDataGridFilterOperator): boolean;
2717
+ /** Whether the operator's value is a `[min, max]` pair - `between`. */
2718
+ declare function operatorTakesRangeValue(operator: TMDataGridFilterOperator): boolean;
2719
+ /** The untouched value a fresh filter starts with - the operator's shape, empty. */
2720
+ declare function emptyValueForOperator(operator: TMDataGridFilterOperator): string | ReadonlyArray<string>;
2721
+ /**
2722
+ * The three value shapes an operator can take. A set is not a range, even
2723
+ * though both are arrays.
2724
+ */
2725
+ type TMDataGridFilterValueShape = "scalar" | "set" | "range";
2726
+ /**
2727
+ * Which shape an operator's value takes. A typed value survives an operator or
2728
+ * column change only within its shape, which is the rule both the panel and
2729
+ * the header controls use when the operator changes.
2730
+ */
2731
+ declare function filterValueShape(operator: TMDataGridFilterOperator): TMDataGridFilterValueShape;
2732
+ /**
2733
+ * A filter only narrows the row set once it has something to compare against.
2734
+ * Half-typed filters stay in state (so the panel keeps rendering their row) but
2735
+ * are treated as inactive for the funnel indicator and for row matching.
2736
+ */
2737
+ declare function isFilterActive(value: unknown): boolean;
2738
+ /** One column's filter, typed - what `columnFilters` holds per entry. */
2739
+ type TMDataGridColumnFilter = {
2740
+ id: string;
2741
+ value: TMDataGridFilterValue;
2742
+ };
2743
+ /**
2744
+ * The column filters that are actually narrowing the grid, typed.
2745
+ *
2746
+ * `ColumnFiltersState` types `value` as `unknown`, so the first line of a
2747
+ * server-side mapping layer is otherwise a cast back to the shape the grid
2748
+ * itself wrote, wrapped in the same "drop the half-typed ones" filter every
2749
+ * consumer writes:
2750
+ *
2751
+ * ```ts
2752
+ * const predicates = activeColumnFilters(table).map((filter) =>
2753
+ * toPredicate(filter.id, filter.value),
2754
+ * );
2755
+ * ```
2756
+ *
2757
+ * Takes the table, or a `columnFilters` array where the consumer owns the
2758
+ * slice. Reading it from the table reads the current value and does not
2759
+ * subscribe; inside a component, subscribe to `columnFilters` the way the
2760
+ * grid's own chrome does.
2761
+ */
2762
+ declare function activeColumnFilters<TData extends RowData>(source: TMDataGridTable<TData> | ColumnFiltersState): Array<TMDataGridColumnFilter>;
2763
+ /**
2764
+ * One-line description of a single filter, as shown on a filter pill.
2765
+ *
2766
+ * The type's default operator is left implicit - "First name: Sofia" reads the
2767
+ * way a person would say it - while any other operator is spelled out, since
2768
+ * that is the part a reader cannot guess.
2769
+ */
2770
+ declare function formatFilterLabel({ label, type, filter, operatorLabels }: {
2771
+ label: string;
2772
+ type: TMDataGridColumnType;
2773
+ filter: TMDataGridFilterValue;
2774
+ /** Localized operator names - `labels.operators`. Defaults to English. */
2775
+ operatorLabels?: Record<TMDataGridFilterOperator, string>;
2776
+ }): string;
2777
+ /**
2778
+ * The single filter function every TMDataGrid column uses. It dispatches on the
2779
+ * operator carried by the filter value, which is what lets one column offer
2780
+ * "contains" / "does not equal" / "is empty" without redefining the column.
2781
+ */
2782
+ declare function tmDataGridFilterFn<TFeatures extends TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown): boolean;
2783
+ //#endregion
2784
+ //#region .types-tmp/core/columnUtils.d.ts
2785
+ /**
2786
+ * Structural shape of the column bits the chrome reads. Kept minimal so these
2787
+ * helpers work with any `Column`/`Header` instance without dragging generics
2788
+ * through every call site.
2789
+ */
2790
+ type ColumnLike = {
2791
+ id: string;
2792
+ columnDef: {
2793
+ header?: unknown;
2794
+ meta?: TMDataGridColumnMeta;
2795
+ };
2796
+ /** Set on a leaf that sits inside a header group. */
2797
+ parent?: unknown;
2798
+ };
2799
+ /** Menu- and panel-facing column name. */
2800
+ declare function getColumnLabel(column: ColumnLike): string;
2801
+ declare function getColumnType(column: ColumnLike): TMDataGridColumnType;
2802
+ /**
2803
+ * The operators this column offers: the type's list, narrowed to
2804
+ * `meta.filter.operators` when the column declares one. The type's order is
2805
+ * kept so the menu reads the same on every column; an operator the type does
2806
+ * not offer is dropped, and an allowlist that leaves nothing falls back to the
2807
+ * type's full list rather than an empty menu.
2808
+ */
2809
+ declare function getColumnOperators(column: ColumnLike): readonly TMDataGridFilterOperator[];
2810
+ /**
2811
+ * The operator a fresh filter on this column starts with -
2812
+ * `meta.filter.defaultOperator`, else the type's default where the column
2813
+ * offers it, else the first operator it does offer.
2814
+ */
2815
+ declare function getColumnDefaultOperator(column: ColumnLike): TMDataGridFilterOperator;
2816
+ /**
2817
+ * This column's filter-panel value control - `meta.filter.control`, or
2818
+ * `undefined` for the built-in shape-by-operator input.
2819
+ */
2820
+ declare function getColumnFilterControl(column: ColumnLike): TMDataGridFilterControlComponent | undefined;
2821
+ /**
2822
+ * Whether `meta.edit.enabled` lets this column's cell on this row be edited -
2823
+ * the switch, then the predicate.
2824
+ *
2825
+ * This is only the column's half of the rule. A cell also needs the column to
2826
+ * map to a field (`getEditFieldName`) and the row to take edits at all
2827
+ * (`isRowEditable`); `edit.canEditCell` is the whole question.
2828
+ */
2829
+ declare function isColumnEditableForRow(column: ColumnLike, row: Row<TMDataGridFeatures, TMDataGridRowData>): boolean;
2830
+ /**
2831
+ * A generated lane holding one fixed-width thing - the checkbox, the details
2832
+ * chevron, the row number.
2833
+ *
2834
+ * They are laid out differently from every other column: cell padding is sized
2835
+ * for text and grows with the scale, which at `xl` squeezed a 16px checkbox out
2836
+ * of its track, so these lanes centre their content in an unpadded cell.
2837
+ * Their headers carry no column menu, and none of them is ever exported -
2838
+ * they hold chrome, not values.
2839
+ *
2840
+ * The tree column is deliberately not one of them: it holds a label as well as a
2841
+ * chevron, and wants the padding.
2842
+ */
2843
+ declare function isControlColumn(columnId: string): boolean;
2844
+ /**
2845
+ * Whether the grid generated this column rather than the consumer declaring it
2846
+ * - the four control lanes plus the tree column.
2847
+ *
2848
+ * These hold the grid's own chrome, and they keep the edges of the row: the
2849
+ * generated left lanes before every consumer column, the edit lane after all of
2850
+ * them. `isControlColumn` answers a narrower question about layout, and leaves
2851
+ * the tree column out because it is padded like a data column.
2852
+ */
2853
+ declare function isGeneratedColumn(columnId: string): boolean;
2854
+ /**
2855
+ * Whether a column may be moved. Ordering is the one column feature TanStack
2856
+ * has no column option for, so the switch lives in `meta.enableOrdering`.
2857
+ *
2858
+ * A leaf inside a header group is never movable: `columnOrder` sequences leaf
2859
+ * columns, so moving one out of its group would leave the group header spanning
2860
+ * columns that no longer belong to it.
2861
+ */
2862
+ declare function isColumnReorderable(column: ColumnLike): boolean;
2863
+ /** `"auto"` shows the search box from `COLUMN_SEARCH_MIN` columns. */
2864
+ type TMDataGridColumnSearchable = boolean | "auto";
2865
+ //#endregion
2866
+ //#region .types-tmp/components/TMDataGridMenu.d.ts
2867
+ type TMDataGridMenuProps = Omit<MenuProps, "children"> & {
2868
+ /** The dropdown's content: Mantine `Menu.Item`s and the `TMDataGrid.Menu.*` items. */
2869
+ children: ReactNode;
2870
+ /** Replaces the burger icon on the trigger. */
2871
+ icon?: ReactNode;
2872
+ /** Tooltip and `aria-label` of the trigger. Default `labels.menuButton`. */
2873
+ label?: string;
2874
+ };
2875
+ type TMDataGridMenuColumnsProps = {
2876
+ /**
2877
+ * Renders a `Menu.Search` above the toggles: `"auto"` (the default) from
2878
+ * six hideable columns, `true` always, `false` never. Use `false` inside a
2879
+ * `Menu.Sub`.
2880
+ */
2881
+ searchable?: TMDataGridColumnSearchable;
2882
+ };
2883
+ /**
2884
+ * The whole column chooser as menu items: a search box, one checkbox item per
2885
+ * hideable column, show/hide all, and Reset layout. Renders nothing when no
2886
+ * column can be hidden.
2887
+ *
2888
+ * `searchable` is only for a block at the top level of a dropdown.
2889
+ * `Menu.Search` registers on the root menu context (`hasSearch`), which
2890
+ * switches off type-ahead and the arrow-key handling of every dropdown of that
2891
+ * menu, so a search inside a `Menu.Sub` breaks the parent menu's keyboard
2892
+ * behaviour.
2893
+ */
2894
+ declare function TMDataGridMenuColumns({ searchable }: TMDataGridMenuColumnsProps): import("react").JSX.Element | null;
2895
+ /**
2896
+ * One checkbox item per hideable column, narrowed to `search` when one is
2897
+ * given. Renders nothing when no column can be hidden.
2898
+ */
2899
+ declare function TMDataGridMenuColumnToggles({ search }: {
2900
+ search?: string;
2901
+ }): import("react").JSX.Element | null;
2902
+ /**
2903
+ * Shows or hides every listed column at once. Renders nothing when no column
2904
+ * can be hidden.
2905
+ */
2906
+ declare function TMDataGridMenuShowHideAll(): import("react").JSX.Element | null;
2907
+ /**
2908
+ * Resets the whole layout, not only visibility: order, widths, pinning and
2909
+ * grouping go back too. Not `table.resetColumnVisibility()`, which resets to
2910
+ * `initialState` - and under persistence the mount built that *from* the
2911
+ * persisted payload.
2912
+ */
2913
+ declare function TMDataGridMenuResetLayout(): import("react").JSX.Element;
2914
+ /** Per-item overrides of the grid's `exportOptions`, and the item's text. */
2915
+ type TMDataGridMenuExportProps = Omit<TMDataGridExportOptions, "columns"> & {
2916
+ /**
2917
+ * Which columns the item writes: `"visible"`, `"all"`, a list of ids, or
2918
+ * `"custom"` - a picker listing every exportable column with the visible
2919
+ * ones ticked, and the download on its Export button. Defaults to the grid's
2920
+ * `exportOptions.columns`.
2921
+ */
2922
+ columns?: TMDataGridExportColumns | "custom";
2923
+ /**
2924
+ * The item's text. Defaults to `labels.exportAll`, or for the selected-rows
2925
+ * item `labels.exportSelected(count)`. Two items offering two formats need
2926
+ * two texts, which is what this is for.
2927
+ */
2928
+ label?: ReactNode;
2929
+ };
2930
+ /**
2931
+ * Downloads every filtered and sorted row, all pages, in the grid's export
2932
+ * format. Props override `exportOptions` for this item alone, which is how one
2933
+ * menu offers two formats.
2934
+ */
2935
+ declare function TMDataGridMenuExport(props: TMDataGridMenuExportProps): import("react").JSX.Element;
2936
+ /**
2937
+ * Downloads the selected rows, in grid order. Disabled while nothing is
2938
+ * selected; renders nothing when row selection is off, since then there is
2939
+ * never anything for it to do.
2940
+ */
2941
+ declare function TMDataGridMenuExportSelected(props: TMDataGridMenuExportProps): import("react").JSX.Element | null;
2942
+ //#endregion
2943
+ //#region .types-tmp/components/TMDataGridColumnsPanel.d.ts
2944
+ /**
2945
+ * The "Manage columns" surface as plain controls, for a host that is not a
2946
+ * menu - a Popover, a Drawer, an inline layout. `TMDataGrid.Menu.Columns` is
2947
+ * the same chooser as menu items.
2948
+ */
2949
+ /** Mantine's style props (`w={320}`, `p="sm"`) are set on the panel block. */
2950
+ type TMDataGridColumnsPanelProps = BoxProps & {
2951
+ /**
2952
+ * The search box over the list: `"auto"` (the default) from six hideable
2953
+ * columns, `true` always, `false` never.
2954
+ */
2955
+ searchable?: TMDataGridColumnSearchable;
2956
+ };
2957
+ declare function TMDataGridColumnsPanel({ className, searchable, ...others }?: TMDataGridColumnsPanelProps): import("react").JSX.Element;
2958
+ //#endregion
2959
+ //#region .types-tmp/components/TMDataGridDraftActions.d.ts
2960
+ /** What the edit chrome is showing. */
2961
+ type TMDataGridDraftActionsState = {
2962
+ /**
2963
+ * Rows in the draft store, which is what Save sends: committed edits,
2964
+ * committed entry rows and deletion marks.
2965
+ */
2966
+ draftCount: number;
2967
+ /**
2968
+ * Rows still open - edited or entered but not committed, so not part of
2969
+ * the save. They stay open across a save.
2970
+ */
2971
+ openCount: number;
2972
+ /**
2973
+ * The ids behind {@link openCount}, in the order the grid opened them - a
2974
+ * sort, a filter or a page never moves this list. An entered row appears as
2975
+ * its `tempId`.
2976
+ *
2977
+ * Narrower than `edit.state.openRowIds`, which is every row holding a form,
2978
+ * the parked ones included. And note the ordering:
2979
+ * {@link TMDataGridDraftActionsActions.scrollToFirstOpenRow} takes "first"
2980
+ * in display order, so it need not be `openRowIds[0]`.
2981
+ */
2982
+ openRowIds: ReadonlyArray<string>;
2983
+ /**
2984
+ * @deprecated Was "everything uncommitted", which Save no longer sends.
2985
+ * Reads as `draftCount + openCount`; use whichever you meant.
2986
+ */
2987
+ pendingCount: number;
2988
+ /** Whether a submit is in flight - any open row is submitting. */
2989
+ isSubmitting: boolean;
2990
+ /** `true` while `saveDrafts` is in flight. */
2991
+ isSaving: boolean;
2992
+ };
2993
+ /** What the edit chrome can do. */
2994
+ type TMDataGridDraftActionsActions = {
2995
+ /** Saves the draft store. Open rows are left alone. */
2996
+ save: () => Promise<boolean>;
2997
+ /** Submits every open row, committing the ones that validate. */
2998
+ commitAll: () => Promise<boolean>;
2999
+ /** Drops everything - open form state and the draft store alike. */
3000
+ discard: () => void;
3001
+ /**
3002
+ * `grid.scrollToRow`, so a control in here can take the user to a row
3003
+ * without the grid being threaded down to it.
3004
+ */
3005
+ scrollToRow: (args: TMDataGridScrollToRowArgs) => boolean;
1919
3006
  /**
1920
- * What the virtualizer assumes an unmeasured detail panel is worth, in px.
1921
- * Defaults to 160.
3007
+ * Scrolls to the first row still open, taking "first" in display order: the
3008
+ * topmost open row under the current sort, filter and page. That need not
3009
+ * be {@link TMDataGridDraftActionsState.openRowIds}`[0]`, which is the
3010
+ * order the grid opened them in.
1922
3011
  *
1923
- * An estimate, not a height: every mounted row is measured, so the real one
1924
- * takes over as soon as the panel is on screen. It keeps the scrollbar
1925
- * accurate for panels that open off screen, such as restored `expanded`
1926
- * state. An approximate value is enough.
3012
+ * Answers whether an open row could be reached. `false` when nothing is
3013
+ * open, and when every open row is filtered out, on another page or
3014
+ * collapsed inside a group. An open entry row answers `true` without
3015
+ * scrolling - it is sticky under the header, so it is on screen already -
3016
+ * and so does an open row pinned to an edge. The scroll goes through
3017
+ * `scrollToRow`, so before `TMDataGrid.Table` has mounted there is nothing
3018
+ * to scroll and the answer is `false`.
1927
3019
  */
1928
- renderDetailsEstHeight?: number;
3020
+ scrollToFirstOpenRow: (align?: TMDataGridScrollAlign) => boolean;
3021
+ };
3022
+ /** The pre-bound pieces of the built-in edit chrome. */
3023
+ type TMDataGridDraftActionsControls = {
3024
+ /** Save, with the draft count, disabled while the draft store is empty. */
3025
+ Save: () => ReactNode;
3026
+ /** Discard, disabled while nothing is pending. */
3027
+ Discard: () => ReactNode;
3028
+ /** The "N rows still being edited" note, or nothing while there are none. */
3029
+ OpenRowsNote: () => ReactNode;
3030
+ };
3031
+ /** What {@link TMDataGridDraftActionsProps.renderActions} is handed. */
3032
+ type TMDataGridDraftActionsSlotArgs = {
3033
+ state: TMDataGridDraftActionsState;
3034
+ actions: TMDataGridDraftActionsActions;
3035
+ Controls: TMDataGridDraftActionsControls;
3036
+ };
3037
+ type TMDataGridDraftActionsProps = {
1929
3038
  /**
1930
- * Rows the virtualizer keeps mounted above and below the viewport. Defaults
1931
- * to 6.
3039
+ * Replaces the built-in Save/Discard pair, and is handed the pieces of it.
1932
3040
  *
1933
- * Raise it to trade memory for a scroll that stays painted - fast wheel or
1934
- * touch flings can outrun the virtualizer and flash blank rows, and a larger
1935
- * buffer covers the gap. Lower it when rows are expensive to render.
3041
+ * ```tsx
3042
+ * <TMDataGrid.DraftActions
3043
+ * renderActions={({ state, Controls }) => (
3044
+ * <Group>
3045
+ * {state.draftCount > 0 && <Badge>{state.draftCount}</Badge>}
3046
+ * <Controls.OpenRowsNote />
3047
+ * <Controls.Save />
3048
+ * <Controls.Discard />
3049
+ * </Group>
3050
+ * )}
3051
+ * />
3052
+ * ```
1936
3053
  */
1937
- overscan?: number;
3054
+ renderActions?: (args: TMDataGridDraftActionsSlotArgs) => ReactNode;
1938
3055
  };
1939
3056
  /**
1940
- * Builds a TMDataGrid table plus its chrome store.
3057
+ * The draft store's toolbar chrome: Save with the store's count, Discard, and
3058
+ * a note counting the rows still open. Save sends the store and leaves open
3059
+ * rows alone, so it greys out while nothing is parked however much is being
3060
+ * typed - the note is what makes those rows visible.
1941
3061
  *
1942
- * Every `TableOptions` field passes straight through, so a server-driven grid
1943
- * only needs `manualPagination` / `manualFiltering` / `manualSorting`,
1944
- * `rowCount` and the matching `onXChange` callbacks - the chrome reads
1945
- * `getRowCount()` / `getPageCount()` / `getPaginatedRowModel()`, all of which
1946
- * already respect manual mode. `manualPagination` also switches the pagination
1947
- * flag on, so `<TMDataGrid.Footer />` renders its pager without further
1948
- * options.
3062
+ * Works under any `editing.mode`. The toolbar is declarative: the grid does
3063
+ * not decide for you, so include this only when the grid runs a draft store -
3064
+ * without `editing.draft` there is nothing to save and Save stays disabled.
3065
+ *
3066
+ * ```tsx
3067
+ * <TMDataGrid.Toolbar>
3068
+ * <TMDataGrid.SummaryCount />
3069
+ * <TMDataGrid.Spacer />
3070
+ * <TMDataGrid.DraftActions />
3071
+ * </TMDataGrid.Toolbar>
3072
+ * ```
1949
3073
  */
1950
- declare function useTMDataGrid<TData extends RowData>({ persist, labels: labelsOverride, enableColumnOrdering, enablePagination, enableRowNumbers, selectionMode, showSelectedBackground, defaultHighlightedRowId, onHighlightedRowChange, cellSelection, onFocusedCellChange, editing, renderDetails, renderDetailsEstHeight, overscan, ...options }: UseTMDataGridOptions<TData>): TMDataGridApi<TData>;
3074
+ declare function TMDataGridDraftActions({ renderActions }?: TMDataGridDraftActionsProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
3075
+ //#endregion
3076
+ //#region .types-tmp/components/TMDataGridFilterPanel.d.ts
3077
+ /** Mantine's style props (`p="md"`, `w={320}`) are set on the panel block. */
3078
+ type TMDataGridFilterPanelProps = BoxProps & {
3079
+ /**
3080
+ * How one filter row is laid out.
3081
+ *
3082
+ * `"row"` - the default - puts column, operator and value side by side,
3083
+ * which wants about 550px. `"stacked"` puts them one under the other, each
3084
+ * filling the width, for a host too narrow for that: the sidebar surface
3085
+ * uses it, and so should a panel you place in a drawer or a narrow column.
3086
+ *
3087
+ * Passed through to every value control as its `layout`, so a
3088
+ * `meta.filter.control` can size itself to the same decision.
3089
+ */
3090
+ layout?: TMDataGridFilterPanelLayout;
3091
+ };
1951
3092
  /**
1952
- * Opens the filter panel for a column, seeding an empty filter row when the
1953
- * column has none yet - mirrors "Filter" in the column header menu.
3093
+ * The MUI-style filter surface: one row per active column filter, each row a
3094
+ * column / operator / value triple, over an "Add filter" / "Clear all" footer.
3095
+ *
3096
+ * A plain block of controls, the way `TMDataGrid.ColumnsPanel` is - it renders
3097
+ * whenever it is mounted and knows nothing about floating. The chrome that
3098
+ * makes a floating surface (a title, a close button, click-away, Escape)
3099
+ * belongs to the popup and the sidebar, so this can equally be dropped into a
3100
+ * drawer, a page column or a form. See the `filters.surface` option.
3101
+ *
3102
+ * It only ever reads and writes the table's `columnFilters` state, so a
3103
+ * `manualFiltering` grid gets the same panel for free - the state is forwarded
3104
+ * to the server instead of a row model.
1954
3105
  */
1955
- declare function openColumnFilter<TData extends RowData>(api: TMDataGridApi<TData>, columnId: string): void;
3106
+ declare function TMDataGridFilterPanel({ layout, className, ...others }?: TMDataGridFilterPanelProps): import("react").JSX.Element;
1956
3107
  //#endregion
1957
3108
  //#region .types-tmp/components/TMDataGridFilterPills.d.ts
1958
- type TMDataGridFilterPillsProps<TData extends RowData> = {
3109
+ /** Mantine's style props (`mb="sm"`, `hiddenFrom="sm"`) are set on the wrapper. */
3110
+ type TMDataGridFilterPillsProps<TData extends RowData> = BoxProps & {
1959
3111
  /** The object returned by `useTMDataGrid`. */
1960
3112
  api: TMDataGridApi<TData>;
1961
3113
  /** Mantine size of the pills. Defaults to `"sm"`. */
@@ -1967,7 +3119,6 @@ type TMDataGridFilterPillsProps<TData extends RowData> = {
1967
3119
  * filter panel on that column.
1968
3120
  */
1969
3121
  onPillClick?: (columnId: string) => void;
1970
- className?: string;
1971
3122
  };
1972
3123
  /**
1973
3124
  * One pill per active filter (`First name: Sofia ✕`), with the ✕ clearing that
@@ -1989,7 +3140,7 @@ type TMDataGridFilterPillsProps<TData extends RowData> = {
1989
3140
  * Half-typed filters are left out: a filter that is not narrowing the rows yet
1990
3141
  * has nothing to report, which is the same rule the funnel indicator uses.
1991
3142
  */
1992
- declare function TMDataGridFilterPills<TData extends RowData>({ api, size, showClearAll, onPillClick, className }: TMDataGridFilterPillsProps<TData>): import("react").JSX.Element | null;
3143
+ declare function TMDataGridFilterPills<TData extends RowData>({ api, size, showClearAll, onPillClick, className, ...others }: TMDataGridFilterPillsProps<TData>): import("react").JSX.Element | null;
1993
3144
  //#endregion
1994
3145
  //#region .types-tmp/components/TMDataGridFooter.d.ts
1995
3146
  /** What the pager is showing. The read half of {@link TMDataGridPaginationApi}. */
@@ -2043,6 +3194,12 @@ type TMDataGridPaginationControls = {
2043
3194
  PageSize: () => ReactNode;
2044
3195
  /** The "1–25 of 300" range label. */
2045
3196
  Range: () => ReactNode;
3197
+ /**
3198
+ * The "Page 3 of 200" label - what a server-paged grid usually shows in
3199
+ * place of a row range. Not in the default footer; put it in a
3200
+ * `renderPagination` layout.
3201
+ */
3202
+ PageNumber: () => ReactNode;
2046
3203
  /** The previous/next buttons. */
2047
3204
  Pager: () => ReactNode;
2048
3205
  };
@@ -2059,7 +3216,8 @@ type TMDataGridPaginationSlotArgs = TMDataGridPaginationApi & {
2059
3216
  * this function takes only a table.
2060
3217
  */
2061
3218
  declare function getTMDataGridPaginationApi<TData extends RowData>(table: TMDataGridTable<TData>, isPaging?: boolean): TMDataGridPaginationApi;
2062
- type TMDataGridFooterProps = {
3219
+ /** Mantine's style props (`mt="sm"`, `px="md"`) are set on the footer bar. */
3220
+ type TMDataGridFooterProps = BoxProps & {
2063
3221
  pageSizeOptions?: ReadonlyArray<number>;
2064
3222
  /**
2065
3223
  * Replaces the built-in pager, and is handed the pieces of it.
@@ -2069,7 +3227,7 @@ type TMDataGridFooterProps = {
2069
3227
  * renderPagination={({ state, actions, Controls }) => (
2070
3228
  * <Group>
2071
3229
  * <Controls.PageSize />
2072
- * <MyJumpToPage page={state.pageIndex} onJump={actions.setPageIndex} />
3230
+ * <Controls.PageNumber />
2073
3231
  * <Controls.Pager />
2074
3232
  * </Group>
2075
3233
  * )}
@@ -2088,7 +3246,7 @@ type TMDataGridFooterProps = {
2088
3246
  * Row totals come from `table.getRowCount()`, which prefers `options.rowCount`
2089
3247
  * - so a server-paged grid shows the server's total without changes here.
2090
3248
  */
2091
- declare function TMDataGridFooter({ pageSizeOptions, renderPagination }: TMDataGridFooterProps): import("react").JSX.Element | null;
3249
+ declare function TMDataGridFooter({ pageSizeOptions, renderPagination, className, ...others }: TMDataGridFooterProps): import("react").JSX.Element | null;
2092
3250
  //#endregion
2093
3251
  //#region .types-tmp/components/TMDataGridSearch.d.ts
2094
3252
  type TMDataGridSearchProps = {
@@ -2147,135 +3305,6 @@ type TMDataGridColumnMenuItemsArgs = {
2147
3305
  */
2148
3306
  type TMDataGridColumnMenuItemsRenderer = (args: TMDataGridColumnMenuItemsArgs) => Array<ReactNode>;
2149
3307
  //#endregion
2150
- //#region .types-tmp/core/cellExport.d.ts
2151
- /** The selected block, flattened to text. One inner array per row. */
2152
- type TMDataGridCellMatrix = Array<Array<string>>;
2153
- /**
2154
- * How values are written out.
2155
- *
2156
- * The defaults are the Nordic ones, because they are the ones that need
2157
- * choosing: an Excel running a Swedish, Norwegian, Danish or Finnish locale
2158
- * reads `;` as its list separator and `,` as its decimal mark, and a file
2159
- * written the other way opens as one column of text. Both are settable for a
2160
- * grid whose users run something else.
2161
- */
2162
- type TMDataGridCellExportOptions = {
2163
- /** CSV field separator. Defaults to `";"`. */
2164
- separator?: string;
2165
- /** Write numbers as `1,5` rather than `1.5`. Defaults to `true`. */
2166
- decimalComma?: boolean;
2167
- /** Column labels as the first row. Defaults to `true`. */
2168
- includeHeaders?: boolean;
2169
- /** Without extension. Defaults to `"export"`. */
2170
- fileName?: string;
2171
- };
2172
- type ResolvedExportOptions = Required<TMDataGridCellExportOptions>;
2173
- declare const DEFAULT_CELL_EXPORT_OPTIONS: ResolvedExportOptions;
2174
- /**
2175
- * One value as text.
2176
- *
2177
- * Deliberately not the rendered cell: what a cell renders is React, and often a
2178
- * badge, a link or an icon rather than the value. The value is what a
2179
- * spreadsheet wants, and it is the one thing every column is guaranteed to
2180
- * have.
2181
- */
2182
- declare function formatExportValue(value: unknown, { decimalComma }: {
2183
- decimalComma: boolean;
2184
- }): string;
2185
- type BuildCellMatrixArgs = {
2186
- rows: ReadonlyArray<Row<TMDataGridFeatures, TMDataGridRowData>>;
2187
- /** Every visible column, in render order - the same list the bounds index into. */
2188
- columns: ReadonlyArray<Column<TMDataGridFeatures, TMDataGridRowData, unknown>>;
2189
- bounds: TMDataGridRangeBounds;
2190
- includeHeaders: boolean;
2191
- decimalComma: boolean;
2192
- };
2193
- /**
2194
- * The selected rectangle as rows of text.
2195
- *
2196
- * The generated lanes - the checkbox, the tree chevron, the details chevron -
2197
- * are dropped even when the rectangle covers them. They hold controls rather
2198
- * than data, so a column of empty strings is all they could contribute, and
2199
- * pasting one into a spreadsheet only shifts everything to its right.
2200
- */
2201
- declare function buildCellMatrix({ rows, columns, bounds, includeHeaders, decimalComma }: BuildCellMatrixArgs): TMDataGridCellMatrix;
2202
- /**
2203
- * The whole grid as rows of text: every filtered and sorted data row - all
2204
- * pages, not the one on screen - by every visible non-control column, in
2205
- * render order.
2206
- *
2207
- * The values are the same ones a cell-range export writes; only the bounds
2208
- * differ. Group rows are left out (their records are the rows themselves),
2209
- * and hidden columns are not exported - what you see is what you get, minus
2210
- * paging.
2211
- */
2212
- declare function buildGridCellMatrix<TData extends RowData>({ table, includeHeaders, decimalComma }: {
2213
- table: TMDataGridTable<TData>;
2214
- includeHeaders?: boolean;
2215
- decimalComma?: boolean;
2216
- }): TMDataGridCellMatrix;
2217
- /**
2218
- * Downloads the whole grid as a CSV for Excel - {@link buildGridCellMatrix}
2219
- * through {@link toExcelCsv}, with the same Nordic defaults and overrides as
2220
- * the cell-range export.
2221
- *
2222
- * No built-in button: wire it to your own toolbar.
2223
- *
2224
- * ```tsx
2225
- * <Button onClick={() => exportGridToCsv({ table: grid.table })}>Export</Button>
2226
- * ```
2227
- */
2228
- declare function exportGridToCsv<TData extends RowData>({ table, options }: {
2229
- table: TMDataGridTable<TData>;
2230
- options?: TMDataGridCellExportOptions;
2231
- }): void;
2232
- /**
2233
- * The clipboard format spreadsheets read: tab between cells, CRLF between rows.
2234
- *
2235
- * Tabs rather than commas because that is what Excel, Sheets and Numbers all
2236
- * put on the clipboard themselves - paste it and the cells land in cells. A
2237
- * comma-separated string pastes into a single column, which is the thing this
2238
- * exists to avoid.
2239
- */
2240
- declare function toClipboardText(matrix: TMDataGridCellMatrix): string;
2241
- /**
2242
- * A CSV that opens straight into columns in Excel.
2243
- *
2244
- * Three things make that true, and all three are needed:
2245
- *
2246
- * | Part | Why |
2247
- * | ---- | --- |
2248
- * | `sep=;` first line | Excel's own directive - it stops guessing and uses this |
2249
- * | UTF-8 BOM | without it Excel reads the file as ANSI, and å ä ö arrive broken |
2250
- * | CRLF line endings | what Excel writes, and what its importer is happiest with |
2251
- *
2252
- * The `sep=` line is Excel's alone; other readers show it as a first row. This
2253
- * export targets Excel, so opening correctly there takes priority over strict
2254
- * CSV.
2255
- */
2256
- declare function toExcelCsv(matrix: TMDataGridCellMatrix, { separator }: {
2257
- separator: string;
2258
- }): string;
2259
- /**
2260
- * Puts text on the clipboard, reporting whether it landed.
2261
- *
2262
- * The async clipboard API only resolves for a document that has the focus and a
2263
- * user gesture behind it - both true when this runs off Ctrl+C or a menu item.
2264
- * It is still allowed to reject (a permissions policy, a page that lost focus
2265
- * mid-copy), so the result is a boolean the caller can act on.
2266
- */
2267
- declare function writeClipboardText(text: string): Promise<boolean>;
2268
- /**
2269
- * Downloads text as a file, through the one mechanism a library can use: an
2270
- * anchor with an object URL behind it, clicked. Revoked on the next frame -
2271
- * immediately would race the browser's own read of it.
2272
- */
2273
- declare function downloadTextFile({ fileName, text, mimeType }: {
2274
- fileName: string;
2275
- text: string;
2276
- mimeType?: string;
2277
- }): void;
2278
- //#endregion
2279
3308
  //#region .types-tmp/components/TMDataGridTable.d.ts
2280
3309
  /** Where a column sits relative to the pinned regions, resolved once per render. */
2281
3310
  type TMDataGridColumnLayout = {
@@ -2484,9 +3513,10 @@ type TMDataGridTableProps<TData extends RowData> = {
2484
3513
  */
2485
3514
  rowContextMenuProps?: Omit<MenuProps, "opened" | "onChange" | "children">;
2486
3515
  /**
2487
- * How Ctrl+C and the export item write values, under
2488
- * `cellSelection: "range"`. Defaults to the Nordic Excel conventions - see
2489
- * {@link TMDataGridCellExportOptions}.
3516
+ * @deprecated Set `exportOptions` on `useTMDataGrid` instead; it covers the
3517
+ * cell-range menu and every other export alike. Until it goes, this is
3518
+ * converted (`separator` and `decimalComma` become a `csvExcelFormat`) and
3519
+ * merged over `exportOptions` for the cell-range menu only.
2490
3520
  */
2491
3521
  cellExport?: TMDataGridCellExportOptions;
2492
3522
  /**
@@ -2526,12 +3556,22 @@ type TMDataGridTableProps<TData extends RowData> = {
2526
3556
  declare function TMDataGridTable$1<TData extends RowData = TMDataGridRowData>({ onRowClick, onCellClick, onCellDoubleClick, onCellContextMenu, rowClassName, rowStyle, striped, onScrollToTop, onScrollToBottom, onScrollToLeft, onScrollToRight, renderEmptyState, renderRowContextMenu, renderColumnMenuItems, rowContextMenuProps, cellExport, onReachEnd, reachEndThreshold, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }: TMDataGridTableProps<TData>): import("react").JSX.Element;
2527
3557
  //#endregion
2528
3558
  //#region .types-tmp/components/TMDataGridToolbar.d.ts
2529
- /** Row above the grid. Compose it from the pieces below, or anything else. */
2530
- declare function TMDataGridToolbar({ children }: {
3559
+ type TMDataGridToolbarProps = BoxProps & {
2531
3560
  children?: ReactNode;
2532
- }): import("react").JSX.Element;
2533
- /** Pushes the following toolbar items to the right. */
2534
- declare function TMDataGridToolbarSpacer(): import("react").JSX.Element;
3561
+ /**
3562
+ * Draws a 1px line under the toolbar in the theme's default border colour -
3563
+ * the same line the header draws under itself. Defaults to `false`.
3564
+ */
3565
+ withBottomBorder?: boolean;
3566
+ };
3567
+ /**
3568
+ * Row above the grid. Compose it from the pieces below, or anything else.
3569
+ * Takes Mantine's style props (`mb="sm"`, `px="md"`, `hiddenFrom="sm"`) and
3570
+ * sets them on the row.
3571
+ */
3572
+ declare function TMDataGridToolbar({ children, withBottomBorder, className, mod, ...others }: TMDataGridToolbarProps): import("react").JSX.Element;
3573
+ /** Pushes the following toolbar items to the right. Takes Mantine's style props. */
3574
+ declare function TMDataGridToolbarSpacer({ className, ...others }: BoxProps): import("react").JSX.Element;
2535
3575
  /**
2536
3576
  * A small spinner shown while `meta.loading` is true, and nothing otherwise.
2537
3577
  *
@@ -2553,18 +3593,22 @@ declare function TMDataGridLoadingIndicator(): import("react").JSX.Element | nul
2553
3593
  /**
2554
3594
  * Visible rows over total rows. On a server-driven grid, set
2555
3595
  * `meta.totalRowCount` for the denominator - the client never sees every row.
3596
+ * Without it the count is rendered alone, since the fallback denominator would
3597
+ * be the rows the server sent for the current page: a plausible-looking wrong
3598
+ * total, and on an unfiltered first page the same number twice.
2556
3599
  */
2557
3600
  declare function TMDataGridSummaryCount({ children }: {
2558
3601
  children?: ReactNode;
2559
3602
  }): import("react").JSX.Element;
2560
3603
  /**
2561
- * Burger menu in the grid's top-right corner - opens "Manage columns".
2562
- * Renders nothing when no column can be hidden (`enableHiding: false`).
2563
- */
2564
- declare function TMDataGridColumnsButton(): import("react").JSX.Element | null;
2565
- /**
2566
- * Toggles the filter panel, seeding a filter row on the first filterable column.
2567
- * Renders nothing when no column can be filtered (`enableColumnFilters: false`).
3604
+ * Toggles the grid's filter surface - the popup or the sidebar, whichever
3605
+ * `filters.surface` names - seeding a filter row on the first filterable
3606
+ * column. The count of active filters tints it.
3607
+ *
3608
+ * Renders nothing when no column can be filtered (`enableColumnFilters:
3609
+ * false`), and nothing under `filters.surface: "none"`, where there is no
3610
+ * automatic surface for it to toggle. Read `ui.state.filterPanelOpen` and
3611
+ * render your own control if a hand-placed panel wants one.
2568
3612
  */
2569
3613
  declare function TMDataGridFilterButton(): import("react").JSX.Element | null;
2570
3614
  //#endregion
@@ -2598,6 +3642,7 @@ type TMDataGridProps<TData extends RowData> = TMDataGridApi<TData> & {
2598
3642
  */
2599
3643
  "data-testid"?: string;
2600
3644
  };
3645
+ declare function TMDataGridRoot<TData extends RowData>({ table, ui, edit, features, filters, exportOptions, labels, renderDetails, renderDetailsEstHeight, overscan, resetSettings, scrollToRow, scrollerRef, size, children, className, style, id, "data-testid": testId }: TMDataGridProps<TData>): import("react").JSX.Element;
2601
3646
  /**
2602
3647
  * Root of the grid. Takes the object returned by `useTMDataGrid` - spread it -
2603
3648
  * and publishes it to the compound components below it:
@@ -2609,22 +3654,30 @@ type TMDataGridProps<TData extends RowData> = TMDataGridApi<TData> & {
2609
3654
  * <TMDataGrid.Toolbar>
2610
3655
  * <TMDataGrid.SummaryCount />
2611
3656
  * <TMDataGrid.Spacer />
2612
- * <TMDataGrid.ColumnsButton />
3657
+ * <TMDataGrid.Menu>
3658
+ * <TMDataGrid.Menu.Columns />
3659
+ * </TMDataGrid.Menu>
2613
3660
  * </TMDataGrid.Toolbar>
2614
3661
  * <TMDataGrid.Table />
2615
3662
  * <TMDataGrid.Footer />
2616
3663
  * </TMDataGrid>
2617
3664
  * ```
2618
3665
  */
2619
- declare function TMDataGridRoot<TData extends RowData>({ table, ui, edit, features, labels, renderDetails, renderDetailsEstHeight, overscan, resetSettings, scrollToRow, scrollerRef, size, children, className, style, id, "data-testid": testId }: TMDataGridProps<TData>): import("react").JSX.Element;
2620
3666
  declare const TMDataGrid: typeof TMDataGridRoot & {
2621
3667
  Toolbar: typeof TMDataGridToolbar;
2622
3668
  Spacer: typeof TMDataGridToolbarSpacer;
2623
3669
  SummaryCount: typeof TMDataGridSummaryCount;
2624
3670
  LoadingIndicator: typeof TMDataGridLoadingIndicator;
2625
3671
  Search: typeof TMDataGridSearch;
2626
- EditActions: typeof TMDataGridEditActions;
2627
- ColumnsButton: typeof TMDataGridColumnsButton;
3672
+ DraftActions: typeof TMDataGridDraftActions;
3673
+ Menu: (({ children, icon, label, ...menuProps }: TMDataGridMenuProps) => import("react").JSX.Element) & {
3674
+ Columns: typeof TMDataGridMenuColumns;
3675
+ ColumnToggles: typeof TMDataGridMenuColumnToggles;
3676
+ ShowHideAll: typeof TMDataGridMenuShowHideAll;
3677
+ ResetLayout: typeof TMDataGridMenuResetLayout;
3678
+ Export: typeof TMDataGridMenuExport;
3679
+ ExportSelected: typeof TMDataGridMenuExportSelected;
3680
+ };
2628
3681
  FilterButton: typeof TMDataGridFilterButton;
2629
3682
  Table: typeof TMDataGridTable$1;
2630
3683
  Footer: typeof TMDataGridFooter;
@@ -2635,7 +3688,10 @@ declare const TMDataGrid: typeof TMDataGridRoot & {
2635
3688
  * rendered outside `<TMDataGrid>` - a page header, for instance.
2636
3689
  */
2637
3690
  FilterPills: typeof TMDataGridFilterPills;
2638
- /** Rendered by `TMDataGrid.ColumnsButton`; exported for custom layouts. */
3691
+ /**
3692
+ * The column chooser as plain controls, for a Popover, a Drawer or an
3693
+ * inline layout; `TMDataGrid.Menu.Columns` is the same thing as menu items.
3694
+ */
2639
3695
  ColumnsPanel: typeof TMDataGridColumnsPanel;
2640
3696
  };
2641
3697
  //#endregion
@@ -2662,17 +3718,60 @@ declare const GROUP_COLUMN_ID = "__group__";
2662
3718
  */
2663
3719
  declare function formatGroupValue(value: unknown, blankLabel?: string): string;
2664
3720
  //#endregion
3721
+ //#region .types-tmp/useTMDataGridExport.d.ts
3722
+ /** What {@link useTMDataGridExport} returns. */
3723
+ type TMDataGridExportApi = {
3724
+ /**
3725
+ * Downloads every filtered and sorted row, all pages. `overrides` are folded
3726
+ * over the hook's options for this one call - the column picker's chosen
3727
+ * columns, for instance.
3728
+ */
3729
+ exportAll: (overrides?: TMDataGridExportOptions) => Promise<void>;
3730
+ /**
3731
+ * Downloads the selected rows of the current view, in grid order. Resolves
3732
+ * without a download when none is selected.
3733
+ */
3734
+ exportSelected: (overrides?: TMDataGridExportOptions) => Promise<void>;
3735
+ /** How many rows `exportSelected` would write. Subscribes to the selection. */
3736
+ selectedCount: number;
3737
+ /**
3738
+ * Whether row selection is on at all - `false` under
3739
+ * `selectionMode: "highlight"` or `enableRowSelection: false`, where a
3740
+ * "selected rows" control has nothing to offer.
3741
+ */
3742
+ canExportSelected: boolean;
3743
+ };
3744
+ /**
3745
+ * The export as click handlers, for a button of your own anywhere inside the
3746
+ * grid. The `TMDataGrid.Menu.Export*` items are this hook behind a
3747
+ * `Menu.Item`.
3748
+ *
3749
+ * ```tsx
3750
+ * function ExportButton() {
3751
+ * const { exportAll } = useTMDataGridExport();
3752
+ * return <Button onClick={() => void exportAll()}>Export</Button>;
3753
+ * }
3754
+ * ```
3755
+ *
3756
+ * `overrides` are folded over the grid's `exportOptions` for this caller:
3757
+ * another format, another file name, another set of columns.
3758
+ */
3759
+ declare function useTMDataGridExport(overrides?: TMDataGridExportOptions): TMDataGridExportApi;
3760
+ //#endregion
2665
3761
  //#region .types-tmp/components/filters/TMDataGridFilterValueInput.d.ts
2666
3762
  /**
2667
- * The built-in value control of a filter-panel row - what renders when a
2668
- * column declares no `meta.filter.control`. Shaped by the operator: a
2669
- * multi-select for the set operators, a From/To pair for `between`, a Yes/No
2670
- * dropdown for booleans, a typed input otherwise.
3763
+ * The built-in value control of a filter row - what renders when a column
3764
+ * declares no `meta.filter.control`. Shaped by the operator: a multi-select
3765
+ * for the set operators, a From/To pair for `between`, a Yes/No dropdown for
3766
+ * booleans, a typed input otherwise.
3767
+ *
3768
+ * Shaped by `layout` as well: in a header cell the fields drop their labels,
3769
+ * fill the column's width and name themselves through `aria-label`.
2671
3770
  *
2672
3771
  * Exported so a custom control can fall back to it for the operators it does
2673
3772
  * not care about, instead of rebuilding them.
2674
3773
  */
2675
- declare function TMDataGridFilterValueInput({ column, operator, value, onChange, options, size, labels }: TMDataGridFilterControlArgs): import("react").JSX.Element;
3774
+ declare function TMDataGridFilterValueInput(args: TMDataGridFilterControlArgs): import("react").JSX.Element;
2676
3775
  //#endregion
2677
3776
  //#region .types-tmp/components/filters/DgRangeSliderFilter.d.ts
2678
3777
  /**
@@ -2760,77 +3859,6 @@ declare function TMDataGridMultiSelectEditor({ field, column, row, table, size }
2760
3859
  */
2761
3860
  declare const TMDATAGRID_LABELS_SV: TMDataGridLabels;
2762
3861
  //#endregion
2763
- //#region .types-tmp/core/columnUtils.d.ts
2764
- /**
2765
- * Structural shape of the column bits the chrome reads. Kept minimal so these
2766
- * helpers work with any `Column`/`Header` instance without dragging generics
2767
- * through every call site.
2768
- */
2769
- type ColumnLike = {
2770
- id: string;
2771
- columnDef: {
2772
- header?: unknown;
2773
- meta?: TMDataGridColumnMeta;
2774
- };
2775
- /** Set on a leaf that sits inside a header group. */
2776
- parent?: unknown;
2777
- };
2778
- /** Menu- and panel-facing column name. */
2779
- declare function getColumnLabel(column: ColumnLike): string;
2780
- declare function getColumnType(column: ColumnLike): TMDataGridColumnType;
2781
- /**
2782
- * The operator a fresh filter on this column starts with -
2783
- * `meta.filter.defaultOperator`, else the type's default.
2784
- */
2785
- declare function getColumnDefaultOperator(column: ColumnLike): TMDataGridFilterOperator;
2786
- /**
2787
- * This column's filter-panel value control - `meta.filter.control`, or
2788
- * `undefined` for the built-in shape-by-operator input.
2789
- */
2790
- declare function getColumnFilterControl(column: ColumnLike): TMDataGridFilterControlComponent | undefined;
2791
- /**
2792
- * Whether `meta.edit.enabled` lets this column's cell on this row be edited -
2793
- * the switch, then the predicate.
2794
- *
2795
- * This is only the column's half of the rule. A cell also needs the column to
2796
- * map to a field (`getEditFieldName`) and the row to take edits at all
2797
- * (`isRowEditable`); `edit.canEditCell` is the whole question.
2798
- */
2799
- declare function isColumnEditableForRow(column: ColumnLike, row: Row<TMDataGridFeatures, TMDataGridRowData>): boolean;
2800
- /**
2801
- * A generated lane holding one fixed-width thing - the checkbox, the details
2802
- * chevron, the row number.
2803
- *
2804
- * They are laid out differently from every other column: cell padding is sized
2805
- * for text and grows with the scale, which at `xl` squeezed a 16px checkbox out
2806
- * of its track, so these lanes centre their content in an unpadded cell.
2807
- * Their headers carry no column menu, and none of them is ever exported -
2808
- * they hold chrome, not values.
2809
- *
2810
- * The tree column is deliberately not one of them: it holds a label as well as a
2811
- * chevron, and wants the padding.
2812
- */
2813
- declare function isControlColumn(columnId: string): boolean;
2814
- /**
2815
- * Whether the grid generated this column rather than the consumer declaring it
2816
- * - the four control lanes plus the tree column.
2817
- *
2818
- * These hold the grid's own chrome, and they keep the edges of the row: the
2819
- * generated left lanes before every consumer column, the edit lane after all of
2820
- * them. `isControlColumn` answers a narrower question about layout, and leaves
2821
- * the tree column out because it is padded like a data column.
2822
- */
2823
- declare function isGeneratedColumn(columnId: string): boolean;
2824
- /**
2825
- * Whether a column may be moved. Ordering is the one column feature TanStack
2826
- * has no column option for, so the switch lives in `meta.enableOrdering`.
2827
- *
2828
- * A leaf inside a header group is never movable: `columnOrder` sequences leaf
2829
- * columns, so moving one out of its group would leave the group header spanning
2830
- * columns that no longer belong to it.
2831
- */
2832
- declare function isColumnReorderable(column: ColumnLike): boolean;
2833
- //#endregion
2834
3862
  //#region .types-tmp/core/grouping.d.ts
2835
3863
  /**
2836
3864
  * The data rows under a group row, at any depth.
@@ -2862,6 +3890,10 @@ type TMDataGridAggregationName = keyof typeof aggregationFns;
2862
3890
  * Filtered rather than paginated rows, so the total covers everything the
2863
3891
  * filters left (all pages), and follows the filters as they change. Reuses
2864
3892
  * TanStack's registered aggregation functions; `fn` defaults to `"sum"`.
3893
+ *
3894
+ * Every data row counts once. Grouping builds its group rows from this model
3895
+ * rather than into it, so a grouped grid totals its records, not its records
3896
+ * plus their subtotals; a tree counts parents and children alike.
2865
3897
  */
2866
3898
  declare function aggregateColumn<TData extends RowData>({ table, columnId, fn }: {
2867
3899
  table: TMDataGridTable<TData>;
@@ -2950,11 +3982,11 @@ type GridTable = TMDataGridTable<TMDataGridRowData>;
2950
3982
  * The lane a column renders in.
2951
3983
  *
2952
3984
  * Pinning splits the grid into three, and TanStack sequences them from two
2953
- * different state slices: `columnPinning.left` / `.right` order the pinned
3985
+ * different state slices: `columnPinning.start` / `.end` order the pinned
2954
3986
  * lanes, `columnOrder` orders the centre. A move therefore always stays inside
2955
3987
  * one lane - moving a column into another one would be a pin, not a reorder.
2956
3988
  */
2957
- type TMDataGridColumnRegion = "left" | "center" | "right";
3989
+ type TMDataGridColumnRegion = "start" | "center" | "end";
2958
3990
  /** Which edge of the column under the pointer a dragged column lands on. */
2959
3991
  type TMDataGridDropSide = "before" | "after";
2960
3992
  declare function getColumnRegion(columnPinning: ColumnPinningState, columnId: string): TMDataGridColumnRegion;
@@ -2980,7 +4012,7 @@ declare function moveColumn({ table, columnId, targetId, side }: MoveColumnArgs)
2980
4012
  * Puts the generated lanes back on the outside of both pinned lanes: the ones
2981
4013
  * on the left before every consumer column, the edit lane after all of them.
2982
4014
  *
2983
- * `column.pin("right")` appends, so pinning a column right would otherwise drop
4015
+ * `column.pin("end")` appends, so pinning a column right would otherwise drop
2984
4016
  * it outside the edit lane, so the row's Save and Delete would no longer be
2985
4017
  * last in the row. Pinning left appends too, which is already correct there,
2986
4018
  * but the same pass keeps both lanes in place whatever a consumer writes into
@@ -3106,4 +4138,4 @@ declare function getSelectableRowIds<TData extends RowData>(row: Row<TMDataGridF
3106
4138
  */
3107
4139
  declare function resolveRowSelectionClick<TData extends RowData>({ rows, rowId, anchorRowId, modifiers, selection, canReplaceSelection }: ResolveRowSelectionClickArgs<TData>): ResolvedRowSelection;
3108
4140
  //#endregion
3109
- export { type BuildCellMatrixArgs, type ColumnStepArgs, DATA_STATE_SLICES, DEFAULT_CELL_EXPORT_OPTIONS, DEFAULT_TMDATAGRID_SIZE, DETAILS_COLUMN_ID, DgAutocompleteFilter, DgDateRangeFilter, DgRangeSliderFilter, DgTriStateFilter, EDIT_COLUMN_ID, FILTER_OPERATOR_LABELS, GROUP_COLUMN_ID, type MoveColumnArgs, PERSIST_PAYLOAD_VERSION, ROW_NUMBER_COLUMN_ID, type ResolveCellMoveArgs, type ResolveRangeBoundsArgs, type ResolveRowSelectionClickArgs, type ResolvedRowSelection, SELECT_COLUMN_ID, SETTINGS_STATE_SLICES, SIZE_CONTROL_SIZE, SIZE_ROW_HEIGHT, TMDATAGRID_LABELS_EN, TMDATAGRID_LABELS_SV, TMDataGrid, type TMDataGridAggregationName, type TMDataGridApi, TMDataGridBooleanEditor, type TMDataGridCapabilities, type TMDataGridCellCoords, type TMDataGridCellEventArgs, type TMDataGridCellExportOptions, type TMDataGridCellMatrix, type TMDataGridCellNav, type TMDataGridCellPosition, type TMDataGridCellRange, type TMDataGridCellSelectionMode, type TMDataGridColumnCapabilities, type TMDataGridColumnEditOptions, type TMDataGridColumnFilterOptions, type TMDataGridColumnLayout, type TMDataGridColumnMenuItemsArgs, type TMDataGridColumnMenuItemsRenderer, type TMDataGridColumnMeta, type TMDataGridColumnRegion, type TMDataGridColumnType, type TMDataGridContextValue, type TMDataGridDataSlice, TMDataGridDateEditor, type TMDataGridDetailsArgs, type TMDataGridDetailsRenderer, type TMDataGridDropSide, TMDataGridEditActions, type TMDataGridEditActionsActions, type TMDataGridEditActionsControls, type TMDataGridEditActionsProps, type TMDataGridEditActionsSlotArgs, type TMDataGridEditActionsState, type TMDataGridEditApi, type TMDataGridEditChange, type TMDataGridEditCommitArgs, type TMDataGridEditCommitDraftsArgs, type TMDataGridEditField, type TMDataGridEditMode, type TMDataGridEditRowProjection, type TMDataGridEditState, type TMDataGridEditValueMap, type TMDataGridEditValueMapArgs, type TMDataGridEditingOptions, type TMDataGridEditorArgs, type TMDataGridEditorComponent, type TMDataGridExpandAllArgs, type TMDataGridExpandTarget, type TMDataGridFeatureFlags, type TMDataGridFeatures, type TMDataGridFieldValidate, type TMDataGridFilterControlArgs, type TMDataGridFilterControlComponent, type TMDataGridFilterOperator, TMDataGridFilterPills, type TMDataGridFilterPillsProps, type TMDataGridFilterValue, TMDataGridFilterValueInput, type TMDataGridFooterProps, type TMDataGridLabels, type TMDataGridLabelsOverride, TMDataGridMultiSelectEditor, TMDataGridNumberEditor, type TMDataGridOption, type TMDataGridOptionsArgs, type TMDataGridOptionsSource, type TMDataGridPaginationActions, type TMDataGridPaginationApi, type TMDataGridPaginationControls, type TMDataGridPaginationSlotArgs, type TMDataGridPaginationState, type TMDataGridPersistKey, type TMDataGridPersistence, type TMDataGridProps, type TMDataGridQuickSearchMode, type TMDataGridRangeBounds, type TMDataGridRowAddArgs, type TMDataGridRowClickModifiers, type TMDataGridRowContextMenuArgs, type TMDataGridRowContextMenuRenderer, type TMDataGridRowData, type TMDataGridRowDeleteArgs, type TMDataGridRowEditForm, type TMDataGridRowStyle, type TMDataGridRowValidators, type TMDataGridScrollAlign, type TMDataGridScrollToRowArgs, TMDataGridSearch, type TMDataGridSearchProps, TMDataGridSelectEditor, type TMDataGridSelectionMode, type TMDataGridSettingsSlice, type TMDataGridSize, type TMDataGridStorageMode, TMDataGridStringEditor, type TMDataGridTable, type TMDataGridTableMeta, type TMDataGridTableProps, type TMDataGridUiActions, type TMDataGridUiState, type TMDataGridUiStore, type UseTMDataGridOptions, aggregateColumn, areAllRowsExpanded, autosizeColumn, boundsCellCount, boundsEdges, buildCellMatrix, buildGridCellMatrix, clearedValueForType, createTMDataGridColumnHelper, downloadTextFile, emptyValueForOperator, exportGridToCsv, formatExportValue, formatFilterLabel, formatGroupValue, fuzzyGlobalFilterFn, getColumnCapabilities, getColumnDefaultOperator, getColumnFilterControl, getColumnLabel, getColumnRegion, getColumnType, getDefaultOperator, getDisplayedRows, getEditFieldName, getGridCapabilities, getGroupDataRows, getOperatorsForType, getSelectableRowIds, getStepTargetColumn, getTMDataGridPaginationApi, isColumnEditableForRow, isColumnReorderable, isControlColumn, isFilterActive, isGeneratedColumn, isPagingActive, isSameCell, isWithinBounds, keepGeneratedColumnsOutermost, measureColumnContentWidth, mergeLabels, moveColumn, moveColumnByStep, normalizeFieldValidate, openColumnFilter, operatorNeedsValue, operatorTakesArrayValue, operatorTakesRangeValue, optionsToComboboxData, readFeatureFlags, resolveCellMove, resolveColumnOptions, resolveExpandAll, resolveRangeBounds, resolveRowSelectionClick, tmDataGridFeatures, toClipboardText, toExcelCsv, useCellControlTabIndex, useTMDataGrid, useTMDataGridContext, writeClipboardText };
4141
+ export { type BuildCellMatrixArgs, type BuildExportDataArgs, type ColumnStepArgs, DATA_STATE_SLICES, DEFAULT_CELL_EXPORT_OPTIONS, DEFAULT_EXPORT_OPTIONS, DEFAULT_TMDATAGRID_SIZE, DETAILS_COLUMN_ID, DgAutocompleteFilter, DgDateRangeFilter, DgRangeSliderFilter, DgTriStateFilter, EDIT_COLUMN_ID, type ExportGridArgs, FILTER_OPERATOR_LABELS, GROUP_COLUMN_ID, type MoveColumnArgs, PERSIST_PAYLOAD_VERSION, ROW_NUMBER_COLUMN_ID, type ResolveCellMoveArgs, type ResolveRangeBoundsArgs, type ResolveRowSelectionClickArgs, type ResolvedRowSelection, SELECT_COLUMN_ID, SETTINGS_STATE_SLICES, SIZE_CONTROL_SIZE, SIZE_ROW_HEIGHT, TMDATAGRID_LABELS_EN, TMDATAGRID_LABELS_SV, TMDataGrid, type TMDataGridAddRowsOptions, type TMDataGridAddRowsResult, type TMDataGridAggregationName, type TMDataGridApi, TMDataGridBooleanEditor, type TMDataGridCapabilities, type TMDataGridCellCoords, type TMDataGridCellEventArgs, type TMDataGridCellExportOptions, type TMDataGridCellMatrix, type TMDataGridCellNav, type TMDataGridCellPosition, type TMDataGridCellRange, type TMDataGridCellSelectionMode, type TMDataGridClipboardTextOptions, type TMDataGridColumnCapabilities, type TMDataGridColumnEditOptions, type TMDataGridColumnFilter, type TMDataGridColumnFilterOptions, type TMDataGridColumnLayout, type TMDataGridColumnMenuItemsArgs, type TMDataGridColumnMenuItemsRenderer, type TMDataGridColumnMeta, type TMDataGridColumnRegion, type TMDataGridColumnSearchable, type TMDataGridColumnType, type TMDataGridColumnsPanelProps, type TMDataGridContextValue, type TMDataGridCsvFormatOptions, type TMDataGridDataSlice, TMDataGridDateEditor, type TMDataGridDetailsArgs, type TMDataGridDetailsRenderer, TMDataGridDraftActions, type TMDataGridDraftActionsActions, type TMDataGridDraftActionsControls, type TMDataGridDraftActionsProps, type TMDataGridDraftActionsSlotArgs, type TMDataGridDraftActionsState, type TMDataGridDropSide, type TMDataGridEditApi, type TMDataGridEditChange, type TMDataGridEditCommitArgs, type TMDataGridEditCommitDraftsArgs, type TMDataGridEditField, type TMDataGridEditMode, type TMDataGridEditRowProjection, type TMDataGridEditRowSnapshot, type TMDataGridEditState, type TMDataGridEditValueMap, type TMDataGridEditValueMapArgs, type TMDataGridEditingOptions, type TMDataGridEditorArgs, type TMDataGridEditorComponent, type TMDataGridExpandAllArgs, type TMDataGridExpandTarget, type TMDataGridExportApi, type TMDataGridExportColumns, type TMDataGridExportData, type TMDataGridExportFormat, type TMDataGridExportOptions, type TMDataGridExportPickerRequest, type TMDataGridExportRows, type TMDataGridExportSettings, type TMDataGridExportValueGetter, type TMDataGridExportWriteOptions, type TMDataGridFeatureFlags, type TMDataGridFeatures, type TMDataGridFieldValidate, type TMDataGridFilterControlArgs, type TMDataGridFilterControlComponent, type TMDataGridFilterControlLayout, type TMDataGridFilterOperator, type TMDataGridFilterPanelLayout, type TMDataGridFilterPanelProps, TMDataGridFilterPills, type TMDataGridFilterPillsProps, type TMDataGridFilterSidebarSide, type TMDataGridFilterSurface, type TMDataGridFilterValue, TMDataGridFilterValueInput, type TMDataGridFilterValueShape, type TMDataGridFiltersOptions, type TMDataGridFiltersSettings, type TMDataGridFooterProps, type TMDataGridJsonFormatOptions, type TMDataGridLabels, type TMDataGridLabelsOverride, type TMDataGridMenuColumnsProps, type TMDataGridMenuExportProps, type TMDataGridMenuProps, TMDataGridMultiSelectEditor, TMDataGridNumberEditor, type TMDataGridOption, type TMDataGridOptionsArgs, type TMDataGridOptionsSource, type TMDataGridPaginationActions, type TMDataGridPaginationApi, type TMDataGridPaginationControls, type TMDataGridPaginationSlotArgs, type TMDataGridPaginationState, type TMDataGridPersistKey, type TMDataGridPersistence, type TMDataGridProps, type TMDataGridQuickSearchMode, type TMDataGridRangeBounds, type TMDataGridRowAddArgs, type TMDataGridRowClickModifiers, type TMDataGridRowContextMenuArgs, type TMDataGridRowContextMenuRenderer, type TMDataGridRowData, type TMDataGridRowDeleteArgs, type TMDataGridRowEditForm, type TMDataGridRowStyle, type TMDataGridRowValidators, type TMDataGridSaveDraftsArgs, type TMDataGridSaveDraftsResult, type TMDataGridSaveOutcomes, type TMDataGridScrollAlign, type TMDataGridScrollToRowArgs, TMDataGridSearch, type TMDataGridSearchProps, TMDataGridSelectEditor, type TMDataGridSelectionMode, type TMDataGridSettingsSlice, type TMDataGridSize, type TMDataGridStorageMode, TMDataGridStringEditor, type TMDataGridTable, type TMDataGridTableMeta, type TMDataGridTableProps, type TMDataGridTableValidateArgs, type TMDataGridTableValidators, type TMDataGridToolbarProps, type TMDataGridTsvFormatOptions, type TMDataGridUiActions, type TMDataGridUiState, type TMDataGridUiStore, type UseTMDataGridOptions, activeColumnFilters, aggregateColumn, areAllRowsExpanded, autosizeColumn, boundsCellCount, boundsEdges, buildCellMatrix, buildExportData, buildGridCellMatrix, clearedValueForType, countSelectedExportRows, createTMDataGridColumnHelper, csvExcelFormat, csvFormat, downloadFile, downloadTextFile, emptyValueForOperator, exportGrid, exportGridToCsv, filterValueShape, formatExportValue, formatFilterLabel, formatGroupValue, fromCellExportOptions, fuzzyGlobalFilterFn, getColumnCapabilities, getColumnDefaultOperator, getColumnFilterControl, getColumnLabel, getColumnOperators, getColumnRegion, getColumnType, getDefaultOperator, getDisplayedRows, getEditFieldName, getExportableColumns, getGridCapabilities, getGroupDataRows, getOperatorsForType, getSelectableRowIds, getStepTargetColumn, getTMDataGridPaginationApi, guardFormula, isColumnEditableForRow, isColumnReorderable, isControlColumn, isFilterActive, isGeneratedColumn, isPagingActive, isSameCell, isWithinBounds, jsonFormat, keepGeneratedColumnsOutermost, measureColumnContentWidth, mergeLabels, moveColumn, moveColumnByStep, normalizeFieldValidate, openColumnFilter, operatorNeedsValue, operatorTakesArrayValue, operatorTakesRangeValue, optionsToComboboxData, readFeatureFlags, resolveCellMove, resolveColumnOptions, resolveExpandAll, resolveExportOptions, resolveRangeBounds, resolveRowSelectionClick, tmDataGridFeatures, toClipboardText, toExcelCsv, tsvFormat, useTMDataGrid, useTMDataGridContext, useTMDataGridExport, writeClipboardText, writeExportFile };