Selector's trigger has no accessible name, and its role changes with hasSearch
- Dominant language
- TypeScript
- Stars
- 13.1k
- Forks
- 1.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 687
Description
### Summary
`Selector`'s trigger button has no accessible name, and the markup it renders differs depending on `hasSearch` in a way that makes it impossible to target by role in either case.
Verified against `@astryxdesign/core@0.1.8` in Chromium, with `label` supplied through the component's own prop.
### What renders
Two `Selector`s on the same page, both given a `label`. Read off the trigger ``:
| `hasSearch` | `role` | `aria-label` | `aria-labelledby` | text content |
| --- | --- | --- | --- | --- |
| absent | `combobox` | `null` | `null` | the placeholder |
| `true` | *(none)* | `null` | `null` | the placeholder |
### Why each is a problem
**Without `hasSearch`** the trigger is ``. `combobox` is not a name-from-content role, so the placeholder text does **not** name it, and with no `aria-label` or `aria-labelledby` the accessible name computes to empty. A screen reader announces "collapsed, combobox" with no indication of which field it is. The visible `label` is rendered as a sibling element that is not associated with the control.
**With `hasSearch`** the same component renders a plain `` with no role. That is name-from-content, so it does get a name — but the name is the **placeholder** ("Select a branch…"), not the `label`. Better than empty, still not the field's name, and it also loses the `combobox` role that conveys the control's behaviour.
### Expected
The value passed to `label` should name the trigger in both shapes — via `aria-labelledby` pointing at the rendered label, or `aria-label` when the label is visually hidden — and the role should not depend on whether a search box is enabled.
### Impact
On a form of several `Selector`s, every one announces identically. It also means neither `getByRole('button', { name })` nor `getByRole('combobox', { name })` matches the trigger, so automated tests and any assistive-tech user hit the same wall: consumers end up adding their own `data-*` hook to locate it, which does nothing for screen-reader users.
### Reproduction
```tsx
```
Inspect either trigger: no `aria-label`, no `aria-labelledby`. Compare the `role` attribute between the two.
Contributor guide
Research direction
Start by reproducing the two Selector examples from the issue and inspecting the rendered trigger with and without hasSearch. Trace the Selector implementation to the label and trigger markup, then verify that the label names the trigger in both shapes and that the trigger exposes the same intended role.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- accessibility, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100