[EuiFilterButton] EuiFilterButton should not infer aria-expanded from active filters
- Dominant language
- TypeScript
- Stars
- 6.4k
- Forks
- 911
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 65
Description
**Reported by**
Originally surfaced from Kibana accessibility issue elastic/kibana#227773.
**Describe the bug**
`EuiFilterButton` treats `hasActiveFilters` as a fallback source for `aria-expanded` when it is rendered as a collapsible chevron button:
```ts
const isExpanded = isCollapsible && (isSelected ?? hasActiveFilters);
```
`hasActiveFilters` is a visual/filter-count state, not the disclosure open state. A closed filter popover can still have active filters, so this can leave the trigger exposed to assistive technology as expanded even when the controlled popover is closed, or cause a missing false-to-true announcement the next time the trigger opens.
**Impact and severity**
This affects screen reader users of filter-popover triggers. The Kibana report notes VoiceOver/Safari missing the expanded-state announcement for the Security > Rules > Benchmarks filter buttons. This is WCAG Name, Role, Value related behavior.
**Environment and versions**
- Kibana version: 9.1.0 in the downstream report
- Browser: Safari 18.5
- Screen reader: VoiceOver
- EUI: current `main` still has the `hasActiveFilters` fallback in `packages/eui/src/components/filter_group/filter_button.tsx`
**Minimum reproducible sandbox**
A minimal component-level case is a collapsible `EuiFilterButton` with active filters but no explicit open state:
```tsx
Status
```
The button receives `aria-expanded` even though no open/closed disclosure state was provided.
**To Reproduce**
1. Render `EuiFilterButton` with `iconType="chevronSingleDown"` and `hasActiveFilters`.
2. Do not pass `isSelected`.
3. Inspect the rendered button.
4. Observe that `aria-expanded` is derived from active-filter state.
**Expected behavior**
For collapsible filter buttons, `aria-expanded` should follow the actual disclosure state supplied through `isSelected`. `hasActiveFilters` should continue to affect only active-filter styling and badge semantics. If `isSelected` is omitted, EUI should not infer a disclosure state from active filters.
**Additional context**
I have a small local patch with focused RTL coverage that changes the computed expanded state to use `isSelected` only for collapsible buttons. Happy to open a PR if this scoping looks right.
Contributor guide
Assessment
This issue has not been assessed yet.