You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 888d799
Browse filesBrowse the repository at this point in the historyBrowse files
fix(react)!: make stable row identity consistent across every entry point (#404)
* fix(react): make optional-when-conventional row identity one contract
`PretableSurfaceRowsProps` declared `getRowId` non-optional while the docs,
`usePretable`, `useLocalRowModel` and `createLocalRowModel` all treated it as
optional for rows with a conventional `id`. The engine has always agreed with
the docs — `createLocalRowModel` falls back to `row.id`, `usePretable` drops an
`undefined` accessor before forwarding, and `<PretableSurface>` already passed
`getRowId` through unconditionally — so the component prop types were the side
that was wrong, and a reader following the docs hit a type error on their first
typed grid.
Omitting the prop was not even a clean failure. Because `getRowId` was a
required member of an intersection-of-union props type, its absence made
inference for the whole call bail to the type-parameter defaults, so the
reported error was a `TColumns` mismatch against `readonly
PretableColumn<object>[]` rather than a missing prop. Declaring it optional
restores inference: `TRow`, `TRowId` and `TColumns` now come from `rows` and
`columns` alone.
`getRowId` is now optional on `<PretableSurface>`, `<Pretable>` and
`<LabeledGridSurface>`, with the new `PretableRowIdRequirement` intersected in
to re-require it for any row shape without an `id: string | number`. That guard
was missing on `usePretable` too, which silently accepted id-less rows and
resolved `TRowId` to `never`, deferring the failure to a `PretableRowModelError`
on the first row read; `UsePretableRowsOptions` is now gated the same way
`CreateLocalRowModelWithDefaultIdOptions` always was.
`<Pretable>` forwards its props as one object rather than prop by prop, because
re-listing `getRowId` erases the unresolved conditional the surface requires.
Covered by a type test under `typecheck:public` and by runtime tests that a
selection and a focused cell stay pinned to the same row across a row-set
update — fresh objects, reordered, with `id` deliberately disagreeing with array
position — plus a case proving an explicit `getRowId` still wins.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: regenerate react.api.md after the final format pass
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: apps/website/content/docs/grid/api-reference.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,7 +65,7 @@ Both helpers return native `Intl.NumberFormatOptions` and are exported from `@pr
65
65
66
66
`rows` and `model` are mutually exclusive. Rows mode diffs each new `rows` prop into its long-lived local model. Explicit-model mode makes the supplied model the only data/derivation owner; compatible `columns` may override presentation only.
67
67
68
-
Rows with a conventional string or number `id` do not require `getRowId`. Otherwise pass a stable explicit accessor. Identity survives row-array replacements and is used by selection, focus, editing, expansion, and transactions.
68
+
Rows with a conventional string or number `id` do not require `getRowId`. Otherwise it is required, and omitting it is a compile error rather than a runtime failure. This is one contract across every entry point that takes rows — `<Pretable>`, `<PretableSurface>`, `usePretable`, `useLocalRowModel`, and `createLocalRowModel` all treat the accessor the same way. Identity survives row-array replacements and is used by selection, focus, editing, expansion, and transactions.
69
69
70
70
Important shared props include `ariaLabel`, `viewportHeight`, `overscan`, `locale`, `state`, `onSelectionChange`, `onRowSelectionChange`, `onFocusChange`, `onPaste`, `onCopy`, `copyToClipboard`, `csvOptions`, `onExport`, `saveFile`, `groupPanel`, `groupColumn`, `hideGroupedColumns`, and cell/header/row render hooks. Rows mode alone accepts the exact controlled `query`/`onQueryChange` pair, `onRowChange`, `initialExpansion`, and `aggregateFilteredRows`. Explicit-model mode alone accepts `beforeRowChange`.
`getRowId` is required — there is no positional default. Row identity is never derived from array position, so pass a function that reads a stable key off the row itself.
41
+
Row identity is never derived from array position. `Person` above has a conventional `id`, so `getRowId` is optional there and the grid reads `row.id`; the example passes it anyway to name the key explicitly. For a row whose stable key is anything else, `getRowId` is required and omitting it is a type error, not a runtime surprise.
42
42
43
43
## Props
44
44
45
-
`columns`, `rows`, `ariaLabel`, and `getRowId`are required — `ariaLabel` is the grid's accessible name, so give it something a screen reader user would recognize as this table's contents (e.g. `"People directory"`, not a generic placeholder). The concise preset also forwards row activation and selection callbacks, row changes, clipboard hooks, tab behavior, messages, the optional selection column, and column width/order/pinning callbacks. Use [`<PretableSurface>`](/docs/grid/pretable-surface) for controlled query and interaction state, grouping controls, custom renderers, explicit row-model ownership, telemetry, or a custom viewport height.
45
+
`columns`, `rows`, and `ariaLabel` are required, and so is `getRowId`unless the row has a conventional string or number `id` — `ariaLabel` is the grid's accessible name, so give it something a screen reader user would recognize as this table's contents (e.g. `"People directory"`, not a generic placeholder). The concise preset also forwards row activation and selection callbacks, row changes, clipboard hooks, tab behavior, messages, the optional selection column, and column width/order/pinning callbacks. Use [`<PretableSurface>`](/docs/grid/pretable-surface) for controlled query and interaction state, grouping controls, custom renderers, explicit row-model ownership, telemetry, or a custom viewport height.
0 commit comments