Context
Leaf of #18762 (responsibility 2, the interaction contract). Measured while filing #18907 and recorded there only as an out-of-scope note; a finding inside another ticket's footnote orphans, so it gets its own leaf.
The Problem
Measured, e2e probe on the public example examples/grid/cellEditing, Date column, real Chromium: with the editor open and the picker closed, ArrowDown opens nothing, Alt+ArrowDown opens nothing, and Enter — the only key form.field.Picker maps to "open" — is the grid's commit (since #18911 it no longer even builds the picker). A keyboard user can type a date into the type="date" input, and cannot reach the date picker at all. A Time editor has the same key map (Enter, Escape), so the same gap — derived, not measured. A pointer user has the trigger.
Outside a grid the same fields open on Enter, so this is a gap of the grid's editing contract, not of the fields.
The Architectural Reality
src/form/field/Picker.mjs: keys: {Enter: 'onKeyDownEnter', Escape: 'onKeyDownEscape'}. ComboBox replaces the map with {Down: 'onKeyDownDown', Escape} and opens on ArrowDown — keys is a plain config, a subclass map replaces the base map.
src/form/field/Date.mjs: inputType: 'date' — the browser steps the focused segment on plain ArrowUp / ArrowDown, so plain ArrowDown is taken.
util.KeyNavigation matches by key name only; its handlers do receive the event data, and main.DomEvents#getKeyboardEventData carries altKey / ctrlKey / metaKey / shiftKey.
- While an editor has focus the grid's models ignore the arrow keys (
selection.grid.BaseModel#hasEditorFocus), so an editor-level arrow handler does not fight grid navigation.
- The native side:
resources/scss/src/form/field/Date.scss hides ::-webkit-calendar-picker-indicator, and nothing cancels Chromium's own Alt+ArrowDown on a date input. Whether the NATIVE picker opens there in a headed browser is unverified (headless shows nothing either way).
main.DomEvents#registerPreventDefaultKeys({id, keys}) (#18892) cancels a key's default and still delivers it — by key name, without modifiers.
The Fix
Recommendation: Alt+ArrowDown opens the picker — the key the WAI-ARIA date-picker and combobox patterns name — in form.field.Picker, for every picker field, inside and outside a grid:
Picker maps Down and acts only when data.altKey is set and the picker is closed; it claims the key (data.cancelBubble, as onKeyDownEscape does).
- The main thread cancels that combination's default on the field's input, so a native date popup cannot open beside Neo's picker:
registerPreventDefaultKeys learns modifiers ({key: 'ArrowDown', altKey: true}), registered by the field while it is mounted.
- From there the existing contract carries on: focus moves into the picker, Enter on a day picks it, Escape closes the picker first and cancels second, Enter in the input commits.
The alternative, F4, is what desktop grids use and needs no modifier support — but it is not what a screen-reader user expects from a combobox.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
form.field.Picker key map (Down + altKey) |
src/form/field/Picker.mjs; precedent ComboBox#onKeyDownDown |
Alt+ArrowDown opens a closed picker and claims the key |
plain ArrowDown untouched (native segment stepping, ComboBox's own handler) |
class docblock |
e2e arm |
main.DomEvents#registerPreventDefaultKeys |
src/main/DomEvents.mjs (#18892) |
an entry may name modifiers; a bare key name keeps today's meaning |
— |
method docblock |
e2e focus/value trail + the existing suspended-Tab arms stay green |
Decision Record impact
none
Acceptance Criteria
Out of Scope
- What Enter means while the picker is open and focus is in the input (today the grid commits).
- The Grids guide (#18866) states the gap until this lands.
Avoided Traps
- Plain ArrowDown for every picker. On
type="date" and type="time" it is the browser's own segment stepping.
- Giving Enter back to the field inside a grid. A closed Date editor could then never be committed by Enter (#18907's trap).
Related
#18762 · #18907 / PR #18911 · #18883 / PR #18892 (the registry) · #18838 / PR #18852 (the picker belongs to its field's component tree)
Live latest-open sweep: checked the latest 20 open issues at 2026-09-18T16:45Z plus an all-state search (picker / keyboard / ArrowDown / grid editor); nearest is #18907 (Enter), which names this gap as out of scope. A2A sweep (latest 12, all read-states): no claim. Memory Core sweep (picker editor Enter / keyboard): only my own 09-18 measurements. Own open assignments: #18923, #15252 — no overlap.
unowned-rationale: fully specified and with a key decision an Opus seat can settle on the code; filed late on a Friday so the contract hole is on the map. The registry it extends is mine (#18892) — I take it next session if it is still open.
Origin Session ID: 323cb989-06a2-4b3f-8d70-912d67796c11
Retrieval Hint: "keyboard open date picker grid editor Alt ArrowDown preventDefaultKeys modifiers"
Context
Leaf of #18762 (responsibility 2, the interaction contract). Measured while filing #18907 and recorded there only as an out-of-scope note; a finding inside another ticket's footnote orphans, so it gets its own leaf.
The Problem
Measured, e2e probe on the public example
examples/grid/cellEditing, Date column, real Chromium: with the editor open and the picker closed, ArrowDown opens nothing, Alt+ArrowDown opens nothing, and Enter — the only keyform.field.Pickermaps to "open" — is the grid's commit (since #18911 it no longer even builds the picker). A keyboard user can type a date into thetype="date"input, and cannot reach the date picker at all. A Time editor has the same key map (Enter,Escape), so the same gap — derived, not measured. A pointer user has the trigger.Outside a grid the same fields open on Enter, so this is a gap of the grid's editing contract, not of the fields.
The Architectural Reality
src/form/field/Picker.mjs:keys: {Enter: 'onKeyDownEnter', Escape: 'onKeyDownEscape'}.ComboBoxreplaces the map with{Down: 'onKeyDownDown', Escape}and opens on ArrowDown —keysis a plain config, a subclass map replaces the base map.src/form/field/Date.mjs:inputType: 'date'— the browser steps the focused segment on plain ArrowUp / ArrowDown, so plain ArrowDown is taken.util.KeyNavigationmatches by key name only; its handlers do receive the event data, andmain.DomEvents#getKeyboardEventDatacarriesaltKey/ctrlKey/metaKey/shiftKey.selection.grid.BaseModel#hasEditorFocus), so an editor-level arrow handler does not fight grid navigation.resources/scss/src/form/field/Date.scsshides::-webkit-calendar-picker-indicator, and nothing cancels Chromium's own Alt+ArrowDown on a date input. Whether the NATIVE picker opens there in a headed browser is unverified (headless shows nothing either way).main.DomEvents#registerPreventDefaultKeys({id, keys})(#18892) cancels a key's default and still delivers it — by key name, without modifiers.The Fix
Recommendation: Alt+ArrowDown opens the picker — the key the WAI-ARIA date-picker and combobox patterns name — in
form.field.Picker, for every picker field, inside and outside a grid:PickermapsDownand acts only whendata.altKeyis set and the picker is closed; it claims the key (data.cancelBubble, asonKeyDownEscapedoes).registerPreventDefaultKeyslearns modifiers ({key: 'ArrowDown', altKey: true}), registered by the field while it is mounted.The alternative, F4, is what desktop grids use and needs no modifier support — but it is not what a screen-reader user expects from a combobox.
Contract Ledger Matrix
form.field.Pickerkey map (Down+altKey)src/form/field/Picker.mjs; precedentComboBox#onKeyDownDownmain.DomEvents#registerPreventDefaultKeyssrc/main/DomEvents.mjs(#18892)Decision Record impact
none
Acceptance Criteria
dev.date:arms stay green.Out of Scope
Avoided Traps
type="date"andtype="time"it is the browser's own segment stepping.Related
#18762 · #18907 / PR #18911 · #18883 / PR #18892 (the registry) · #18838 / PR #18852 (the picker belongs to its field's component tree)
Live latest-open sweep: checked the latest 20 open issues at 2026-09-18T16:45Z plus an all-state search (picker / keyboard / ArrowDown / grid editor); nearest is #18907 (Enter), which names this gap as out of scope. A2A sweep (latest 12, all read-states): no claim. Memory Core sweep (picker editor Enter / keyboard): only my own 09-18 measurements. Own open assignments: #18923, #15252 — no overlap.
unowned-rationale: fully specified and with a key decision an Opus seat can settle on the code; filed late on a Friday so the contract hole is on the map. The registry it extends is mine (#18892) — I take it next session if it is still open.
Origin Session ID: 323cb989-06a2-4b3f-8d70-912d67796c11
Retrieval Hint: "keyboard open date picker grid editor Alt ArrowDown preventDefaultKeys modifiers"