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

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jielga/tmdatagrid",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.3",
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",
@@ -16,7 +16,7 @@ description: >
16
16
  metadata:
17
17
  type: core
18
18
  library: '@jielga/tmdatagrid'
19
- library_version: '2.0.0-beta.2'
19
+ library_version: '2.0.0-beta.3'
20
20
  sources:
21
21
  - 'Jielga/TMDataGrid:src/docs/styling.md'
22
22
  - 'Jielga/TMDataGrid:src/docs/toolbar.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.2'
17
+ library_version: '2.0.0-beta.3'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:src/docs/cell-selection.md'
20
20
  - 'Jielga/TMDataGrid:src/tmdatagrid/core/cellNavigation.ts'
@@ -16,7 +16,7 @@ description: >
16
16
  metadata:
17
17
  type: core
18
18
  library: '@jielga/tmdatagrid'
19
- library_version: '2.0.0-beta.2'
19
+ library_version: '2.0.0-beta.3'
20
20
  sources:
21
21
  - 'Jielga/TMDataGrid:src/docs/columns.md'
22
22
  - 'Jielga/TMDataGrid:src/docs/column-layout.md'
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: core
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.0.0-beta.2'
18
+ library_version: '2.0.0-beta.3'
19
19
  sources:
20
20
  - 'Jielga/TMDataGrid:src/docs/pagination.md'
21
21
  - 'Jielga/TMDataGrid:src/docs/scrolling.md'
@@ -3,7 +3,7 @@ name: editing
3
3
  description: >
4
4
  Edit cells and rows in TMDataGrid. Covers the editing option with its four
5
5
  mode policies (cell, cellConfirm, row, draft), the required getRowId,
6
- editing.onCommit and editing.onCommitDrafts, why the grid never mutates data,
6
+ editing.onCommit and editing.onSaveDrafts, why the grid never mutates data,
7
7
  per-column gating with meta.edit.enabled and meta.edit.field, the six built-in
8
8
  editors picked by meta.type, custom editors through meta.edit.editor,
9
9
  per-keystroke value mapping with meta.edit.mapValue, field validation with
@@ -11,13 +11,14 @@ description: >
11
11
  Schema and Zod), adding and deleting rows with edit.addRow,
12
12
  editing.newRowDefaults, editing.onRowAdd and editing.onRowDelete, the
13
13
  generated edit lane, TMDataGrid.EditActions with its renderActions slot, and
14
- the public edit engine (begin, commit, cancel, submitAll, getForm, store).
15
- Load when making a grid editable, choosing an edit mode, wiring a save,
16
- writing a cell editor, validating an edit, or when cells will not open.
14
+ the public edit engine (begin, commit, commitAll, saveDrafts, addRows,
15
+ getForm, store). Load when making a grid editable, choosing an edit mode,
16
+ wiring a save, writing a cell editor, validating an edit, or when cells will
17
+ not open.
17
18
  metadata:
18
19
  type: core
19
20
  library: '@jielga/tmdatagrid'
20
- library_version: '2.0.0-beta.2'
21
+ library_version: '2.0.0-beta.3'
21
22
  sources:
22
23
  - 'Jielga/TMDataGrid:src/docs/editing.md'
23
24
  - 'Jielga/TMDataGrid:src/docs/query-builder.md'
