Leaf of #18762. RowModel is the grid's default selection model (learn/guides/datahandling/Grids.md, "Selection Models"). With cellEditing: true and that default, a keyboard user cannot start an edit at all, and after a pointer-started edit the arrow keys lose their place. Measured in real Chromium (Playwright e2e rig, dev@7db03e862c), not derived.
The Problem
Fixture test/playwright/component/apps/grid-cell-editing, grid #grid-cell-editing-pooled, view.selectionModel switched to RowModel at runtime:
Step
Editors
Selected rows
click record 3's c3
0
record 3
Enter
0
record 3
F2
0
record 3
ArrowDown, then Enter
0
record 4
double-click record 3's c3 (control)
1
none — the two clicks toggled the row on and off
type, Enter (commit)
0
none, focus on the View
ArrowDown
0
record 2 — the arrows restart from the store's first record
So under the default model the feature is pointer-only (WCAG 2.1.1), and a committed edit on row 250 sends the next ArrowDown to row 2.
The public example hides this: examples/grid/cellEditing offers only the four cell-selecting models. The guide says "Enter or F2 edits the selected cell" and never names the precondition.
Source authority: D#17832's interaction convergence — "double-click, F2 and Enter activate an editable active target" and "Selection is neither necessary nor sufficient across Row/Cell selection models". The shipped keyboard path takes its target from the cell selection alone.
The Architectural Reality
src/grid/plugin/CellEditing.mjs#editSelectedCell (:178–184) reads view.selectedCells[0]; grid.View#selectedCells (src/grid/View.mjs:137) returns [] for a model without selectsCells. Enter and F2 on the View both route there.
#onEnterKey (:388–404) re-selects the edited cell after a commit only when selectionModel.selectsCells; a row-only model gets no anchor back.
src/selection/grid/RowModel.mjs:75: with no selected row the nav keys start from store.getAt(0).
A row's selection toggles per click, so a double-click deselects the row it edits (RowModel#onRowClick).
The born-suspended start (startEdit(record, dataField, true) + view.scrollByRows / scrollByColumns, the Tab path in #onTabKey) already embodies an edit whose cell is outside the mounted window.
The Fix
In src/grid/plugin/CellEditing.mjs:
The keyboard target follows the selection: a selected cell wins (unchanged). With a selected row and no selected cell → that row's record, in the column of the grid's last edit while that column is still editable, else the record's first editable column in arrow-walk order. A target out of sight is scrolled into it through the Tab path (one helper, editInSight, for both).
A model that selects rows follows the edit by its row: startEdit selects the edited record's row when it is not selected, so every end (Enter, Escape, Tab past either end) leaves it selected.
Scope amendment (2026-09-19, measured while implementing): rule 2 was first scoped to models that select rows and no cells. A probe on the public example under "Cell & Row" falsified that guard: today Tab into the next record selects the cell and leaves no row selected, and a double-click edit ended by Escape leaves nothing selected; with the rule applied to every row-selecting model the cell's row follows the Tab and stays as the anchor after Escape, where Enter edits it again. The guard is gone, and two arms on the public example pin it.
New spec test/playwright/e2e/grid/CellEditingRowModel.spec.mjs (sibling of the six CellEditing*.spec.mjs); the fixture's gridDriver.mjs gains the runtime model switch, so no existing witness's fixture default changes. The guide's "Starting an Edit" names the rule per model family.
a selected row and no selected cell: edits that row's record (last-edit column, else first editable), scrolled into sight
neither a cell nor a row selected: starts nothing
Grids guide, "Starting an Edit"
e2e arms, red on dev
an edit under a row-selecting model (RowModel, CellRowModel, CellColumnRowModel)
CellEditing#onEnterKey re-select for cell models
the edited record's row is selected from the start of the edit, and grid.View fires select for it
—
"Ending an Edit"
e2e arms: ArrowDown after a commit selects the next record; "Cell & Row" on the public example
Decision Record impact
none (aligned with D#17832's active-target principle).
Acceptance Criteria
Under RowModel, Enter and F2 on a selected row each start an edit on that record; with no selected row nothing starts and no error is logged.
The column is the last edit's while still editable, else the record's first editable one; a target outside the mounted column window is scrolled into sight and embodied, focused.
After Enter, Escape, and a Tab that ends the edit at an end of the store (witnessed: Shift+Tab before the first cell) under RowModel, the edited record's row is selected, and ArrowDown selects the next record — also for an edit started by double-click.
Under a model that selects cells and rows, Tab into the next record selects its cell and its row, and a double-click edit ended by Escape keeps its row selected.
The existing grid e2e and component arms stay green.
The new arms are red on dev and mutation-pinned; --repeat-each=20 clean.
The Grids guide states the keyboard rule, with every behavioural claim mapped to an arm.
Out of Scope
Changing RowModel's click-toggle itself (a double-click deselecting the row it lands on).
Type-to-replace activation (D#17832 keeps it outside the first epic).
Adding RowModel to the public example's radio group.
Avoided Traps
Forcing a cell-selecting model whenever cellEditing is on: it overrides an app's selection contract to fix an activation path.
Documenting the precondition only: the default configuration would stay keyboard-inaccessible.
Related
#18762 (epic) · #18861, #18883 (Tab paths this reuses) · #18925 (the previous keyboard-reachability leaf) · D#17832
Live latest-open sweep: checked latest 20 open issues at 2026-09-19T10:32:37Z; no equivalent found.
A2A claim sweep: latest 12 messages (all read-states) at 10:33Z; no overlapping claim.
MC sweep: "grid cellEditing keyboard user cannot start an edit row selection model RowModel Enter F2 selected row no selected cell", 6 results, no prior decision found; KB ticket sweep: only the 2024 table.plugin.CellEditing tickets (#6154, #6164).
Own-assignment sweep: 1 open (#15252), not overlapping.
Origin Session ID: 2c9503fc-beef-4d80-939b-7d616601cd97
Retrieval Hint: "RowModel keyboard activation cell editing active target last edit column"
Context
Leaf of #18762.
RowModelis the grid's default selection model (learn/guides/datahandling/Grids.md, "Selection Models"). WithcellEditing: trueand that default, a keyboard user cannot start an edit at all, and after a pointer-started edit the arrow keys lose their place. Measured in real Chromium (Playwright e2e rig, dev@7db03e862c), not derived.The Problem
Fixture
test/playwright/component/apps/grid-cell-editing, grid#grid-cell-editing-pooled,view.selectionModelswitched toRowModelat runtime:c3c3(control)So under the default model the feature is pointer-only (WCAG 2.1.1), and a committed edit on row 250 sends the next ArrowDown to row 2.
The public example hides this:
examples/grid/cellEditingoffers only the four cell-selecting models. The guide says "Enter or F2 edits the selected cell" and never names the precondition.Source authority: D#17832's interaction convergence — "double-click, F2 and Enter activate an editable active target" and "Selection is neither necessary nor sufficient across Row/Cell selection models". The shipped keyboard path takes its target from the cell selection alone.
The Architectural Reality
src/grid/plugin/CellEditing.mjs#editSelectedCell(:178–184) readsview.selectedCells[0];grid.View#selectedCells(src/grid/View.mjs:137) returns[]for a model withoutselectsCells. Enter and F2 on the View both route there.#onEnterKey(:388–404) re-selects the edited cell after a commit only whenselectionModel.selectsCells; a row-only model gets no anchor back.src/selection/grid/RowModel.mjs:75: with no selected row the nav keys start fromstore.getAt(0).RowModel#onRowClick).startEdit(record, dataField, true)+view.scrollByRows/scrollByColumns, the Tab path in#onTabKey) already embodies an edit whose cell is outside the mounted window.The Fix
In
src/grid/plugin/CellEditing.mjs:editInSight, for both).startEditselects the edited record's row when it is not selected, so every end (Enter, Escape, Tab past either end) leaves it selected.Scope amendment (2026-09-19, measured while implementing): rule 2 was first scoped to models that select rows and no cells. A probe on the public example under "Cell & Row" falsified that guard: today Tab into the next record selects the cell and leaves no row selected, and a double-click edit ended by Escape leaves nothing selected; with the rule applied to every row-selecting model the cell's row follows the Tab and stays as the anchor after Escape, where Enter edits it again. The guard is gone, and two arms on the public example pin it.
New spec
test/playwright/e2e/grid/CellEditingRowModel.spec.mjs(sibling of the sixCellEditing*.spec.mjs); the fixture'sgridDriver.mjsgains the runtime model switch, so no existing witness's fixture default changes. The guide's "Starting an Edit" names the rule per model family.Contract Ledger
grid.ViewwithcellEditingCellEditing#editSelectedCellRowModel,CellRowModel,CellColumnRowModel)CellEditing#onEnterKeyre-select for cell modelsgrid.Viewfiresselectfor itDecision Record impact
none (aligned with D#17832's active-target principle).
Acceptance Criteria
RowModel, Enter and F2 on a selected row each start an edit on that record; with no selected row nothing starts and no error is logged.RowModel, the edited record's row is selected, and ArrowDown selects the next record — also for an edit started by double-click.--repeat-each=20clean.Out of Scope
RowModel's click-toggle itself (a double-click deselecting the row it lands on).RowModelto the public example's radio group.Avoided Traps
cellEditingis on: it overrides an app's selection contract to fix an activation path.Related
#18762 (epic) · #18861, #18883 (Tab paths this reuses) · #18925 (the previous keyboard-reachability leaf) · D#17832
Live latest-open sweep: checked latest 20 open issues at 2026-09-19T10:32:37Z; no equivalent found. A2A claim sweep: latest 12 messages (all read-states) at 10:33Z; no overlapping claim. MC sweep: "grid cellEditing keyboard user cannot start an edit row selection model RowModel Enter F2 selected row no selected cell", 6 results, no prior decision found; KB ticket sweep: only the 2024
table.plugin.CellEditingtickets (#6154,#6164). Own-assignment sweep: 1 open (#15252), not overlapping.Origin Session ID: 2c9503fc-beef-4d80-939b-7d616601cd97 Retrieval Hint: "RowModel keyboard activation cell editing active target last edit column"