@jielga/tmdatagrid 2.0.0-beta.13 → 2.0.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -212
- package/dist/index.d.ts +967 -610
- package/dist/index.js +2944 -2327
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/anatomy.md +102 -0
- package/docs/cell-selection.md +154 -0
- package/docs/column-layout.md +204 -0
- package/docs/columns.md +262 -0
- package/docs/components.md +303 -0
- package/docs/editing.md +572 -0
- package/docs/editors.md +248 -0
- package/docs/export.md +326 -0
- package/docs/filtering.md +358 -0
- package/docs/getting-started.md +123 -0
- package/docs/grouping.md +165 -0
- package/docs/loading-and-empty.md +92 -0
- package/docs/localization.md +79 -0
- package/docs/menu.md +143 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +111 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +175 -0
- package/docs/quick-search.md +83 -0
- package/docs/row-details.md +111 -0
- package/docs/row-interaction.md +148 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +134 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +111 -0
- package/docs/server-query.md +246 -0
- package/docs/server-side.md +206 -0
- package/docs/sorting.md +101 -0
- package/docs/styling.md +126 -0
- package/docs/summary-row.md +76 -0
- package/docs/testing.md +309 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +21 -45
- package/skills/appearance/SKILL.md +31 -15
- package/skills/cell-selection/SKILL.md +44 -41
- package/skills/columns/SKILL.md +33 -32
- package/skills/data/SKILL.md +85 -15
- package/skills/editing/SKILL.md +6 -6
- package/skills/editing/references/common-mistakes.md +12 -12
- package/skills/filtering/SKILL.md +40 -18
- package/skills/getting-started/SKILL.md +5 -5
- package/skills/grouping/SKILL.md +11 -11
- package/skills/options/SKILL.md +5 -5
- package/skills/rows/SKILL.md +15 -15
- package/skills/server-side/SKILL.md +131 -7
- package/skills/testing/SKILL.md +4 -4
- package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +28 -20
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +5 -4
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +40 -15
- package/src/components/TMDataGridExportPicker.module.css +77 -0
- package/src/components/TMDataGridExportPicker.tsx +234 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPanel.tsx +22 -6
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +7 -5
- package/src/{tmdatagrid/components → components}/TMDataGridFilterSurface.tsx +8 -3
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +20 -7
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +16 -5
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderFilterRow.tsx +2 -4
- package/src/{tmdatagrid/components → components}/TMDataGridMenu.tsx +115 -16
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +2 -1
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +74 -55
- package/src/{tmdatagrid/components → components}/TMDataGridToolbar.module.css +5 -0
- package/src/{tmdatagrid/components → components}/TMDataGridToolbar.tsx +44 -8
- package/src/{tmdatagrid/components → components}/editors/editorShared.ts +2 -1
- package/src/{tmdatagrid/components → components}/icons.ts +1 -0
- package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/dom.ts +74 -0
- package/src/core/export.ts +840 -0
- package/src/{tmdatagrid/core → core}/filterControls.ts +10 -1
- package/src/{tmdatagrid/core → core}/labels.ts +40 -2
- package/src/{tmdatagrid/core → core}/labelsSv.ts +17 -1
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/{tmdatagrid/core → core}/summary.ts +20 -4
- package/src/{tmdatagrid/index.ts → index.ts} +43 -4
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +100 -45
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- /package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridDraftActions.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPanel.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterSurface.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridHeaderFilterRow.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/editors/TMDataGridNumberEditor.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/filters/controlLayout.ts +0 -0
- /package/src/{tmdatagrid/components → components}/filters/filterControlFor.ts +0 -0
- /package/src/{tmdatagrid/components → components}/sticky.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/useHideableColumns.ts +0 -0
- /package/src/{tmdatagrid/core → core}/capabilities.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
- /package/src/{tmdatagrid/core → core}/columnOptions.ts +0 -0
- /package/src/{tmdatagrid/core → core}/controlledState.ts +0 -0
- /package/src/{tmdatagrid/core → core}/controlledStateSync.ts +0 -0
- /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
- /package/src/{tmdatagrid/core → core}/editEngine.ts +0 -0
- /package/src/{tmdatagrid/core → core}/editorFocus.ts +0 -0
- /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
- /package/src/{tmdatagrid/core → core}/filterOperators.ts +0 -0
- /package/src/{tmdatagrid/core → core}/filterSurface.ts +0 -0
- /package/src/{tmdatagrid/core → core}/grouping.ts +0 -0
- /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/pageReset.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/resizePreview.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
- /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
- /package/src/{tmdatagrid/core → core}/useSettledTableState.ts +0 -0
package/docs/editors.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Editors and validation
|
|
2
|
+
|
|
3
|
+
Which control a cell opens when editing starts, what the value becomes on the
|
|
4
|
+
way in, and what prevents a bad one being committed. All three follow from the
|
|
5
|
+
column: `meta.type` picks the editor, and `meta.edit` holds the rest.
|
|
6
|
+
|
|
7
|
+
```demo
|
|
8
|
+
file: editing/EditorsAndValidation.tsx
|
|
9
|
+
hint: Type a single letter into String, or 5 into Number, to see validation reject it.
|
|
10
|
+
height: 440
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## The built-in editors
|
|
14
|
+
|
|
15
|
+
`meta.type` picks one, and `meta.options` feeds the select editors from the same
|
|
16
|
+
source the filter panel reads. Neither lives under `meta.edit`.
|
|
17
|
+
|
|
18
|
+
| `meta.type` | Editor | Writes |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| `string` (default) | Text input | `string` |
|
|
21
|
+
| `number` | Number input | `number`, or `null` while the cell is empty or the text is not yet a number |
|
|
22
|
+
| `boolean` | Checkbox | `boolean` |
|
|
23
|
+
| `date` | Native `<input type="date">` | A `Date`, or the `"YYYY-MM-DD"` string; `null` when cleared |
|
|
24
|
+
| `select` | Searchable select from `meta.options`. Commits on pick under `"cell"` | `string \| null` |
|
|
25
|
+
| `multiSelect` | Multi-select, same source | `string[]` |
|
|
26
|
+
|
|
27
|
+
**Writes** is the value the editor puts into the draft: what `meta.edit.mapValue` is handed, what `meta.edit.validate` checks, and what a commit carries in `value` and in `changes[].next`.
|
|
28
|
+
|
|
29
|
+
The number editor writes `null` rather than `NaN` while the text does not parse, so a half-typed number leaves the field empty instead of committing a number no rule can describe.
|
|
30
|
+
The date editor picks between its two types once, when it opens, from what the cell held: a `Date` cell keeps receiving `Date`s and a string cell keeps receiving `"YYYY-MM-DD"` strings, so clearing and retyping cannot flip the type.
|
|
31
|
+
|
|
32
|
+
Each is a named export (`TMDataGridStringEditor`, `TMDataGridNumberEditor`,
|
|
33
|
+
`TMDataGridBooleanEditor`, `TMDataGridDateEditor`, `TMDataGridSelectEditor`,
|
|
34
|
+
`TMDataGridMultiSelectEditor`), so a custom editor can wrap one instead of
|
|
35
|
+
starting from scratch.
|
|
36
|
+
|
|
37
|
+
## Writing your own
|
|
38
|
+
|
|
39
|
+
`meta.edit.editor` fills the same slot as the built-ins. It is a **component**,
|
|
40
|
+
rendered as JSX, so hooks may be used inside, and it receives the live TanStack
|
|
41
|
+
Form `field` API. Bind any control to it as you would inside a form:
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
const SalaryEditor: TMDataGridEditorComponent = ({ field, commit }) => (
|
|
45
|
+
<Slider
|
|
46
|
+
value={field.state.value}
|
|
47
|
+
onChange={field.handleChange}
|
|
48
|
+
onChangeEnd={() => void commit()}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
meta: { edit: { editor: SalaryEditor } }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Define editors at module scope.** An inline arrow function gets a new identity
|
|
56
|
+
on every render, which remounts the editor mid-edit and discards what was typed.
|
|
57
|
+
|
|
58
|
+
The field's validation message is shown by the host, in a tooltip on the
|
|
59
|
+
editor: open while the input is focused, and on hover. A custom editor gets the
|
|
60
|
+
same tooltip, so it renders no message of its own.
|
|
61
|
+
|
|
62
|
+
The built-in editors mark the input invalid and add no inline text, since the
|
|
63
|
+
message would be clipped by the width of the cell. A custom editor does the
|
|
64
|
+
same by binding a boolean to the control's `error` prop:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
const hasError = field.state.meta.errors.length > 0;
|
|
68
|
+
|
|
69
|
+
<Slider value={field.state.value} onChange={field.handleChange} error={hasError} />;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Mapping the value as it is typed
|
|
73
|
+
|
|
74
|
+
A column can rewrite every value on its way into the draft: uppercase a code,
|
|
75
|
+
strip spaces out of an IBAN, clamp a number into range. `meta.edit.mapValue`
|
|
76
|
+
runs on each write an editor makes, which is each keystroke for a text input and
|
|
77
|
+
each pick for a select.
|
|
78
|
+
|
|
79
|
+
```demo
|
|
80
|
+
file: editing/MappedInput.tsx
|
|
81
|
+
hint: Type into either column. Code uppercases, Reference keeps digits only.
|
|
82
|
+
height: 420
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
meta: {
|
|
87
|
+
edit: {
|
|
88
|
+
mapValue: ({ value }) =>
|
|
89
|
+
typeof value === "string" ? value.toUpperCase() : value,
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
What it returns is what the cell shows, what the validators check and what is
|
|
95
|
+
committed.
|
|
96
|
+
|
|
97
|
+
The map is applied inside the editor host, around the field every editor writes
|
|
98
|
+
through, so one declaration covers all six built-in editors, your own
|
|
99
|
+
`meta.edit.editor`, and the character that opened the editor when typing started
|
|
100
|
+
the edit.
|
|
101
|
+
|
|
102
|
+
Some writes are not mapped: the value the editor opens with, and the writes that go through the form rather than through an editor - `edit.clearCell()`, the Delete key, `edit.setCellValue()` and `edit.setRowValues()`.
|
|
103
|
+
An editor calling `field.setValue` instead of `field.handleChange` also bypasses the map.
|
|
104
|
+
`handleChange` is the mapped path.
|
|
105
|
+
|
|
106
|
+
The map receives the row and column as well, so it can depend on the record
|
|
107
|
+
being edited:
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
meta: {
|
|
111
|
+
edit: {
|
|
112
|
+
mapValue: ({ value, row }) =>
|
|
113
|
+
row.original.country === "SE" && typeof value === "string"
|
|
114
|
+
? value.replace(/ /g, "")
|
|
115
|
+
: value,
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`previous` is the value the field held before this write, which a mask needs in
|
|
121
|
+
order to tell an insertion from a deletion.
|
|
122
|
+
|
|
123
|
+
### Keeping the caret
|
|
124
|
+
|
|
125
|
+
A mapped value differs from the one the input holds, so React writes the new
|
|
126
|
+
value into the DOM node and the browser collapses the selection to the end of
|
|
127
|
+
the field.
|
|
128
|
+
|
|
129
|
+
The built-in string and number editors restore the caret to where it was typed,
|
|
130
|
+
shifted by however much the map changed the length, so a mask that inserts or
|
|
131
|
+
strips characters keeps the caret beside the same text.
|
|
132
|
+
|
|
133
|
+
A custom editor rendering its own input has the same problem, and solves it the
|
|
134
|
+
same way: record `selectionStart` as the value is handed over, and restore it in
|
|
135
|
+
a layout effect once the mapped value has rendered.
|
|
136
|
+
|
|
137
|
+
## Validation
|
|
138
|
+
|
|
139
|
+
The validators are TanStack Form's own: a Standard Schema (Zod, Valibot,
|
|
140
|
+
ArkType) or a plain function returning an error message or nothing.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
// Per column: field-level validators. A bare schema or function means { onChange: it }.
|
|
144
|
+
meta: { edit: { validate: z.string().min(2, "Too short") } }
|
|
145
|
+
|
|
146
|
+
// The same rule without a schema library:
|
|
147
|
+
meta: {
|
|
148
|
+
edit: {
|
|
149
|
+
validate: ({ value }: { value: unknown }) =>
|
|
150
|
+
typeof value === "string" && value.length < 2 ? "Too short" : undefined,
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Per row: form-level validators - cross-field rules live here.
|
|
155
|
+
useTMDataGrid({
|
|
156
|
+
editing: {
|
|
157
|
+
mode: "cell",
|
|
158
|
+
rowValidators: {
|
|
159
|
+
onSubmit: z.object({ salary: z.number().positive() })
|
|
160
|
+
.refine((r) => r.status !== "Terminated" || r.salary === 0, {
|
|
161
|
+
message: "A terminated employee has no salary",
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
A plain function is typed `TMDataGridValidator`, whose `value` is `never`, so annotate the parameter - `{ value: unknown }`, or the type the column's editor writes - rather than leaving it to be inferred.
|
|
169
|
+
|
|
170
|
+
Pathed issues land on the matching cells; pathless ones on the row, where the
|
|
171
|
+
message shows in the edit lane's tooltip - on the open row's ✓, and on the
|
|
172
|
+
parked row's marker. To show a pathless message somewhere of your own, read it
|
|
173
|
+
from `edit.getForm(rowId)?.state.errors`; `edit.store` carries the flag
|
|
174
|
+
(`hasRowError`) and the field messages (`errorMessages`), not the row text.
|
|
175
|
+
|
|
176
|
+
A commit blocked by validation keeps the editor open, invalid, with the message
|
|
177
|
+
in its tooltip. A rejected `editing.onCommit` keeps the draft too, with the
|
|
178
|
+
error on the row. Server-side field errors can be returned natively through
|
|
179
|
+
`editing.rowValidators.onSubmitAsync`'s `{ form, fields }` shape.
|
|
180
|
+
|
|
181
|
+
Cross-field rules need a mode that commits the whole row at once. Under
|
|
182
|
+
`"cell"` each cell commits alone, so a rule spanning two columns cannot be
|
|
183
|
+
satisfied by either one. Use `editing.rowValidators.onSubmit` with `"row"`. See
|
|
184
|
+
[Editing](/docs/editing#row-editing).
|
|
185
|
+
|
|
186
|
+
A rule about the whole collection, such as "no duplicates" or "shares sum to
|
|
187
|
+
100", is neither a field rule nor a row rule. It takes
|
|
188
|
+
`editing.tableValidators` - see [Cross-row rules](#cross-row-rules).
|
|
189
|
+
|
|
190
|
+
## Cross-row rules
|
|
191
|
+
|
|
192
|
+
`editing.tableValidators` holds the rules that need the other rows: no
|
|
193
|
+
duplicate keys, no overlapping ranges, allocations summing to a total. Its
|
|
194
|
+
validators receive the committing row and `rows`, the collection as it would
|
|
195
|
+
stand if the commit landed - every draft overlaid, entry rows appended,
|
|
196
|
+
deletion-marked rows removed:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
editing: {
|
|
200
|
+
mode: "cell",
|
|
201
|
+
draft: true,
|
|
202
|
+
tableValidators: {
|
|
203
|
+
onSubmit: ({ value, rowId, rows }) =>
|
|
204
|
+
rows.some((r) => r.rowId !== rowId && r.value.code === value.code)
|
|
205
|
+
? { fields: { code: "Codes must be unique" } }
|
|
206
|
+
: undefined,
|
|
207
|
+
},
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The result is the `rowValidators` vocabulary: nothing passes, a string is a
|
|
212
|
+
row-level message, and `{ form, fields }` lands pathed issues on the
|
|
213
|
+
committing row's cells. `onSubmit` runs first, and its failure stands without
|
|
214
|
+
`onSubmitAsync` running.
|
|
215
|
+
|
|
216
|
+
The rules run at every commit, after the row's own validators, and again for
|
|
217
|
+
every parked row during `saveDrafts` - a draft that a later edit has
|
|
218
|
+
invalidated fails there, keeps its markers, and the save resolves `false`.
|
|
219
|
+
Errors land on the committing row only; the row it clashes with is not
|
|
220
|
+
marked.
|
|
221
|
+
|
|
222
|
+
`rows` is unfiltered, so a rule sees the whole collection whatever the view
|
|
223
|
+
shows, and it never contains group rows.
|
|
224
|
+
|
|
225
|
+
```demo
|
|
226
|
+
file: editing/TableValidation.tsx
|
|
227
|
+
hint: Give two teams the same code, or push the shares past 100, and the commit is refused. Drafts count - a clash with a pending edit is caught too.
|
|
228
|
+
height: 380
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
A grid inside an outer form can put collection rules in the form's own field
|
|
232
|
+
validator instead. See [A query builder form](/docs/query-builder).
|
|
233
|
+
|
|
234
|
+
## Reference
|
|
235
|
+
|
|
236
|
+
| Name | Kind | Type | Default | What it does |
|
|
237
|
+
| --- | --- | --- | --- | --- |
|
|
238
|
+
| `meta.edit.editor` | Column meta | `TMDataGridEditorComponent` | By `meta.type` | Replaces the cell editor. |
|
|
239
|
+
| `meta.edit.validate` | Column meta | `TMDataGridFieldValidate` | – | Field-level validation. A bare schema or function means `onChange`. |
|
|
240
|
+
| `meta.edit.mapValue` | Column meta | `TMDataGridEditValueMap` | – | Maps each value an editor writes, before it reaches the draft. |
|
|
241
|
+
| `editing.rowValidators` | Option | `TMDataGridRowValidators` | – | Form-level validation, for cross-field rules. |
|
|
242
|
+
| `editing.tableValidators` | Option | `TMDataGridTableValidators` | – | Cross-row rules, handed the collection with every draft overlaid. See [Cross-row rules](#cross-row-rules). |
|
|
243
|
+
| `TMDataGridTableValidateArgs` | Export | type | – | What a table validator receives: `value`, `rowId`, `isNew`, `rows`. |
|
|
244
|
+
| `TMDataGridEditorArgs` | Export | type | – | What an editor component receives: `field`, `commit`, `cancel`, `row`, `column`. |
|
|
245
|
+
| `TMDataGridEditValueMapArgs` | Export | type | – | What `mapValue` receives: `value`, `previous`, `row`, `column`, `table`. |
|
|
246
|
+
| `TMDataGridStringEditor` · `NumberEditor` · `BooleanEditor` · `DateEditor` · `SelectEditor` · `MultiSelectEditor` | Exports | components | – | The six built-ins, for wrapping. |
|
|
247
|
+
| `normalizeFieldValidate` | Export | `(validate) => validators` | – | Turns a bare schema into TanStack Form's validator shape. |
|
|
248
|
+
| `getEditFieldName` | Export | `(column) => string` | – | The data path a column's edits write to. |
|
package/docs/export.md
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# Export
|
|
2
|
+
|
|
3
|
+
Downloads the grid as a file: every filtered and sorted row across every page, or the selected rows, in the format the grid is configured with.
|
|
4
|
+
`TMDataGrid.Menu.Export` and `TMDataGrid.Menu.ExportSelected` are the built-in entry points; `useTMDataGridExport` is the same export as click handlers for a control of your own.
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
<TMDataGrid.Toolbar>
|
|
8
|
+
<TMDataGrid.SummaryCount />
|
|
9
|
+
<TMDataGrid.Spacer />
|
|
10
|
+
<TMDataGrid.Menu>
|
|
11
|
+
<TMDataGrid.Menu.Export />
|
|
12
|
+
<TMDataGrid.Menu.ExportSelected />
|
|
13
|
+
<Menu.Divider />
|
|
14
|
+
<TMDataGrid.Menu.Columns />
|
|
15
|
+
</TMDataGrid.Menu>
|
|
16
|
+
</TMDataGrid.Toolbar>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```demo
|
|
20
|
+
file: data/Export.tsx
|
|
21
|
+
hint: Tick a few rows, then open the menu. The Excel CSV opens straight into columns.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## What is written
|
|
25
|
+
|
|
26
|
+
By default the columns are the visible data columns in render order, so a hidden column is not exported and a pinned one keeps its place.
|
|
27
|
+
`columns` on `exportOptions`, on the menu items and on the functions picks another set:
|
|
28
|
+
|
|
29
|
+
- `"visible"` - the data columns on screen. The default.
|
|
30
|
+
- `"all"` - every exportable column, hidden ones in the place they would take if shown.
|
|
31
|
+
- a list of column ids - those columns, in render order.
|
|
32
|
+
|
|
33
|
+
The generated lanes (checkbox, details, edit, row numbers) are never exported, whichever is asked for.
|
|
34
|
+
Set `meta.enableExport: false` to leave a column of your own out the same way:
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
columnHelper.display({
|
|
38
|
+
id: "actions",
|
|
39
|
+
cell: ActionsCell,
|
|
40
|
+
meta: { enableExport: false },
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The rows are every row after filtering and sorting, across every page.
|
|
45
|
+
On a grouped grid the records under every group are written, whether the group is open or not, and the group rows are not.
|
|
46
|
+
|
|
47
|
+
Each cell is written as its **value**, `row.getValue(column.id)`, not as what the cell renders.
|
|
48
|
+
A cell showing `32 000 kr` exports `32000`; a select column exports the option's `value`.
|
|
49
|
+
Set `meta.exportValue` to write something else:
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
columnHelper.accessor("status", {
|
|
53
|
+
meta: {
|
|
54
|
+
type: "select",
|
|
55
|
+
options: STATUS_OPTIONS,
|
|
56
|
+
exportValue: ({ value }) => STATUS_LABELS[value as EmployeeStatus],
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`exportValue` receives `{ value, row, column }` and returns the value the format writes.
|
|
62
|
+
Both meta fields also apply to Ctrl+C under [cell selection](/docs/cell-selection#copy-and-export).
|
|
63
|
+
|
|
64
|
+
## The exportOptions option
|
|
65
|
+
|
|
66
|
+
`exportOptions` on `useTMDataGrid` sets the format, the file name and whether the column labels go in as the first row:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const grid = useTMDataGrid({
|
|
70
|
+
data,
|
|
71
|
+
columns,
|
|
72
|
+
exportOptions: { format: csvFormat(), fileName: "employees" },
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| Field | Type | Default | Description |
|
|
77
|
+
| --- | --- | --- | --- |
|
|
78
|
+
| `format` | `TMDataGridExportFormat` | `csvExcelFormat()` | The file format. See [Formats](#formats). |
|
|
79
|
+
| `fileName` | `string` | `"export"` | The file name without extension; the format adds its own. |
|
|
80
|
+
| `includeHeaders` | `boolean` | `true` | Determines whether the column labels are written as the first row. |
|
|
81
|
+
| `columns` | `"visible" \| "all" \| Array<string>` | `"visible"` | Which columns are written. See [What is written](#what-is-written). |
|
|
82
|
+
|
|
83
|
+
The option is read field by field, so a literal is fine.
|
|
84
|
+
Every export of the grid reads it: the menu items, the hook, and the export item of the cell-range menu.
|
|
85
|
+
|
|
86
|
+
## Formats
|
|
87
|
+
|
|
88
|
+
A format is a `TMDataGridExportFormat`, and the package ships four factories:
|
|
89
|
+
|
|
90
|
+
| Factory | File | Writes |
|
|
91
|
+
| --- | --- | --- |
|
|
92
|
+
| `csvExcelFormat()` | `.csv` | A CSV Excel opens straight into columns: UTF-8 BOM, a `sep=;` first line, CRLF endings, `;` between fields, `,` as the decimal mark. |
|
|
93
|
+
| `csvFormat()` | `.csv` | CSV as RFC 4180 has it: `,` between fields, `.` as the decimal mark, CRLF, a UTF-8 BOM, no `sep=` line. |
|
|
94
|
+
| `tsvFormat()` | `.tsv` | Tab-separated text, the clipboard shape as a file. |
|
|
95
|
+
| `jsonFormat()` | `.json` | An array with one object per row, keyed by column label, values as the data holds them. |
|
|
96
|
+
|
|
97
|
+
Excel xlsx is a separate package, since it needs a spreadsheet library the grid should not carry: see [Excel export (xlsx)](/docs/xlsx).
|
|
98
|
+
|
|
99
|
+
By default the grid writes `csvExcelFormat()` with the Nordic conventions, because an Excel running a Swedish, Norwegian, Danish or Finnish locale reads `;` as its list separator and `,` as its decimal mark, and a file written the other way opens as one column of text.
|
|
100
|
+
To write for an English-locale Excel, set the separator and the decimal mark on the format:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
exportOptions: { format: csvExcelFormat({ separator: ",", decimalComma: false }) }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `sep=` line is Excel's alone; Google Sheets and Numbers show it as a first row.
|
|
107
|
+
Use `csvFormat()` for a file that goes there.
|
|
108
|
+
|
|
109
|
+
`csvExcelFormat`, `csvFormat` and `tsvFormat` write values through `formatExportValue`: numbers with the format's decimal mark, dates in the `sv-SE` form (`2026-07-31 14:05:00`, which Excel reads as a date), booleans as `true` / `false`, arrays joined with `, `, and any other object as JSON.
|
|
110
|
+
`jsonFormat` writes numbers as numbers, dates as ISO strings, and `undefined` as `null`.
|
|
111
|
+
|
|
112
|
+
| Option | Formats | Type | Default | Description |
|
|
113
|
+
| --- | --- | --- | --- | --- |
|
|
114
|
+
| `separator` | csvExcel, csv | `string` | `";"` for csvExcel, `","` for csv | The character between fields. |
|
|
115
|
+
| `decimalComma` | csvExcel, csv, tsv | `boolean` | `true` for csvExcel and tsv, `false` for csv | Determines whether numbers are written as `1,5` rather than `1.5`. |
|
|
116
|
+
| `escapeFormulas` | csvExcel, csv, tsv | `boolean` | `true` | Determines whether text a spreadsheet would run as a formula is prefixed. See [Formula guard](#formula-guard). |
|
|
117
|
+
| `space` | json | `number` | `2` | Indentation passed to `JSON.stringify`. |
|
|
118
|
+
|
|
119
|
+
### Formula guard
|
|
120
|
+
|
|
121
|
+
Excel and Google Sheets run a cell that starts with `=`, `+`, `-` or `@` as a formula, so text one user typed into the grid would run in another user's spreadsheet when the file is opened.
|
|
122
|
+
By default the text formats prefix such a value with an apostrophe, which every spreadsheet reads as "text follows" and shows.
|
|
123
|
+
Text that parses as a number (`-5`, `+4670123456`) is not prefixed; a phone number written with spaces (`+46 70 123 45 67`) is.
|
|
124
|
+
To write every value as it is, set `escapeFormulas: false` on the format:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
exportOptions: { format: csvExcelFormat({ escapeFormulas: false }) }
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`guardFormula(text)` is the rule as a function, for a format of your own.
|
|
131
|
+
|
|
132
|
+
## TMDataGrid.Menu.Export
|
|
133
|
+
|
|
134
|
+
A menu item that downloads every filtered and sorted row, all pages, in the grid's format.
|
|
135
|
+
It needs a Mantine `Menu` around it and reads the grid from context, so it works in `TMDataGrid.Menu` and in any Mantine menu rendered inside `TMDataGrid`.
|
|
136
|
+
Its props override `exportOptions` for this item alone, which is how one menu offers two formats:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<TMDataGrid.Menu>
|
|
140
|
+
<TMDataGrid.Menu.Export />
|
|
141
|
+
<TMDataGrid.Menu.Export
|
|
142
|
+
format={csvFormat()}
|
|
143
|
+
fileName="employees-plain"
|
|
144
|
+
label="Export all rows as plain CSV"
|
|
145
|
+
/>
|
|
146
|
+
</TMDataGrid.Menu>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Prop | Type | Default | Description |
|
|
150
|
+
| --- | --- | --- | --- |
|
|
151
|
+
| `format` | `TMDataGridExportFormat` | `exportOptions.format` | The file format for this item. |
|
|
152
|
+
| `fileName` | `string` | `exportOptions.fileName` | The file name for this item. |
|
|
153
|
+
| `includeHeaders` | `boolean` | `exportOptions.includeHeaders` | Determines whether this item writes the header row. |
|
|
154
|
+
| `columns` | `"visible" \| "all" \| Array<string> \| "custom"` | `exportOptions.columns` | Which columns the item writes. `"custom"` opens the column picker. |
|
|
155
|
+
| `label` | `ReactNode` | `labels.exportAll` | The item's text. |
|
|
156
|
+
|
|
157
|
+
### The column picker
|
|
158
|
+
|
|
159
|
+
`columns="custom"` opens a dialog instead of downloading, titled with the format ("Export as CSV"): every exportable column as a checkbox, the visible ones ticked and the hidden ones marked **Hidden**, and an Export button that downloads the ticked columns in render order.
|
|
160
|
+
The line under the title names the selected rows when the item is `ExportSelected`.
|
|
161
|
+
A select-all row heads the list with a count of the ticked columns, a search box appears once there are six columns, and the list scrolls inside the dialog past half the viewport.
|
|
162
|
+
Under a search, select all ticks the matches and leaves the rest as they are.
|
|
163
|
+
Cancel closes it with no download.
|
|
164
|
+
The dialog follows the grid's `size`: its width, title and controls step with the toolbar's.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
<TMDataGrid.Menu.Export columns="custom" label="Export all rows, choose columns" />
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The picker is rendered by the `TMDataGrid` root and driven by `ui.state.exportPicker`, which holds `{ rows, options }` while it is open and `null` otherwise.
|
|
171
|
+
`ui.actions.openExportPicker({ rows: "all", options })` opens it from a control of your own; `getExportableColumns(table)` is the list it shows.
|
|
172
|
+
|
|
173
|
+
## TMDataGrid.Menu.ExportSelected
|
|
174
|
+
|
|
175
|
+
A menu item that downloads the selected rows of the current view, in grid order, with the same props as `TMDataGrid.Menu.Export`.
|
|
176
|
+
By default its text carries the count (`Export 3 selected rows`); `label` replaces it.
|
|
177
|
+
It is disabled while nothing is selected.
|
|
178
|
+
It renders nothing when row selection is off (`selectionMode: "highlight"` or `enableRowSelection: false`).
|
|
179
|
+
|
|
180
|
+
A selected row the filters have since hidden is not written and not counted.
|
|
181
|
+
|
|
182
|
+
## useTMDataGridExport
|
|
183
|
+
|
|
184
|
+
The export as click handlers, for a button or an item of your own anywhere inside `TMDataGrid`:
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import { useTMDataGridExport } from "@jielga/tmdatagrid";
|
|
188
|
+
|
|
189
|
+
function ExportButtons() {
|
|
190
|
+
const { exportAll, exportSelected, selectedCount, canExportSelected } =
|
|
191
|
+
useTMDataGridExport();
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<>
|
|
195
|
+
<Button size="xs" onClick={() => void exportAll()}>
|
|
196
|
+
Export
|
|
197
|
+
</Button>
|
|
198
|
+
{canExportSelected && (
|
|
199
|
+
<Button size="xs" disabled={selectedCount === 0} onClick={() => void exportSelected()}>
|
|
200
|
+
Export {selectedCount} selected
|
|
201
|
+
</Button>
|
|
202
|
+
)}
|
|
203
|
+
</>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
It takes a `TMDataGridExportOptions` argument, folded over the grid's `exportOptions` for this caller.
|
|
209
|
+
`exportAll` and `exportSelected` take one more, folded over both for that call, which is how a control passes a chosen set of columns.
|
|
210
|
+
|
|
211
|
+
| Field | Type | Description |
|
|
212
|
+
| --- | --- | --- |
|
|
213
|
+
| `exportAll` | `(overrides?) => Promise<void>` | Downloads every filtered and sorted row, all pages. |
|
|
214
|
+
| `exportSelected` | `(overrides?) => Promise<void>` | Downloads the selected rows of the current view. Resolves without a download when none is selected. |
|
|
215
|
+
| `selectedCount` | `number` | How many rows `exportSelected` would write. Subscribes to the selection. |
|
|
216
|
+
| `canExportSelected` | `boolean` | `true` while row selection is on. |
|
|
217
|
+
|
|
218
|
+
## Exporting from outside the grid
|
|
219
|
+
|
|
220
|
+
`exportGrid` is the same export for code that holds the table and nothing else:
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { exportGrid, jsonFormat } from "@jielga/tmdatagrid";
|
|
224
|
+
|
|
225
|
+
await exportGrid({ table: grid.table, rows: "selected", options: { format: jsonFormat() } });
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`rows` is `"all"` (the default), `"selected"`, or an array of TanStack rows of your own; `options.columns` picks the columns.
|
|
229
|
+
`buildExportData({ table, rows, columns })` is the step before the file: the columns, their labels and the raw values as a `TMDataGridExportData`, for a format or a post-processing step of your own.
|
|
230
|
+
`writeExportFile(data, settings)` writes and downloads it.
|
|
231
|
+
|
|
232
|
+
## Writing your own format
|
|
233
|
+
|
|
234
|
+
A format is an object with an id, a file extension, a MIME type and a `write` function.
|
|
235
|
+
`write` receives the `TMDataGridExportData` and `{ includeHeaders }`, and returns the file as a string or a `Blob`, or a promise of either:
|
|
236
|
+
|
|
237
|
+
```tsx
|
|
238
|
+
import type { TMDataGridExportFormat } from "@jielga/tmdatagrid";
|
|
239
|
+
|
|
240
|
+
export function markdownFormat(): TMDataGridExportFormat {
|
|
241
|
+
return {
|
|
242
|
+
id: "markdown",
|
|
243
|
+
extension: "md",
|
|
244
|
+
mimeType: "text/markdown",
|
|
245
|
+
write: ({ headers, rows }, { includeHeaders }) => {
|
|
246
|
+
const line = (cells: Array<unknown>) => `| ${cells.map(String).join(" | ")} |`;
|
|
247
|
+
const head = includeHeaders
|
|
248
|
+
? [line(headers), line(headers.map(() => "---"))]
|
|
249
|
+
: [];
|
|
250
|
+
return [...head, ...rows.map(line)].join("\n");
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Set `decimalComma` on the format when it writes text with a decimal mark, so Ctrl+C writes the same mark.
|
|
257
|
+
`formatExportValue(value, { decimalComma })` is the grid's own text rule, for a format that wants it.
|
|
258
|
+
|
|
259
|
+
## Copy and the cell-range menu
|
|
260
|
+
|
|
261
|
+
Under `cellSelection: "range"`, Ctrl+C and the **Export cells** item of the right-click menu write the selected rectangle through the same `exportOptions`, column meta and format.
|
|
262
|
+
See [Copy and export](/docs/cell-selection#copy-and-export).
|
|
263
|
+
|
|
264
|
+
## Labels
|
|
265
|
+
|
|
266
|
+
| Label | Default | Used by |
|
|
267
|
+
| --- | --- | --- |
|
|
268
|
+
| `exportAll` | `"Export all rows"` | `TMDataGrid.Menu.Export` |
|
|
269
|
+
| `exportSelected` | `(count) => "Export 3 selected rows"` | `TMDataGrid.Menu.ExportSelected` |
|
|
270
|
+
| `exportCells` | `"Export cells"` | The cell-range menu |
|
|
271
|
+
| `exportPickerTitle` | `` (format) => `Export as ${format}` `` | The column picker; `format` is the extension in upper case |
|
|
272
|
+
| `exportPickerHint` | `(selected) => "Select the columns to export"`, or `… for the ${selected} selected rows` | The line under the picker's title |
|
|
273
|
+
| `exportPickerConfirm` | `"Export"` | The column picker |
|
|
274
|
+
| `exportPickerCancel` | `"Cancel"` | The column picker |
|
|
275
|
+
| `exportPickerSelectAll` | `"Select all"` | The column picker |
|
|
276
|
+
| `exportPickerCount` | `` (checked, total) => `${checked} of ${total}` `` | The column picker |
|
|
277
|
+
| `exportPickerHidden` | `"Hidden"` | The column picker, on a column the grid hides |
|
|
278
|
+
|
|
279
|
+
See [Localization](/docs/localization).
|
|
280
|
+
|
|
281
|
+
## Testing
|
|
282
|
+
|
|
283
|
+
`TMDataGrid.Menu.Export` is `data-dg-part="menu-export"` and `TMDataGrid.Menu.ExportSelected` is `data-dg-part="menu-export-selected"`.
|
|
284
|
+
The column picker is `export-picker`, its checkboxes `export-column` with `data-column-id`, its select-all row `export-column-all` with the count `export-picker-count`, its search box `export-picker-search`, the line under the title `export-picker-hint`, and its buttons `export-picker-confirm` and `export-picker-cancel`.
|
|
285
|
+
The search box and the picker share `columnsSearchPlaceholder` and `columnsNoMatch` with the column chooser.
|
|
286
|
+
A download is an anchor with an object URL, clicked; a jsdom test stubs `URL.createObjectURL` and `HTMLAnchorElement.prototype.click` to read the file back.
|
|
287
|
+
See [Testing](/docs/testing).
|
|
288
|
+
|
|
289
|
+
## Deprecated names
|
|
290
|
+
|
|
291
|
+
The names below still work and go in the next beta.
|
|
292
|
+
|
|
293
|
+
| Deprecated | Use instead |
|
|
294
|
+
| --- | --- |
|
|
295
|
+
| `cellExport` on `TMDataGrid.Table` | `exportOptions` on `useTMDataGrid`; `separator` and `decimalComma` become `csvExcelFormat({ separator, decimalComma })` |
|
|
296
|
+
| `exportGridToCsv({ table, options })` | `exportGrid({ table, options })` |
|
|
297
|
+
| `TMDataGridCellExportOptions` · `DEFAULT_CELL_EXPORT_OPTIONS` | `TMDataGridExportOptions` · `DEFAULT_EXPORT_OPTIONS` |
|
|
298
|
+
| `buildCellMatrix` · `buildGridCellMatrix` · `TMDataGridCellMatrix` | `buildExportData` · `TMDataGridExportData` |
|
|
299
|
+
| `toExcelCsv(matrix, { separator })` | `csvExcelFormat({ separator }).write(data, options)` |
|
|
300
|
+
| `downloadTextFile` | `downloadFile` |
|
|
301
|
+
| `labels.exportCsv` | `labels.exportCells` |
|
|
302
|
+
|
|
303
|
+
## Reference
|
|
304
|
+
|
|
305
|
+
| Name | Kind | Type | Default | What it does |
|
|
306
|
+
| --- | --- | --- | --- | --- |
|
|
307
|
+
| `exportOptions` | Option | `TMDataGridExportOptions` | `DEFAULT_EXPORT_OPTIONS` | Format, file name and header row for every export of the grid. |
|
|
308
|
+
| `meta.enableExport` | Column meta | `boolean` | `true` | `false` leaves the column out of every export and of Ctrl+C. |
|
|
309
|
+
| `meta.exportValue` | Column meta | `({ value, row, column }) => unknown` | – | The value written in place of `row.getValue`. |
|
|
310
|
+
| `TMDataGrid.Menu.Export` | Component | `TMDataGridMenuExportProps` | – | Menu item: every filtered row. `columns="custom"` opens the picker. |
|
|
311
|
+
| `TMDataGrid.Menu.ExportSelected` | Component | `TMDataGridMenuExportProps` | – | Menu item: the selected rows. Renders nothing when row selection is off. |
|
|
312
|
+
| `ui.state.exportPicker` | UI state | `{ rows, options } \| null` | `null` | The column picker while open. |
|
|
313
|
+
| `ui.actions.openExportPicker` · `closeExportPicker` | UI actions | – | – | Open the picker from your own code. |
|
|
314
|
+
| `getExportableColumns` | Function | `(table) => Array<Column>` | – | Every column an export could take, hidden ones included. |
|
|
315
|
+
| `useTMDataGridExport` | Hook | `(overrides?) => TMDataGridExportApi` | – | `exportAll`, `exportSelected`, `selectedCount`, `canExportSelected`. |
|
|
316
|
+
| `exportGrid` | Function | `({ table, rows?, options? }) => Promise<void>` | – | Downloads the grid from outside a component. |
|
|
317
|
+
| `buildExportData` | Function | `({ table, rows?, columns?, bounds? }) => TMDataGridExportData` | – | The columns, labels and values a format writes. |
|
|
318
|
+
| `writeExportFile` | Function | `(data, settings) => Promise<void>` | – | Writes export data in a format and downloads it. |
|
|
319
|
+
| `csvExcelFormat` · `csvFormat` · `tsvFormat` · `jsonFormat` | Functions | `(options?) => TMDataGridExportFormat` | – | The built-in formats. |
|
|
320
|
+
| `guardFormula` · `formatExportValue` | Functions | – | – | The formula guard and the text rule, for a format of your own. |
|
|
321
|
+
| `resolveExportOptions` | Function | `(...overrides) => TMDataGridExportSettings` | – | The defaults with overrides folded over, `undefined` fields skipped. |
|
|
322
|
+
| `countSelectedExportRows` | Function | `(table) => number` | – | How many rows `"selected"` would write. |
|
|
323
|
+
| `downloadFile` | Function | `({ fileName, content, mimeType }) => void` | – | Downloads a string or a `Blob`. |
|
|
324
|
+
| `DEFAULT_EXPORT_OPTIONS` | Constant | `TMDataGridExportSettings` | – | `csvExcelFormat()`, `"export"`, `true`. |
|
|
325
|
+
| `TMDataGridExportFormat` · `TMDataGridExportData` · `TMDataGridExportOptions` · `TMDataGridExportSettings` · `TMDataGridExportRows` · `TMDataGridExportApi` | Types | – | – | The export types. |
|
|
326
|
+
| `data-dg-part` | Data attribute | `menu-export`, `menu-export-selected` | – | On the menu items. |
|