mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
## What kind of change does this PR introduce?
A11y fix for keyboard focus (esp. Safari), plus a lint rule to keep it
from regressing.
## What is the current behavior?
`Button` already defaults an explicit `tabIndex={0}` (#40458). Other
interactive primitives (Checkbox, bare triggers, etc.) still skip Tab
focus in Safari unless macOS Keyboard navigation is on. Raw `<button>`
call sites have no guardrail.
## What is the new behavior?
- Same explicit `tabIndex` default baked into Checkbox, Accordion
Trigger, Collapsible Trigger, Dropdown Menu / Popover / Dialog / Sheet /
Alert Dialog triggers, Table Head Sort, Command reset, sidebar actions,
and shadcn Button
- `supabase/require-explicit-tabindex` ESLint rule, ratcheted in Studio
(82 existing violations)
- Design-system accessibility docs list which primitives bake this in
Resolves [DEPR-621](https://linear.app/supabase/issue/DEPR-621)
## Additional context
### To test
Use **Safari** with macOS Keyboard navigation **off** (the default).
Chrome once for a sanity pass.
**Storage → Files bucket (list view) — Checkbox**
1. Open an empty folder (or one with only folders). Header “select all”
Checkbox is disabled and skipped by Tab — expected (`columnFiles.length
=== 0`).
2. Upload a file (e.g. an image). Header Checkbox enables.
3. Tab to it and toggle with Space. Row Checkboxes should also be
Tab-reachable.
**Storage → Analytics bucket → bucket details — Accordion Trigger**
On an Analytics bucket with no tables yet, Tab to the “Create your first
table via PyIceberg” Accordion Triggers and open/close with Enter/Space.
**Elsewhere (light smoke)**
- Bare Dropdown / Popover / Collapsible triggers still Tab + activate
- `*Trigger asChild><Button>` (Sheets, Dialogs, menus) still one Tab
stop; open/close fine
- Disabled controls stay out of the Tab order
### Later
Chip-away of the 82 raw Studio buttons (and remove exceptions from
rule). Prefer migrating those to `Button` from `ui` later.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Accessibility Improvements**
* Improved keyboard focus behavior across common interactive controls
(buttons, dialog/popover/dropdown/sheet triggers,
accordions/collapsibles, checkboxes, and sidebar actions).
* Disabled controls now default to `tabIndex={-1}`, while enabled
controls default to `tabIndex={0}`.
* Added explicit `tabIndex` handling for command reset and table sort
header controls.
* **New Features**
* Added a shared `getExplicitTabIndex` utility used by UI components to
standardize focus behavior.
* **Documentation**
* Updated accessibility guidance to clarify which components include
built-in focus/tabIndex handling and which require manual setup.
* **Developer Experience**
* Added an ESLint rule to enforce explicit `tabIndex` on raw button-like
elements, with corresponding baseline updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->