Bottom Sheet: keyboard users cannot scroll the sheet body (axe serious)
- Dominant language
- TypeScript
- Stars
- 13.1k
- Forks
- 1.1k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 669
Description
**Bug:** a keyboard user cannot scroll the Bottom Sheet's content when that content has no focusable elements.
The scrolling area has no `tabIndex`, so it never takes focus, so arrow keys and Page Down do nothing. A sheet full of plain text is unreachable by keyboard. A sheet with a button inside is fine — focus lands there and scrolls the area.
axe calls this `scrollable-region-focusable`, severity **serious**.
**How it surfaced.** CI's a11y job audits Storybook stories. No Bottom Sheet story had ever rendered *open*, so nothing was ever checked. A story in PR #5203 did open, and the audit failed immediately. I closed that story to unblock the PR — the bug is older and not from that change.
**The fix is not one line.** Adding `tabIndex={0}` to the scroll body adds a tab stop to *every* sheet, including ones that do not need it. It probably needs to be conditional on the content having no focusable children, which is a runtime check and wants its own review.
**Also worth fixing:** at least one Bottom Sheet story should render open, or CI will keep missing this whole component.
Files: `packages/core/src/BottomSheet/BottomSheetPanel.tsx` (the `styles.body` div).
Rule: https://dequeuniversity.com/rules/axe/4.12/scrollable-region-focusable
Contributor guide
Research direction
Start in packages/core/src/BottomSheet/BottomSheetPanel.tsx, focusing on the styles.body div, and inspect the Bottom Sheet Storybook stories and CI accessibility job. Reproduce an open sheet containing only plain text, then verify keyboard users can scroll its body without unnecessary tab stops. Ensure an open Bottom Sheet story is covered by the axe audit so this regression is detected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- accessibility, frontend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100