fix(a11y): name every select by its visible label, or by an aria-label
Merged
DO
1d ago+108+108+012345678901234567890123456789-86-86-01234567890123456789
Proposed changes (including videos or screenshots)
Follow-up to #43061. Fuselage's Select is now a select-only combobox that a <label htmlFor> names like any other input, so the call sites no longer need workarounds, and the ones that had no name get one.
- Visible label →
htmlFor+id. Selects that sat under aFieldLabelwithouthtmlFor, or that were wired witharia-labelledby, now use<FieldLabel htmlFor={id}>+<Select id={id}>: timestamp picker (Format, Timezone), custom user status, role form, omnichannel analytics, canned responses, queue list, real-time monitoring, chats filters (status and custom fields), SLA policies, room notification preferences, and the onboarding Request trial and Create cloud workspace forms. - No visible label →
aria-label. Threads, Team channels, ABAC rooms, contact history and call history filters, the moderation date range, the color setting editor and the timespan setting unit. aria-controlsremoved from the Threads, Files and Members filters. On a combobox it points at its own listbox, whichSelectalready sets; the search inputs keep theirs.- AutoTranslate: the label pointed at
translate-to, but the select's id waslanguage. - Outgoing webhook event trigger: its hint id went to
aria-descriptioninstead ofaria-describedby, so the hint was never announced.
After this, no Select passes aria-labelledby or aria-controls, and every Select has a name. The few that spread their props (SenderSelect, RecipientSelect, the app logs filters) receive it from their callers.
Issue(s)
ARCH-2588
Follow-up to #43061.
Steps to test or reproduce
- Open a room's Threads, Files or Members list, and a team's Team channels. With a screen reader, or in the browser's accessibility tree, the filter select is announced with a name (Filter, File type, Status) instead of only its value.
- Open Administration → Status and presence, create a custom status, then click the Presence label. The select takes the focus, and it is announced as "Presence".
- In a room, open Auto translate and click Translate to. The language select takes the focus.
- Open Administration → Integrations and create an outgoing integration (
/admin/integrations/new/outgoing). The Event trigger select announces its hint.
Further comments
- No new tests: the changes are accessible-name wiring, and the existing client tests pass. Happy to add some if a reviewer wants them.
- Typecheck is clean for
apps/meteorandonboarding-ui.
🤖 Generated with Claude Code
Summary by CodeRabbit
- Accessibility
- Improved screen-reader names and label associations for selectors across administration, omnichannel, room and team views, call history, timestamp settings, and onboarding forms.
- Corrected how the outgoing webhook event selector references its hint.
- Removed
aria-controlsassociations from select controls in room file, member, and thread views. - Added accessible labels for color-editor and time-unit settings.