Four of the composite widgets handle no keys at all. grep -l 'keydown\|ArrowDown\|key ===' packages/components/src/**/*.stx:
| handles keys | handles none |
|---|---|
Accordion, Tabs, RadioGroup, Dialog, Drawer, CommandPalette, Sidebar, TwoFactorChallenge, Card, DateRangePicker | Dropdown, Listbox, Combobox, Popover |
Select is a native <select>, so the browser handles it — not a gap.
Each of the four opens its panel on click and offers no way to reach what's inside, or to dismiss it, without a pointer. That is WCAG 2.1.1 (Keyboard), and for Listbox/Combobox it also means the one piece of state a user is there to change is pointer-only.
What APG asks for, per widget:
Popover— smallest gap. The trigger is a real<button>, so Enter/Space already work; it needs Escape to close and focus returned to the trigger.DialogandDraweralready do exactly this (Drawer.stx:147), so there is a pattern in-tree to copy.Dropdown(menu button →role="menu") — ArrowDown/ArrowUp to move betweenmenuitems, Home/End, Enter/Space to activate, Escape to close, and ArrowDown on the closed trigger should open it and focus the first item.Listbox— ArrowDown/Up to move the selection, Home/End, Enter/Space to commit, Escape to cancel, and ideally printable-character type-ahead.Combobox— ArrowDown from the input moves into the list without taking focus off the input, Enter commits, Escape closes. This one additionally needsaria-activedescendant, which is deliberately absent today precisely because there is no navigation to track: see the note inCombobox.stxand the test asserting its absence indisclosure-expanded-state.test.ts.
Found while giving those four their aria-expanded / aria-controls (cd52f36 and its two siblings). That work made the state announceable; it did not make the widgets operable, and the two are independent. Filing rather than folding it in because keyboard navigation is a feature-sized change per widget, with focus management and aria-activedescendant to get right, not a missing attribute.
Worth doing as four separate changes, smallest first — Popover's Escape is a handful of lines and the in-tree pattern already exists.