@@ -69,8 +70,8 @@ const grid = useTMDataGrid({
69
70
  ```
70
71
 
71
72
  Two rules are compile errors, not options that silently do nothing: `editing`
72
- requires `getRowId`, and `editing.onCommitDrafts` exists only under
73
- `editing.mode: "draft"`. Draft _without_ `onCommitDrafts` is fine: `submitAll`
73
+ requires `getRowId`, and `editing.onSaveDrafts` exists only under
74
+ `editing.mode: "draft"`. Draft _without_ `onSaveDrafts` is fine: `saveDrafts`
74
75
  falls back to the per-row `editing.onCommit` loop.
75
76
 
76
77
  ## The four modes
@@ -83,7 +84,7 @@ as a commit, and which controls trigger it.
83
84
  | `"cell"` | Enter, Tab, blur | Escape | none |
84
85
  | `"cellConfirm"` | ✓ or Enter; blur keeps the draft | ✕ or Escape | ✓ / ✕ beside the input |
85
86
  | `"row"` | Save in the edit lane, or Ctrl+Enter | Cancel, or Escape | generated edit lane |
86
- | `"draft"` | `edit.submitAll()` | `edit.cancelAll()`, or per row in the lane | `TMDataGrid.EditActions` + the edit lane |
87
+ | `"draft"` | Enter or the lane's ✓, into the draft store | `edit.cancelAll()`, or per row in the lane | `TMDataGrid.EditActions` + the edit lane |
87
88
 
88
89
  Which to pick: `"cell"` for saved-as-you-go spreadsheet feel; `"cellConfirm"`
89
90
  when a stray click must not fire a request; `"row"` when the row is the unit of
@@ -104,7 +105,8 @@ the cell clicked, opens every editable cell of the row, and ✓ saves them as on
104
105
  commit. Rows accumulate: opening a second row leaves the first open, and each
105
106
  row's ✓ and ✕ act on that row alone.
106
107
 
107
- Under `"draft"` nothing reaches a callback until `submitAll`. Enter and Tab hold
108
+ Under `"draft"` nothing reaches a callback until `saveDrafts`. Enter commits the
109
+ row into the draft store; Tab holds
108
110
  the draft, Tab moving on to the next editable cell, Escape drops that one draft,
109
111
  and drafts accumulate across rows, surviving filters, sorts and scrolling.
110
112
  `edit.commit(rowId)` validates and holds the draft too, so there is no per-row
@@ -119,9 +121,9 @@ Restore. A row holding a dirty draft hides the trash - revert first, then
119
121
  delete. A row blocked by validation turns its icon red with the message in the
120
122
  tooltip.
121
123
 
122
- `submitAll` then commits every pending change: through the per-row
124
+ `saveDrafts` then sends the draft store: through the per-row
123
125
  `editing.onCommit` / `editing.onRowAdd` / `editing.onRowDelete` loop by default,
124
- or through one `editing.onCommitDrafts({ rows, added, deleted })` call when that
126
+ or through one `editing.onSaveDrafts({ rows, added, deleted })` call when that
125
127
  is set. Rows failing validation stay open either way, and a rejected save keeps
126
128
  every draft.
127
129
 
@@ -210,18 +212,21 @@ Detail for all three: [references/editors-and-validation.md](references/editors-
210
212
  ## Adding and deleting rows
211
213
 
212
214
  `edit.addRow()` opens an entry row in a sticky block under the header, seeded
213
- from `editing.newRowDefaults`. Enter, or the lane's ✓, commits the add through
214
- `editing.onRowAdd` under the immediate modes; under draft mode it enters the
215
- row, which is validated, held with the other drafts, and reported in
216
- `submitAll`'s `added`. Escape, or ✕, discards the entry.
215
+ from `editing.newRowDefaults`. `edit.addRow(values)` overrides that seed key by
216
+ key, so `addRow()` opens the `newRowDefaults` row and `addRow(values)` opens it
217
+ with those fields filled in - pass a whole row to duplicate it. Enter, or the
218
+ lane's ✓, commits the add through `editing.onRowAdd` under the immediate modes;
219
+ under draft mode it puts the row in the draft store, validated, and
220
+ `saveDrafts` reports it in `added`. Escape, or ✕, discards the entry. An entry
221
+ row never OK'd is not part of a save - it stays open.
217
222
 
218
223
  Under `"draft"` an entered row renders as a value row with no inputs, marked
219
- `data-new` and `data-confirmed` and tinted with `--dg-row-new-bg`. By default it
224
+ `data-new` and `data-committed` and tinted with `--dg-row-new-bg`. By default it
220
225
  joins the scrolling flow above the body rows; `editing.newRowsSticky: true`
221
- keeps entered rows pinned in the entry block until Save all. Double-click, or
226
+ keeps committed rows pinned in the entry block until the save. Double-click, or
222
227
  the lane's pencil, reopens it; ✕ removes it. To limit how many entry rows are
223
228
  open at once, gate the Add button on
224
- `useSelector(grid.edit.store, (s) => s.newRows.some((n) => !n.confirmed))`.
229
+ `useSelector(grid.edit.store, (s) => s.newRows.some((n) => !n.committed))`.
225
230
 
226
231
  ```tsx
227
232
  const grid = useTMDataGrid({
@@ -231,7 +236,7 @@ const grid = useTMDataGrid({
231
236
  editing: {
232
237
  mode: "draft",
233
238
  newRowDefaults: () => ({ id: 0, firstName: "", salary: 30_000 }),
234
- onCommitDrafts: async ({ rows, added, deleted }) => {
239
+ onSaveDrafts: async ({ rows, added, deleted }) => {
235
240
  await api.saveBatch({ rows, added, deleted });
236
241
  },
237
242
  },
@@ -239,15 +244,31 @@ const grid = useTMDataGrid({
239
244
 
240
245
  <TMDataGrid.Toolbar>
241
246
  <Button onClick={() => grid.edit.addRow()}>Add row</Button>
247
+ <Button onClick={() => grid.edit.addRow({ salary: 50_000 })}>
248
+ Add senior
249
+ </Button>
242
250
  <TMDataGrid.Spacer />
243
251
  <TMDataGrid.EditActions />
244
252
  </TMDataGrid.Toolbar>;
245
253
  ```
246
254
 
255
+ `edit.addRows(rows, options?)` opens a batch in one write. `{ commit: true }`
256
+ submits each row as it lands - the import case: valid rows are committed,
257
+ invalid ones stay open in the entry block with their errors, and the result
258
+ (`{ committed, open }`) says which went which way. Column rules are enforced
259
+ even though the rows never had an editor on screen, because the engine runs
260
+ `meta.edit.validate` itself at commit.
261
+
262
+ ```tsx
263
+ const { committed, open } = await grid.edit.addRows(parsed, { commit: true });
264
+ if (open.length > 0) notify(`${open.length} rows need attention`);
265
+ await grid.edit.saveDrafts();
266
+ ```
267
+
247
268
  `edit.deleteRow(rowId)` calls `editing.onRowDelete({ rowId, row })` immediately
248
269
  under the immediate modes, so put any confirmation inside that callback. Under
249
270
  draft mode it toggles a mark instead: the row renders struck through and inert
250
- (`data-deleted`), the lane shows Restore, and `submitAll` reports the ids in
271
+ (`data-deleted`), the lane shows Restore, and `saveDrafts` reports the ids in
251
272
  `deleted`. You apply adds and deletes, the same as edits. The engine's `tempId`
252
273
  (`__new__1`, …) does not need to become a real id.
253
274
 
@@ -283,7 +304,8 @@ while editing is off, and works under any mode, not only draft.
283
304
  ## The engine: `edit`
284
305
 
285
306
  `grid.edit` is public, and everything the built-in controls do goes through it:
286
- `begin` and `commit`, `cancel` / `cancelAll`, `submitAll`, `addRow` /
307
+ `begin` and `commit`, `cancel` / `cancelAll`, `commitAll` / `saveDrafts`,
308
+ `addRow` / `addRows` /
287
309
  `deleteRow`, `getForm`, and `store` for `useSelector` (an example is under
288
310
  [Submitting an outer form](#high-submitting-an-outer-form-while-the-grid-holds-a-draft)).
289
311
  Every member with its signature, the gates, `clearCell`, `deactivate`, and the
@@ -324,7 +346,7 @@ are in [references/common-mistakes.md](references/common-mistakes.md).
324
346
  | HIGH | Swallowing the error in `editing.onCommit` - a resolved catch drops the draft |
325
347
  | HIGH | Submitting an outer form while the grid holds a draft - it saves stale rows |
326
348
  | MEDIUM | Reading a commit's result as the saved value - it is a `boolean` about the form |
327
- | MEDIUM | Expecting `editing.onRowDelete` to fire under draft - the mark waits for `submitAll` |
349
+ | MEDIUM | Expecting `editing.onRowDelete` to fire under draft - the mark waits for `saveDrafts` |
328
350
 
329
351
  ## References
330
352
 
@@ -137,7 +137,7 @@ Source: `src/tmdatagrid/useTMDataGrid.tsx` (`TMDataGridEditingCallbacks`).
137
137
  ## HIGH Submitting an outer form while the grid holds a draft
138
138
 
139
139
  The outer form's array contains only committed rows. Under any mode a mid-edit
140
- row is invisible to it, and under `"draft"` every edit is until `submitAll()`,
140
+ row is invisible to it, and under `"draft"` every edit is until `saveDrafts()`,
141
141
  so a form submit saves stale rows and collection rules skip pending values.
142
142
 
143
143
  Correct:
@@ -146,8 +146,9 @@ Correct:
146
146
  const hasOpenDraft = useSelector(grid.edit.store, (s) => s.openRowIds.length > 0);
147
147
 
148
148
  <Button type="submit" disabled={!canSubmit || hasOpenDraft}>Save</Button>
149
- // or flush instead of blocking:
150
- const flushed = await grid.edit.submitAll();
149
+ // or commit and flush instead of blocking:
150
+ await grid.edit.commitAll();
151
+ const flushed = await grid.edit.saveDrafts();
151
152
  if (flushed) await form.handleSubmit();
152
153
  ```
153
154
 
@@ -155,12 +156,13 @@ Source: `src/docs/query-builder.md` (Which mode, Submitting).
155
156
 
156
157
  ## MEDIUM Reading a commit's result as the saved value
157
158
 
158
- `edit.commit(rowId)` and `edit.submitAll()` resolve to a `boolean` saying
159
- whether the form closed, and resolve `false` when validation or a rejected save
160
- kept it open. Ignoring the result reports a save that did not happen.
159
+ `edit.commit(rowId)`, `edit.commitAll()` and `edit.saveDrafts()` resolve to a
160
+ `boolean` saying whether everything landed, and resolve `false` when validation
161
+ or a rejected save kept a row open. Ignoring the result reports a save that did
162
+ not happen.
161
163
 
162
164
  ```tsx
163
- const saved = await grid.edit.submitAll();
165
+ const saved = await grid.edit.saveDrafts();
164
166
  notifications.show({ message: saved ? "Saved" : "Some rows need attention" });
165
167
  ```
166
168
 
@@ -170,7 +172,7 @@ Source: `src/tmdatagrid/core/editEngine.ts` (`TMDataGridEditApi`).
170
172
 
171
173
  Under the immediate modes `edit.deleteRow` calls `editing.onRowDelete` at once.
172
174
  Under `"draft"` it only toggles a deletion mark, so nothing is removed until
173
- `submitAll`: the ids arrive as `deleted` in `editing.onCommitDrafts`, or, with
175
+ `saveDrafts`: the ids arrive as `deleted` in `editing.onSaveDrafts`, or, with
174
176
  no such callback, in the per-row `editing.onRowDelete` loop. A confirmation
175
177
  placed inside `editing.onRowDelete` therefore guards the save, not the trash.
176
178
 
@@ -17,7 +17,7 @@ kind.
17
17
  | `cellSelection` | `"none" \| "single" \| "range"` | `"single"` while `editing` is set | Editing turns the cell cursor on; set it explicitly to override. |
18
18
 
19
19
  Passing any other member of `editing` without `mode` is a compile error, and
20
- `onCommitDrafts` and `newRowsSticky` exist only in the `"draft"` branch of the
20
+ `onSaveDrafts` and `newRowsSticky` exist only in the `"draft"` branch of the
21
21
  type.
22
22
 
23
23
  ## Callbacks
@@ -25,7 +25,8 @@ type.
25
25
  | Name | Argument | What it does |
26
26
  | --- | --- | --- |
27
27
  | `editing.onCommit` | `{ rowId, value, original, changes, source }` | Applies one row's change. Reject to keep the draft and show the error. |
28
- | `editing.onCommitDrafts` | `{ rows, added, deleted }` | Draft mode only. One call for the entire save. Without it, `submitAll` loops `editing.onCommit`, `editing.onRowAdd` and `editing.onRowDelete`. |
28
+ | `editing.onSaveDrafts` | `{ rows, added, deleted }` | Draft mode only. One call for the whole draft store. Without it, `saveDrafts` loops `editing.onCommit`, `editing.onRowAdd` and `editing.onRowDelete`. |
29
+ | `editing.onCommitDrafts` | `{ rows, added, deleted }` | **Deprecated** - renamed to `onSaveDrafts`. Still honoured; the new name wins if both are set. |
29
30
  | `editing.onRowAdd` | `{ tempId, value }` | Commits an entry row. Mint the real id here. |
30
31
  | `editing.onRowDelete` | `{ rowId, row }` | Deletes a row under the immediate modes, and puts the trash can in the edit lane. |
31
32
 
@@ -49,14 +50,17 @@ path, which may be dotted.
49
50
 
50
51
  | Member | Signature | Notes |
51
52
  | --- | --- | --- |
52
- | `begin` | `({ rowId, columnId }) => void` | Row mode opens the entire row either way. `columnId` selects which cell takes the caret; `null` (the pencil) uses its first editable one. On an entered new row it reopens the row, flipping `confirmed` back to `false`. |
53
- | `commit` | `(rowId) => Promise<boolean>` | `false` keeps the form open with its errors. Under `"draft"` it validates and holds the draft: no consumer callback runs until `submitAll`. |
53
+ | `begin` | `({ rowId, columnId }) => void` | Row mode opens the entire row either way. `columnId` selects which cell takes the caret; `null` (the pencil) uses its first editable one. On a committed row it reopens it, taking it back out of the draft store. |
54
+ | `commit` | `(rowId) => Promise<boolean>` | The OK gesture: submits the row's form. `false` keeps it open with its errors. Under `"draft"` a pass puts the row in the draft store - no consumer callback runs until `saveDrafts`. Column rules run whether or not an editor is mounted. |
55
+ | `commitAll` | `() => Promise<boolean>` | Submits every open row. Rows that fail stay open. `false` when one did. |
56
+ | `saveDrafts` | `() => Promise<boolean>` | Sends the draft store. Open rows are left alone and stay open. |
54
57
  | `cancel` | `(rowId) => void` | Drops one draft. |
55
58
  | `cancelAll` | `() => void` | Drops every draft. |
56
59
  | `deactivate` | `() => void` | Closes the editor without touching the draft, as blur does under `"cellConfirm"`. |
57
- | `submitAll` | `() => Promise<boolean>` | Draft mode's Save all. `true` when every row landed. |
60
+ | `submitAll` | `() => Promise<boolean>` | **Deprecated** - `commitAll()` then `saveDrafts()`. |
58
61
  | `clearCell` | `(rowId, columnId) => Promise<boolean>` | What Delete does: writes the type's empty value and commits. |
59
- | `addRow` | `() => string` | Opens an entry row, returns its `tempId`. |
62
+ | `addRow` | `(values?) => string` | Opens an entry row, returns its `tempId`. `values` overrides `editing.newRowDefaults` key by key for that row; with no argument the row is `newRowDefaults` alone. |
63
+ | `addRows` | `(rows, options?) => Promise<{ committed, open }>` | Opens a batch in one write, each row seeded as `addRow` seeds. `{ commit: true }` submits each as it lands - valid rows commit, invalid ones stay open with their errors. |
60
64
  | `deleteRow` | `(rowId) => void` | `editing.onRowDelete` under the immediate modes, a deletion mark under draft mode. Toggles: a second call restores the row. |
61
65
  | `canEditCell` | `(row, column) => boolean` | The check the built-in controls use. |
62
66
  | `canEditRow` | `(row) => boolean` | The pencil's gate. |
@@ -71,8 +75,8 @@ path, which may be dotted.
71
75
  type TMDataGridEditState = {
72
76
  // The cell the last open gesture named - where the caret goes.
73
77
  active: { rowId: string; columnId: string | null } | null;
74
- // Rows with a live form. One under `"cell"`; as many as the user opened
75
- // under `"row"`, `"cellConfirm"` and `"draft"` - which rows are editing.
78
+ // Rows with a live form, committed or not. A row is *open* when it is in
79
+ // here and not in `committedRowIds`.
76
80
  openRowIds: ReadonlyArray<string>;
77
81
  // One `TMDataGridEditRowProjection` per open row.
78
82
  rows: Record<
@@ -86,9 +90,12 @@ type TMDataGridEditState = {
86
90
  values: TMDataGridRowData;
87
91
  }
88
92
  >;
89
- // `confirmed` is draft mode's "entered, awaiting Save all". Under the
90
- // immediate modes a confirm commits through `onRowAdd`, so it stays `false`.
91
- newRows: ReadonlyArray<{ tempId: string; confirmed: boolean }>;
93
+ // The draft store's edit slice: existing rows whose form passed its submit,
94
+ // parked for `saveDrafts`. Empty outside `"draft"`.
95
+ committedRowIds: ReadonlyArray<string>;
96
+ // `committed` is draft mode's "in the store, awaiting the save". Under the
97
+ // immediate modes a commit adds through `onRowAdd`, so it stays `false`.
98
+ newRows: ReadonlyArray<{ tempId: string; committed: boolean }>;
92
99
  deletedRowIds: ReadonlyArray<string>;
93
100
  };
94
101
  ```
@@ -119,7 +126,7 @@ holds:
119
126
 
120
127
  - `editing.mode: "row"` - the lane is Save and Cancel's home
121
128
  - `editing.mode: "draft"` - the lane is the change indicator and the per-row
122
- revert, and `editing.onCommitDrafts` is not required for it
129
+ revert, and `editing.onSaveDrafts` is not required for it
123
130
  - `editing.onRowDelete` is set - the trash can has somewhere to report to
124
131
 
125
132
  `"cell"` and `"cellConfirm"` have no lane unless `editing.onRowDelete` asks for
@@ -142,7 +149,7 @@ control carries a tooltip from the labels, `revertRow`, `rowStateNew`,
142
149
  | `--dg-row-new-bg` | CSS variable | Background of an entered new row. A green tint. |
143
150
  | `data-deleted` | Row attribute | On a row marked for deletion under draft mode. |
144
151
  | `data-dirty` | Row attribute | On a body row holding a dirty draft. Also on the cell whose field is dirty. |
145
- | `data-new` / `data-confirmed` | Entry row attributes | On an entry row; `data-confirmed` once it is entered, awaiting Save all. |
152
+ | `data-new` / `data-committed` | Entry row attributes | On an entry row; `data-committed` once it is committed, awaiting the save. |
146
153
  | `data-dg-entry-flow-block` | Attribute | The in-flow block above the body rows holding entered new rows, unless `editing.newRowsSticky` keeps them in the sticky entry block. |
147
154
  | `data-dg-part="editor-input"` | Part | The control inside an editing cell. |
148
155
  | `data-dg-part="save-row"` / `"cancel-row"` | Parts | The edit lane's buttons on an open row, with `data-row-id`. Row mode only. |
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: core
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.0.0-beta.2'
18
+ library_version: '2.0.0-beta.3'
19
19
  sources:
20
20
  - 'Jielga/TMDataGrid:src/docs/filtering.md'
21
21
  - 'Jielga/TMDataGrid:src/docs/quick-search.md'
@@ -11,7 +11,7 @@ description: >
11
11
  metadata:
12
12
  type: core
13
13
  library: '@jielga/tmdatagrid'
14
- library_version: '2.0.0-beta.2'
14
+ library_version: '2.0.0-beta.3'
15
15
  sources:
16
16
  - 'Jielga/TMDataGrid:src/docs/getting-started.md'
17
17
  - 'Jielga/TMDataGrid:src/docs/anatomy.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.2'
17
+ library_version: '2.0.0-beta.3'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:src/docs/grouping.md'
20
20
  - 'Jielga/TMDataGrid:src/docs/summary-row.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.2'
17
+ library_version: '2.0.0-beta.3'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:src/docs/use-tm-data-grid.md'
20
20
  - 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
@@ -65,7 +65,7 @@ rather than forwarded to TanStack.
65
65
  | `initialState` | `Partial<TableState>` | See below | Merged over the grid defaults. |
66
66
  | `meta` | `TMDataGridTableMeta` | `{}` | Grid configuration, see below. |
67
67
  | `persist` | `TMDataGridPersistence` | – | State persistence, see below. |
68
- | `editing` | `TMDataGridEditingOptions` | off | Turns editing on. `mode` (`"cell" \| "cellConfirm" \| "row" \| "draft"`) picks the commit policy; the object also holds `onCommit`, `onCommitDrafts`, `rowValidators`, `isRowEditable`, `newRowDefaults`, `newRowsSticky`, `onRowAdd` and `onRowDelete` - see the `editing` skill. |
68
+ | `editing` | `TMDataGridEditingOptions` | off | Turns editing on. `mode` (`"cell" \| "cellConfirm" \| "row" \| "draft"`) picks the commit policy; the object also holds `onCommit`, `onSaveDrafts`, `rowValidators`, `isRowEditable`, `newRowDefaults`, `newRowsSticky`, `onRowAdd` and `onRowDelete` - see the `editing` skill. |
69
69
  | `labels` | `TMDataGridLabelsOverride` | English | Overrides for the grid's strings and `aria-label`s. |
70
70
 
71
71
  ### Default initial state
@@ -17,7 +17,7 @@ description: >
17
17
  metadata:
18
18
  type: core
19
19
  library: '@jielga/tmdatagrid'
20
- library_version: '2.0.0-beta.2'
20
+ library_version: '2.0.0-beta.3'
21
21
  sources:
22
22
  - 'Jielga/TMDataGrid:src/docs/row-selection.md'
23
23
  - 'Jielga/TMDataGrid:src/docs/row-interaction.md'
@@ -10,7 +10,7 @@ description: >
10
10
  metadata:
11
11
  type: core
12
12
  library: '@jielga/tmdatagrid'
13
- library_version: '2.0.0-beta.2'
13
+ library_version: '2.0.0-beta.3'
14
14
  sources:
15
15
  - 'Jielga/TMDataGrid:src/docs/server-side.md'
16
16
  - 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
@@ -11,7 +11,7 @@ description: >
11
11
  metadata:
12
12
  type: core
13
13
  library: '@jielga/tmdatagrid'
14
- library_version: '2.0.0-beta.2'
14
+ library_version: '2.0.0-beta.3'
15
15
  sources:
16
16
  - 'Jielga/TMDataGrid:src/docs/testing.md'
17
17
  - 'Jielga/TMDataGrid:src/tmdatagrid/components/TMDataGrid.tsx'
@@ -172,7 +172,11 @@ export function TMDataGridCellEditor({
172
172
  onClose({ committed: false, via: "escape" });
173
173
  };
174
174
 
175
- /** Draft: the key closes the editor and leaves the draft for submitAll. */
175
+ /**
176
+ * Draft: the key closes the editor and leaves the row open - undecided
177
+ * form state, which `saveDrafts` does not send. Tab moving along the row
178
+ * is not a decision about it; Enter is, and commits instead.
179
+ */
176
180
  const deferAndClose = (via: "defer" | "defer-tab" | "defer-shift-tab") => {
177
181
  if (closingRef.current) return;
178
182
  closingRef.current = true;
@@ -185,12 +189,11 @@ export function TMDataGridCellEditor({
185
189
  if (event.key === "Enter") {
186
190
  event.preventDefault();
187
191
  event.stopPropagation();
188
- // In row mode Enter (and Ctrl+Enter, the documented pair) saves the
189
- // row; in draft nothing reaches a callback until submitAll, so Enter
190
- // parks the draft - and in the entry block it confirms the entry, which
191
- // the engine parks the same way.
192
- if (isDraft && !inEntryBlock) deferAndClose("defer");
193
- else void commitAndClose("enter");
192
+ // Enter is OK, in every mode: the row's form submits and has to pass
193
+ // validation. What a commit *does* is the mode's business - the
194
+ // immediate modes call the consumer, draft mode parks the row in the
195
+ // draft store for `saveDrafts` - so this key does not branch.
196
+ void commitAndClose("enter");
194
197
  } else if (event.key === "Escape") {
195
198
  event.preventDefault();
196
199
  event.stopPropagation();