Picker menu — accessibility
Keyboard
- The trigger is supplied by the caller; it must be a
buttonso Enter/Space fire the click that the anchor span handles. A non-focusable trigger (div, span) makes the menu mouse-only. - Open menu: focus stays on the trigger; Tab walks the
menuitemradiobuttons; Enter or Space picks and closes. - No arrow navigation, Home/End or type-ahead; no focus trap.
- Esc closes (window
keydownin<Popover>); scrimmousedown, scroll of an anchor scroll-parent and resize close as well; scrolling inside the panel does not. disabledonly removes the anchor's click handler — the caller must also disable the trigger button.
ARIA
- Shell:
role="menu"witharia-label={header}— the name is invisible by design (no eyebrow in menus). - Rows:
button[role="menuitemradio"]+aria-checkedfor the current value; icons (<Icon>) arearia-hidden;.stagedotis a colour-only span — the stage name is in.nm, so colour is not the only cue. - The accessible name is the row's
name(orariaLabel); the full name is also the row'stitle— no grey trailing tag (owner 28 Sep 2026, ACRM-375–377). - The trigger must carry
aria-haspopup="menu"andaria-expanded={open}itself (Nav select does; a bespoke trigger has to add them). - No
aria-controlsfrom trigger to menu.
Focus
- Trigger and rows use the foundation ring
outline: 2px solid var(--accent); outline-offset: 1px(button,[role='menuitemradio']). - Focus is not moved into the menu on open and not restored to the trigger on pick or Esc (the row unmounts →
body).
Contrast
Computed from packages/ui/src/tokens/tokens.css:
- Row name
--ink-900on--surface-100= 17.59:1 (light), 14.53:1 (dark); on hover--hover-surface17.0:1 / 13.09:1. - Icon slot
--fg-secondary= 3.93:1 (light) / 6.2:1 (dark) — non-text, passes 3:1. - Tag
--fg-muted11px = 2.85:1 (light) / 3.63:1 (dark) — below AA 4.5:1. - Check
--accent= 4.44:1 (light) / 3.83:1 (dark). - Danger row
--critical#e5484d on white = 3.91:1 (light) — below AA for 13px text; 4.35:1 (dark); on--critical-subtle#ffebeb hover ≈ 3.4:1. - Disabled row
opacity: 0.4≈ 2.6:1 (light). - Stage dot 9px: colour from
var(--ic-*)— not a text element; the name carries the meaning.
Known limits
- Menu keyboard support is Tab-only; focus is neither trapped nor restored.
- Trigger a11y attributes depend on the caller (render prop).
- Tag (11px
--fg-muted) and danger text are below AA 4.5:1 in light theme. disableddoes not disable the trigger visually or for assistive tech.
Source: docs/select/picker-menu.a11y.md · GitLab