Entity picker — accessibility

Keyboard

  • "Přidat" is a button.add-ref: Tab focuses it, Enter or Space opens the panel; focus moves to the search input on the next animation frame (Record select).
  • Typing searches on the server after MENTION_MIN_QUERY characters (debounce 180 ms).
  • Enter in the search picks the first row (adding mode): the first result, the first recent record (recent), or the typed address (emails, offered first). Nothing is picked while results are loading.
  • Arrow keys, Home and End move between rows (canonical Popover); rows are also Tab stops; Enter or Space picks. The panel stays open after a pick and the search keeps focus (keepOpen); with max reached it closes.
  • Esc closes the panel and, in emails mode, discards a typed address. Click outside closes it and keeps a typed valid address as a token.
  • Removing a token uses its own "×" (Entity reference, focusable).

ARIA

  • Trigger: aria-haspopup="listbox", aria-expanded.
  • Panel = Record select: search input with aria-label (the placeholder); list role="listbox" with aria-label={label} (required even with hideLabel); rows button[role="option"] with aria-selected="false" — picked records leave the list. Adding mode is not multi, so the listbox has no aria-multiselectable; the picked set is the tokens, not the list.
  • Token state (statusOf): the dot carries aria-label = its title, so the invitation state is not colour only.
  • The type mark in a row is decorative; the type name is text in sub.

Focus

  • On close (Esc, outside click, max reached) focus returns to „Přidat“ (DS.RecordRefField, acrm !4502).
  • .add-ref, rows and token "×" use the foundation ring outline: 2px solid var(--accent); outline-offset: 1px.
  • Search input has no ring of its own (Record select).
  • After a pick focus stays in the search (keepOpen).

Contrast

Record select tokens: row name --ink-900 17.59:1 (light) / 14.53:1 (dark); sub --fg-secondary 300 12px (#707477 since 2 Oct 2026) ≥ 4.5:1 (light) / 6.2:1 (dark); hint and empty text --fg-muted 2.85:1 (light) / 3.63:1 (dark). Tokens, the .add-ref pill and state dots are documented with Entity reference.

Known limits

  • The switch from recent records to search results (recent) is visual only — no group name, no live announcement.
  • Hint and empty text use --fg-muted (2.85:1 light) on purpose: supplementary text stays light (owner, 3 Oct 2026); readable text uses --fg-secondary.

Source: docs/select/entity-picker.a11y.md · GitLab