@jielga/tmdatagrid 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -245,7 +245,9 @@ The grid picks one from the column's `meta.type`, and `meta.edit.editor` replace
245
245
  | `TMDataGridSelectEditor` | `Select`, committing on pick in `"cell"` mode | `"select"` |
246
246
  | `TMDataGridMultiSelectEditor` | `MultiSelect`, committing on Enter or blur | `"multiSelect"` |
247
247
 
248
- Every editor takes the same argument object, `TMDataGridEditorArgs`, so a custom editor can wrap a built-in rather than replace it:
248
+ Each built-in editor also takes `inputProps`, passed to its Mantine control. See [Extending a built-in editor](/docs/editors#extending-a-built-in-editor).
249
+
250
+ Every editor takes the same argument object, `TMDataGridEditorArgs`:
249
251
 
250
252
  | Field | Type | What it is |
251
253
  | --- | --- | --- |
package/docs/editors.md CHANGED
@@ -29,10 +29,98 @@ source the filter panel reads. Neither lives under `meta.edit`.
29
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
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
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.
32
+ ## Extending a built-in editor
33
+
34
+ Each built-in editor is a named export that takes `TMDataGridEditorArgs` and `inputProps`.
35
+ To change the Mantine control a built-in renders, pass `args` through whole and add props with `inputProps`:
36
+
37
+ ```tsx
38
+ import { IconBarcode } from "@tabler/icons-react";
39
+ import {
40
+ TMDataGridStringEditor,
41
+ type TMDataGridEditorComponent,
42
+ } from "@jielga/tmdatagrid";
43
+
44
+ const SkuEditor: TMDataGridEditorComponent = (args) => (
45
+ <TMDataGridStringEditor
46
+ {...args}
47
+ inputProps={{ leftSection: <IconBarcode size={14} /> }}
48
+ />
49
+ );
50
+
51
+ columnHelper.accessor("sku", {
52
+ header: "SKU",
53
+ meta: { edit: { editor: SkuEditor } },
54
+ });
55
+ ```
56
+
57
+ ```demo
58
+ file: editing/ExtendedEditors.tsx
59
+ hint: Double-click a cell. SKU has an icon, Price a unit and no negative numbers, Category a dropdown shadow and its own "nothing found" text.
60
+ height: 300
61
+ ```
62
+
63
+ Define the editor at module scope, as for [your own editor](#writing-your-own).
64
+ Spread `args` into the built-in with `{...args}`: its props type requires every field of `TMDataGridEditorArgs`.
65
+ Do not spread or rebuild `field` itself, because it is a live TanStack Form `FieldApi` and a copy loses the binding its methods rely on.
66
+
67
+ `inputProps` takes the props of the editor's Mantine control and `data-*` attributes, except the props the grid sets itself:
68
+
69
+ | Editor | Mantine control | `inputProps` type | Set by the grid |
70
+ | --- | --- | --- | --- |
71
+ | `TMDataGridStringEditor` | `TextInput` | `TMDataGridStringEditorProps["inputProps"]` | `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label` |
72
+ | `TMDataGridNumberEditor` | `NumberInput` | `TMDataGridNumberEditorProps["inputProps"]` | `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label` |
73
+ | `TMDataGridBooleanEditor` | `Checkbox` | `TMDataGridBooleanEditorProps["inputProps"]` | `checked`, `defaultChecked`, `onChange`, `error`, `size`, `aria-label` |
74
+ | `TMDataGridDateEditor` | `TextInput` | `TMDataGridDateEditorProps["inputProps"]` | `type`, `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label` |
75
+ | `TMDataGridSelectEditor` | `Select` | `TMDataGridSelectEditorProps["inputProps"]` | `data`, `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label`, `comboboxProps.withinPortal` |
76
+ | `TMDataGridMultiSelectEditor` | `MultiSelect` | `TMDataGridMultiSelectEditorProps["inputProps"]` | `data`, `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label`, `comboboxProps.withinPortal` |
77
+
78
+ The props the grid sets are left out of each type, so passing one is a type error.
79
+ `data-dg-part` is set after `inputProps`, so the input keeps `data-dg-part="editor-input"`.
80
+
81
+ - `onFocus` and `onBlur` run after the grid's own handlers.
82
+ The string and number editors select the value on focus, and every editor calls `field.handleBlur()` on blur, which marks the field as touched and runs its `onBlur` validators.
83
+ - `onBlur` runs when focus leaves the editor, for example on a click outside it.
84
+ It does not run when Enter, Tab or Escape closes the editor, or when a pick in the select editor commits under `"cell"`, because the editor closes before the focus moves.
85
+ To run code when an edit ends, use `editing.onCommit`, or `meta.edit.mapCommitValue` to change the committed value.
86
+ - `ref` receives the control's input element; the grid keeps its own ref on it too.
87
+ - `comboboxProps` on the select editors is merged with the grid's, and `withinPortal` is always `false`, because an option picked from a portal is a click outside the cell.
88
+ - The defaults the grid sets on the control can be overridden: `w="100%"` on every editor except the checkbox, `hideControls` on the number editor, and `searchable` on the select editors.
89
+ - The select editors read their options from `meta.options` only, so `data` is not accepted.
90
+ - To change the value as it is typed, use [`meta.edit.mapValue`](#mapping-the-value-as-it-is-typed); `onChange` is the grid's.
91
+
92
+ Important: do not stop the propagation of Enter, Tab or Escape in an `onKeyDown`, as the grid handles these keys on an ancestor to commit, move and cancel.
93
+ Props that add text around the control, such as `label` and `description`, make the editor taller than the cell, and `aria-labelledby` replaces the grid's translated accessible name.
94
+
95
+ To place content beside the control instead of inside it, render the built-in inside your own layout:
96
+
97
+ ```tsx
98
+ import { Group, Text } from "@mantine/core";
99
+ import {
100
+ TMDataGridNumberEditor,
101
+ TMDataGridSelectEditor,
102
+ TMDataGridStringEditor,
103
+ type TMDataGridEditorComponent,
104
+ } from "@jielga/tmdatagrid";
105
+
106
+ // Content beside the input.
107
+ const SalaryEditor: TMDataGridEditorComponent = (args) => (
108
+ <Group gap={4} wrap="nowrap" w="100%">
109
+ <TMDataGridNumberEditor {...args} />
110
+ <Text size="xs" c="dimmed">
111
+ per month
112
+ </Text>
113
+ </Group>
114
+ );
115
+
116
+ // A different built-in per row.
117
+ const DepartmentEditor: TMDataGridEditorComponent = (args) =>
118
+ args.row.original.status === "Terminated" ? (
119
+ <TMDataGridStringEditor {...args} />
120
+ ) : (
121
+ <TMDataGridSelectEditor {...args} />
122
+ );
123
+ ```
36
124
 
37
125
  ## Writing your own
38
126
 
@@ -273,9 +361,11 @@ validator instead. See [A query builder form](/docs/query-builder).
273
361
  | `editing.rowValidators` | Option | `TMDataGridRowValidators` | – | Form-level validation, for cross-field rules. |
274
362
  | `editing.tableValidators` | Option | `TMDataGridTableValidators` | – | Cross-row rules, handed the collection with every draft overlaid. See [Cross-row rules](#cross-row-rules). |
275
363
  | `TMDataGridTableValidateArgs` | Export | type | – | What a table validator receives: `value`, `rowId`, `isNew`, `rows`. |
276
- | `TMDataGridEditorArgs` | Export | type | – | What an editor component receives: `field`, `commit`, `cancel`, `row`, `column`. |
364
+ | `TMDataGridEditorArgs` | Export | type | – | What an editor component receives: `field`, `form`, `cell`, `row`, `column`, `table`, `commit`, `cancel`, `size`, `seedText`. See [Editors](/docs/components#editors). |
277
365
  | `TMDataGridEditValueMapArgs` | Export | type | – | What `mapValue` receives: `value`, `previous`, `row`, `column`, `table`. |
278
366
  | `TMDataGridEditCommitMapArgs` | Export | type | – | What `mapCommitValue` receives: `value`, `previous`, `row`, `column`, `table`. |
279
- | `TMDataGridStringEditor` · `NumberEditor` · `BooleanEditor` · `DateEditor` · `SelectEditor` · `MultiSelectEditor` | Exports | components | – | The six built-ins, for wrapping. |
367
+ | `TMDataGridStringEditor` · `NumberEditor` · `BooleanEditor` · `DateEditor` · `SelectEditor` · `MultiSelectEditor` | Exports | components | – | The six built-in editors. See [Extending a built-in editor](#extending-a-built-in-editor). |
368
+ | `inputProps` | Built-in editor prop | The Mantine control's props and `data-*` attributes, without the props the grid sets | – | Props passed to the Mantine control of a built-in editor. |
369
+ | `TMDataGridStringEditorProps` · `NumberEditorProps` · `BooleanEditorProps` · `DateEditorProps` · `SelectEditorProps` · `MultiSelectEditorProps` | Exports | types | – | The props of each built-in editor: `TMDataGridEditorArgs` and `inputProps`. |
280
370
  | `normalizeFieldValidate` | Export | `(validate) => validators` | – | Turns a bare schema into TanStack Form's validator shape. |
281
371
  | `getEditFieldName` | Export | `(column) => string` | – | The data path a column's edits write to. |
package/docs/testing.md CHANGED
@@ -185,6 +185,7 @@ None of them carries `data-column-id`; scope through the row.
185
185
  A column declaring `meta.filter.control` or `meta.edit.editor` renders your component
186
186
  in that slot, so `filter-value` and `editor-input` cover the built-ins only.
187
187
  `filter-row` and `editor` still apply; scope your own queries through them.
188
+ A built-in editor extended through `inputProps` keeps `editor-input`.
188
189
 
189
190
  `editor-input` is also where the grid puts the caret when an editor opens. An
190
191
  editor that does not publish it is focused on the first focusable element inside
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jielga/tmdatagrid",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "A React data grid built on TanStack Table v9 and Mantine - always virtualized, with resizable, reorderable, sortable, filterable, hideable and pinnable columns.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.5.0'
21
+ library_version: '2.6.0'
22
22
  sources:
23
23
  - 'Jielga/react:packages/tmdatagrid/docs/styling.md'
24
24
  - 'Jielga/react:packages/tmdatagrid/docs/toolbar.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.5.0'
17
+ library_version: '2.6.0'
18
18
  sources:
19
19
  - 'Jielga/react:packages/tmdatagrid/docs/cell-selection.md'
20
20
  - 'Jielga/react:packages/tmdatagrid/src/core/cellNavigation.ts'
@@ -16,7 +16,7 @@ description: >
16
16
  metadata:
17
17
  type: core
18
18
  library: '@jielga/tmdatagrid'
19
- library_version: '2.5.0'
19
+ library_version: '2.6.0'
20
20
  sources:
21
21
  - 'Jielga/react:packages/tmdatagrid/docs/columns.md'
22
22
  - 'Jielga/react:packages/tmdatagrid/docs/column-layout.md'
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.5.0'
21
+ library_version: '2.6.0'
22
22
  sources:
23
23
  - 'Jielga/react:packages/tmdatagrid/docs/pagination.md'
24
24
  - 'Jielga/react:packages/tmdatagrid/docs/scrolling.md'
@@ -5,20 +5,20 @@ description: >
5
5
  (mode: cell, cellConfirm, row; draft), the required getRowId, editing.onCommit
6
6
  and editing.onSaveDrafts, why the grid never mutates data, gating with
7
7
  editing.columns, meta.edit.enabled and meta.edit.field, the built-in editors
8
- picked by meta.type, custom editors via meta.edit.editor, value mapping with
9
- mapValue and mapCommitValue, validation at every level - meta.edit.validate,
10
- cross-field editing.rowValidators, cross-row editing.tableValidators over the
11
- draft-overlaid collection - adding and deleting rows (edit.addRow,
12
- newRowDefaults, onRowAdd, onRowDelete), the edit lane, TMDataGrid.DraftActions
13
- and renderActions, and the edit engine (begin, commit, commitAll, saveDrafts,
14
- addRows, setCellValue, setRowValues, getForm, store). Load when making a grid
15
- editable, choosing an edit mode, wiring a save, writing a cell editor,
16
- validating an edit, writing cells from a toolbar action or bulk fill, or when
17
- cells will not open.
8
+ (meta.type, inputProps), custom editors via meta.edit.editor, value mapping
9
+ with mapValue and mapCommitValue, validation at every level -
10
+ meta.edit.validate, cross-field editing.rowValidators, cross-row
11
+ editing.tableValidators over the draft-overlaid collection - adding and
12
+ deleting rows (edit.addRow, newRowDefaults, onRowAdd, onRowDelete), the edit
13
+ lane, TMDataGrid.DraftActions and renderActions, and the edit engine (begin,
14
+ commit, commitAll, saveDrafts, addRows, setCellValue, setRowValues, getForm,
15
+ store). Load when making a grid editable, choosing an edit mode, wiring a
16
+ save, writing a cell editor, validating an edit, writing cells from a toolbar
17
+ action or bulk fill, or when cells will not open.
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.5.0'
21
+ library_version: '2.6.0'
22
22
  sources:
23
23
  - 'Jielga/react:packages/tmdatagrid/docs/editing.md'
24
24
  - 'Jielga/react:packages/tmdatagrid/docs/draft-store.md'
@@ -207,11 +207,9 @@ columnHelper.accessor("salary", {
207
207
 
208
208
  ## Editors and validation
209
209
 
210
- `meta.type` picks the editor - `"string"` (the default), `"number"`,
211
- `"boolean"`, `"date"`, `"select"` and `"multiSelect"` - and `meta.options` feeds
212
- the two select editors from the same declaration the filter panel reads. Each
213
- one, with the value it writes into the draft and the export that wraps it, is in
214
- [references/editors-and-validation.md](references/editors-and-validation.md#the-built-in-editors).
210
+ `meta.type` picks the editor - `"string"` (the default), `"number"`, `"boolean"`, `"date"`, `"select"` and `"multiSelect"` - and `meta.options` feeds the two select editors from the same declaration the filter panel reads.
211
+ Each one, with the value it writes into the draft and its export, is in [references/editors-and-validation.md](references/editors-and-validation.md#the-built-in-editors).
212
+ To add a `leftSection`, a unit or a wider dropdown, do not copy a built-in: render it from `meta.edit.editor` with `inputProps` ([Extending a built-in](references/editors-and-validation.md#extending-a-built-in)).
215
213
 
216
214
  `meta.edit.editor` replaces one, `meta.edit.validate` guards the field, and
217
215
  `editing.rowValidators` carries cross-field rules. The validators are TanStack
@@ -487,7 +485,7 @@ are in [references/common-mistakes.md](references/common-mistakes.md).
487
485
  ## References
488
486
 
489
487
  - [Editors and validation](references/editors-and-validation.md) - the editor
490
- API, wrapping a built-in, what `mapValue` leaves alone, field, row and
488
+ API, extending a built-in with `inputProps`, what `mapValue` leaves alone, field, row and
491
489
  cross-row validators, derived columns with a table-wide rule, server-side
492
490
  errors.
493
491
  - [Editing API](references/editing-api.md) - every option, callback, column meta
@@ -124,7 +124,8 @@ type TMDataGridEditState = {
124
124
  | `hasPendingEdits` | Export | `(state) => boolean` - unsaved work: an open row with a changed value, any entry row, the draft store, or a save in flight. `useSelector(grid.edit.store, hasPendingEdits)` for a navigation blocker; do not use `openRowIds.length`, which also counts committed rows and rows that are only open. |
125
125
  | `getEditFieldName` | Export | `(column) => string` - the data path a column's edits write to. |
126
126
  | `normalizeFieldValidate` | Export | `(validate) => validators` - a bare schema into Form's shape. |
127
- | `TMDataGridStringEditor` … `TMDataGridMultiSelectEditor` | Exports | The six built-in editors, for wrapping. |
127
+ | `TMDataGridStringEditor` … `TMDataGridMultiSelectEditor` | Exports | The six built-in editors, for extending with `inputProps` or wrapping. |
128
+ | `TMDataGridStringEditorProps` · `TMDataGridNumberEditorProps` · `TMDataGridBooleanEditorProps` · `TMDataGridDateEditorProps` · `TMDataGridSelectEditorProps` · `TMDataGridMultiSelectEditorProps` | Exports | The props of each built-in editor: `TMDataGridEditorArgs` and `inputProps`. |
128
129
 
129
130
  Types: `TMDataGridEditMode`, `TMDataGridEditApi`, `TMDataGridEditState`,
130
131
  `TMDataGridEditCommitArgs`, `TMDataGridSaveDraftsArgs`,
@@ -94,11 +94,86 @@ columnHelper.accessor("salary", {
94
94
  });
95
95
  ```
96
96
 
97
- ## Wrapping a built-in
97
+ ## Extending a built-in
98
98
 
99
- The built-ins take `TMDataGridEditorArgs` as their props, so a custom editor can
100
- pass the whole object through and render around it instead of starting from
101
- scratch.
99
+ The built-ins take `TMDataGridEditorArgs` and `inputProps` as their props. To
100
+ change the Mantine control a built-in renders, render it from a
101
+ `meta.edit.editor`, pass `args` through whole, and add props with `inputProps`.
102
+ Extend a built-in rather than copying its source: keeping the caret in place
103
+ while `mapValue` rewrites the value, select-all on focus, the invalid border,
104
+ the translated accessible name and `data-dg-part="editor-input"` all come with
105
+ it. The props type requires every field of `TMDataGridEditorArgs`, so spread
106
+ `{...args}`; never spread or rebuild `field` itself.
107
+
108
+ ```tsx
109
+ import { Text } from "@mantine/core";
110
+ import { IconBarcode } from "@tabler/icons-react";
111
+ import {
112
+ TMDataGridNumberEditor,
113
+ TMDataGridSelectEditor,
114
+ TMDataGridStringEditor,
115
+ type TMDataGridEditorComponent,
116
+ } from "@jielga/tmdatagrid";
117
+
118
+ // Module scope. A new identity per render remounts the editor mid-edit.
119
+ const SkuEditor: TMDataGridEditorComponent = (args) => (
120
+ <TMDataGridStringEditor
121
+ {...args}
122
+ inputProps={{ leftSection: <IconBarcode size={14} /> }}
123
+ />
124
+ );
125
+
126
+ const PriceEditor: TMDataGridEditorComponent = (args) => (
127
+ <TMDataGridNumberEditor
128
+ {...args}
129
+ inputProps={{ allowNegative: false, rightSection: <Text size="xs">kr</Text> }}
130
+ />
131
+ );
132
+
133
+ // comboboxProps is merged with the grid's; withinPortal is not accepted.
134
+ const CategoryEditor: TMDataGridEditorComponent = (args) => (
135
+ <TMDataGridSelectEditor {...args} inputProps={{ comboboxProps: { shadow: "md" } }} />
136
+ );
137
+ ```
138
+
139
+ | Editor | Mantine control | Set by the grid, left out of `inputProps` |
140
+ | --- | --- | --- |
141
+ | `TMDataGridStringEditor` | `TextInput` | `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label` |
142
+ | `TMDataGridNumberEditor` | `NumberInput` | `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label` |
143
+ | `TMDataGridBooleanEditor` | `Checkbox` | `checked`, `defaultChecked`, `onChange`, `error`, `size`, `aria-label` |
144
+ | `TMDataGridDateEditor` | `TextInput` | `type`, `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label` |
145
+ | `TMDataGridSelectEditor` | `Select` | `data`, `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label`, `comboboxProps.withinPortal` |
146
+ | `TMDataGridMultiSelectEditor` | `MultiSelect` | `data`, `value`, `defaultValue`, `onChange`, `error`, `size`, `aria-label`, `comboboxProps.withinPortal` |
147
+
148
+ - `inputProps` also takes `data-*` attributes; `data-dg-part` stays
149
+ `"editor-input"`, because the grid sets it after the spread.
150
+ - `onFocus` and `onBlur` run after the grid's own: select-all on focus in the
151
+ string and number editors, `field.handleBlur()` (touched, `onBlur`
152
+ validators) in every editor.
153
+ - `onBlur` runs only when focus leaves the editor, such as a click outside it.
154
+ Enter, Tab, Escape and a committing select pick close the editor before the
155
+ focus moves, so it does not run. Code for "the edit ended" belongs in
156
+ `editing.onCommit` or `meta.edit.mapCommitValue`.
157
+ - `ref` receives the input element; the grid's own ref stays attached.
158
+ - `comboboxProps` is merged with the grid's and `withinPortal` is always
159
+ `false`, because an option picked from a portal is a click outside the cell.
160
+ - A consumer `onKeyDown` must not stop the propagation of Enter, Tab or Escape:
161
+ the grid handles them on an ancestor.
162
+ - `label` and `description` make the editor taller than the cell;
163
+ `aria-labelledby` replaces the grid's translated accessible name.
164
+ - `onChange` is the grid's; to rewrite the value as it is typed, use
165
+ `meta.edit.mapValue`.
166
+ - The grid's defaults can be overridden: `w="100%"` (not on the checkbox),
167
+ `hideControls` on the number editor, `searchable` on the select editors.
168
+ - The select editors read options from `meta.options` only; `data` is not
169
+ accepted.
170
+ - The props types are exported: `TMDataGridStringEditorProps`,
171
+ `TMDataGridNumberEditorProps`, `TMDataGridBooleanEditorProps`,
172
+ `TMDataGridDateEditorProps`, `TMDataGridSelectEditorProps`,
173
+ `TMDataGridMultiSelectEditorProps`.
174
+
175
+ To place content beside the control instead of inside it, render the built-in
176
+ inside your own layout:
102
177
 
103
178
  ```tsx
104
179
  import { Group, Text } from "@mantine/core";
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.5.0'
21
+ library_version: '2.6.0'
22
22
  sources:
23
23
  - 'Jielga/react:packages/tmdatagrid/docs/filtering.md'
24
24
  - 'Jielga/react:packages/tmdatagrid/docs/quick-search.md'
@@ -13,7 +13,7 @@ description: >
13
13
  metadata:
14
14
  type: core
15
15
  library: '@jielga/tmdatagrid'
16
- library_version: '2.5.0'
16
+ library_version: '2.6.0'
17
17
  sources:
18
18
  - 'Jielga/react:packages/tmdatagrid/docs/getting-started.md'
19
19
  - 'Jielga/react:packages/tmdatagrid/docs/anatomy.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.5.0'
17
+ library_version: '2.6.0'
18
18
  sources:
19
19
  - 'Jielga/react:packages/tmdatagrid/docs/grouping.md'
20
20
  - 'Jielga/react:packages/tmdatagrid/docs/summary-row.md'
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: lifecycle
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.5.0'
18
+ library_version: '2.6.0'
19
19
  sources:
20
20
  - 'Jielga/react:packages/tmdatagrid/docs/migrating-to-2.md'
21
21
  - 'Jielga/react:packages/tmdatagrid/src/index.ts'
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.5.0'
21
+ library_version: '2.6.0'
22
22
  sources:
23
23
  - 'Jielga/react:packages/tmdatagrid/docs/use-tm-data-grid.md'
24
24
  - 'Jielga/react:packages/tmdatagrid/docs/persistence.md'
@@ -17,7 +17,7 @@ description: >
17
17
  metadata:
18
18
  type: core
19
19
  library: '@jielga/tmdatagrid'
20
- library_version: '2.5.0'
20
+ library_version: '2.6.0'
21
21
  sources:
22
22
  - 'Jielga/react:packages/tmdatagrid/docs/row-selection.md'
23
23
  - 'Jielga/react:packages/tmdatagrid/docs/row-interaction.md'
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: core
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.5.0'
18
+ library_version: '2.6.0'
19
19
  sources:
20
20
  - 'Jielga/react:packages/tmdatagrid/docs/server-side.md'
21
21
  - 'Jielga/react:packages/tmdatagrid/docs/server-query.md'
@@ -13,7 +13,7 @@ description: >
13
13
  metadata:
14
14
  type: core
15
15
  library: '@jielga/tmdatagrid'
16
- library_version: '2.5.0'
16
+ library_version: '2.6.0'
17
17
  sources:
18
18
  - 'Jielga/react:packages/tmdatagrid/docs/testing.md'
19
19
  - 'Jielga/react:playwright/support/DataGrid.ts'
@@ -12,7 +12,7 @@ description: >
12
12
  metadata:
13
13
  type: core
14
14
  library: '@jielga/tmdatagrid'
15
- library_version: '2.5.0'
15
+ library_version: '2.6.0'
16
16
  sources:
17
17
  - 'Jielga/react:packages/tmdatagrid/docs/testing.md'
18
18
  - 'Jielga/react:packages/tmdatagrid/test/gallery/main.tsx'
@@ -12,7 +12,7 @@ description: >
12
12
  metadata:
13
13
  type: core
14
14
  library: '@jielga/tmdatagrid'
15
- library_version: '2.5.0'
15
+ library_version: '2.6.0'
16
16
  sources:
17
17
  - 'Jielga/react:packages/tmdatagrid/docs/testing.md'
18
18
  - 'Jielga/react:packages/tmdatagrid/docs/editing.md'
@@ -102,7 +102,9 @@ async saveDrafts(): Promise<void> {
102
102
 
103
103
  `fillRow` covers the built-in editors. A column with `meta.edit.editor` renders
104
104
  the app's own component inside the `editor` part; scope through
105
- `part("editor", { rowId, columnId })` and fill whatever is inside.
105
+ `part("editor", { rowId, columnId })` and fill whatever is inside. A built-in
106
+ editor rendered through `meta.edit.editor` with `inputProps` keeps
107
+ `editor-input`, so `fillRow` covers it.
106
108
 
107
109
  ## Recipes
108
110
 
@@ -1,26 +1,48 @@
1
- import { Checkbox } from "@mantine/core";
1
+ import { Checkbox, type CheckboxProps } from "@mantine/core";
2
2
  import type { TMDataGridEditorArgs } from "../../core/editEngine";
3
3
  import { getColumnLabel } from "../../core/columnUtils";
4
4
  import { useTMDataGridContext } from "../../TMDataGridContext";
5
- import { useFieldInvalid, useFieldValue } from "./editorShared";
5
+ import {
6
+ useFieldInvalid,
7
+ useFieldValue,
8
+ type EditorDataAttributes,
9
+ } from "./editorShared";
10
+
11
+ export type TMDataGridBooleanEditorProps = TMDataGridEditorArgs & {
12
+ /**
13
+ * Props for the Mantine `Checkbox`. The grid keeps `checked`, `onChange`,
14
+ * `error`, `size` and the accessible name; `onBlur` runs after the grid's
15
+ * own.
16
+ */
17
+ inputProps?: Omit<
18
+ CheckboxProps,
19
+ "checked" | "defaultChecked" | "onChange" | "error" | "size" | "aria-label"
20
+ > &
21
+ EditorDataAttributes;
22
+ };
6
23
 
7
24
  /** The built-in editor for `meta.type: "boolean"` - a focused checkbox. */
8
25
  export function TMDataGridBooleanEditor({
9
26
  field,
10
27
  column,
11
28
  size,
12
- }: TMDataGridEditorArgs) {
29
+ inputProps,
30
+ }: TMDataGridBooleanEditorProps) {
13
31
  const { labels } = useTMDataGridContext();
14
32
  const value = useFieldValue(field);
15
33
  const invalid = useFieldInvalid(field);
16
34
  return (
17
35
  <Checkbox
36
+ {...inputProps}
18
37
  size={size}
19
38
  aria-label={labels.editCell(getColumnLabel(column))}
20
39
  data-dg-part="editor-input"
21
40
  checked={value === true}
22
41
  onChange={(event) => field.handleChange(event.currentTarget.checked)}
23
- onBlur={field.handleBlur}
42
+ onBlur={(event) => {
43
+ field.handleBlur();
44
+ inputProps?.onBlur?.(event);
45
+ }}
24
46
  error={invalid}
25
47
  />
26
48
  );
@@ -1,9 +1,32 @@
1
- import { TextInput } from "@mantine/core";
1
+ import { TextInput, type TextInputProps } from "@mantine/core";
2
2
  import { useRef } from "react";
3
3
  import type { TMDataGridEditorArgs } from "../../core/editEngine";
4
4
  import { getColumnLabel } from "../../core/columnUtils";
5
5
  import { useTMDataGridContext } from "../../TMDataGridContext";
6
- import { useFieldInvalid, useFieldValue } from "./editorShared";
6
+ import {
7
+ useFieldInvalid,
8
+ useFieldValue,
9
+ type EditorDataAttributes,
10
+ } from "./editorShared";
11
+
12
+ export type TMDataGridDateEditorProps = TMDataGridEditorArgs & {
13
+ /**
14
+ * Props for the Mantine `TextInput`. The grid keeps `type`, the value,
15
+ * `onChange`, `error`, `size` and the accessible name; `onBlur` runs after
16
+ * the grid's own.
17
+ */
18
+ inputProps?: Omit<
19
+ TextInputProps,
20
+ | "type"
21
+ | "value"
22
+ | "defaultValue"
23
+ | "onChange"
24
+ | "error"
25
+ | "size"
26
+ | "aria-label"
27
+ > &
28
+ EditorDataAttributes;
29
+ };
7
30
 
8
31
  /**
9
32
  * The built-in editor for `meta.type: "date"` - the native
@@ -14,7 +37,8 @@ export function TMDataGridDateEditor({
14
37
  field,
15
38
  column,
16
39
  size,
17
- }: TMDataGridEditorArgs) {
40
+ inputProps,
41
+ }: TMDataGridDateEditorProps) {
18
42
  const { labels } = useTMDataGridContext();
19
43
  const value = useFieldValue(field);
20
44
  const invalid = useFieldInvalid(field);
@@ -32,8 +56,9 @@ export function TMDataGridDateEditor({
32
56
 
33
57
  return (
34
58
  <TextInput
35
- size={size}
36
59
  w="100%"
60
+ {...inputProps}
61
+ size={size}
37
62
  type="date"
38
63
  aria-label={labels.editCell(getColumnLabel(column))}
39
64
  data-dg-part="editor-input"
@@ -48,7 +73,10 @@ export function TMDataGridDateEditor({
48
73
  writesDates.current ? new Date(`${next}T00:00:00`) : next,
49
74
  );
50
75
  }}
51
- onBlur={field.handleBlur}
76
+ onBlur={(event) => {
77
+ field.handleBlur();
78
+ inputProps?.onBlur?.(event);
79
+ }}
52
80
  error={invalid}
53
81
  />
54
82
  );