A Screen Reader Storybook addon for accessibility testing
npm install storybook-screen-reader
A screen reader simulation addon for Storybook that helps developers test accessibility during component development. It uses industry-standard libraries to provide accurate accessible name computation and role announcements.
- π― W3C AccName Spec - Uses dom-accessibility-api for accurate accessible name computation
- π·οΈ ARIA Role Detection - Uses aria-query for proper role mapping
- π Voice Reader - Uses Web Speech API to announce focused elements
- π Text Reader - Displays announcements in the addon panel
- π― Focus Tracking - Automatically tracks focus changes (Tab, arrow keys, clicks)
- π’ Live Regions - Announces aria-live region updates
- π Deep Shadow DOM Support - Traverses into shadow roots to find the actual focused element (like real screen readers)
- π¨ Spectrum Web Components UI - Built with Lit + SWC for the addon panel
- π Story Navigation - Automatically resets when switching between stories
---
| Feature | This Plugin | VoiceOver (macOS) | Notes |
|---------|:-----------:|:-----------------:|-------|
| Accessible Name Computation | β
W3C AccName spec | β
Native | We use dom-accessibility-api which implements the full W3C spec |
| Accessible Description | β
aria-describedby | β
Native | Full support via dom-accessibility-api |
| ARIA Roles | β
40+ roles | β
All roles | We use aria-query for accurate role detection |
| Focus Tracking | β
focusin event | β
Native | Tracks Tab, Shift+Tab, clicks |
| Shadow DOM Traversal | β
Deep active element | β
Native | Finds actual focused element inside shadow roots |
| Arrow Key Navigation | β
aria-activedescendant | β
Native | For menus, listboxes, trees |
| Live Regions | β
aria-live | β
Native | Announces dynamic content changes |
| Form States | β
required, invalid, readonly | β
Native | Comprehensive form feedback |
| Button States | β
pressed, expanded | β
Native | Toggle buttons, accordions |
| List Position | β
"Item X of Y" | β
Native | Lists, tabs, options |
| Table Navigation | β οΈ Basic | β
Full | We announce row/column counts |
| Checkbox States | β
checked, mixed, unchecked | β
Native | Tri-state support |
| Slider Values | β
value, min, max, valuetext | β
Native | Full range announcements |
| Virtual Buffer Mode | β Not supported | β
Native | NVDA/JAWS feature, not VoiceOver |
| Reading All Content | β Focus-only | β
Browse mode | We only announce focused elements |
| OS Integration | β Browser only | β
System-wide | VoiceOver works across all apps |
| Braille Output | β Not supported | β
Native | Hardware requirement |
| Category | Supported Features |
|----------|-------------------|
| Roles | button, link, checkbox, radio, switch, textbox, searchbox, combobox, listbox, slider, spinbutton, heading, img, listitem, option, menuitem, tab, tabpanel, navigation, main, banner, contentinfo, complementary, region, article, form, search, dialog, alertdialog, alert, status, log, progressbar, meter, tooltip, tree, treeitem, grid, table, menu, menubar, toolbar, group, separator |
| States | checked, pressed, expanded, selected, invalid, required, readonly, disabled |
| Properties | aria-label, aria-labelledby, aria-describedby, aria-valuenow, aria-valuemin, aria-valuemax, aria-valuetext, aria-level, aria-activedescendant, aria-modal |
| Live Regions | aria-live (polite/assertive), role="alert", role="status", role="log" |
---
| Use Case | Reliability | Recommendation |
|----------|:-----------:|----------------|
| Quick dev feedback | β
High | Great for catching obvious issues |
| ARIA role verification | β
High | Accurate role mapping via aria-query |
| Accessible name testing | β
High | W3C spec via dom-accessibility-api |
| Focus order testing | β
High | Reliable focus tracking |
| Live region testing | β
Medium | Basic support, may miss edge cases |
| Full WCAG compliance | β οΈ Medium | Use with real screen readers |
| Production sign-off | β Low | Always test with VoiceOver/NVDA |
```
1. π οΈ Development β Use this plugin (instant feedback)
2. π Code Review β Use axe-core / Storybook a11y addon
3. β
QA Testing β Use REAL VoiceOver / NVDA
4. π₯ User Testing β Involve actual screen reader users
---
`bash`
npm install storybook-screen-reader
or
`bash`
yarn add storybook-screen-reader
Add the addon to your .storybook/main.js:
`js`
module.exports = {
addons: [
// ... other addons
'storybook-screen-reader',
],
};
1. Open Storybook and navigate to any story
2. Click the "Screen Reader" tab in the addons panel
3. Enable Voice Reader and/or Text Reader
4. Navigate through your component:
- Tab / Shift+Tab - Move between focusable elements
- Arrow keys - Navigate within menus, listboxes, etc.
- Click - Focus any element
The addon will announce each focused element with its role, name, and state.
| Element | Announcement |
|---------|-------------|
| Button | "Button, Submit. Press Space or Enter to activate." |
| Toggle Button | "Button, Dark mode, pressed. Press Space or Enter to activate." |
| Link | "Link, Learn more. Press Enter to follow." |
| Checkbox | "Checkbox, Accept terms, not checked. Press Space to toggle." |
| Radio | "Radio button, Option A, selected." |
| Switch | "Switch, Notifications, on. Press Space to toggle." |
| Text Field | "Text field, Email, required. Empty." |
| Invalid Field | "Text field, Password, required, invalid entry. Contains: **" |
| Slider | "Slider, Volume. Value: 75. Range: 0 to 100." |
| Heading | "Heading level 2, Welcome" |
| Tab | "Tab, Settings, selected. 2 of 4." |
| List Item | "Home. List item 1 of 5." |
| Menu Item | "Menu item, Copy" |
| Dialog | "Modal Dialog, Confirm deletion" |
| Alert | "Alert: Your session will expire in 5 minutes" |
| Progress | "Progress bar, Uploading. 45 percent" |
| Table | "Table, User data. 10 rows, 4 columns." |
---
| Library | Purpose |
|---------|---------|
| dom-accessibility-api | W3C Accessible Name and Description computation |aria-query
| | ARIA role definitions and element-to-role mapping |lit
| | Web component framework for addon panel |@spectrum-web-components
| | Adobe Spectrum design system components |
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Storybook Manager β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β screen-reader-panel (Lit + SWC) β β
β β βββ Toggle switches for voice/text output β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Storybook Preview (iframe) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β ScreenReader class β β
β β βββ Focus tracking (focusin event) β β
β β βββ ARIA attribute monitoring (MutationObserver) β β
β β βββ Live region monitoring (MutationObserver) β β
β β βββ Name computation (dom-accessibility-api) β β
β β βββ Role detection (aria-query) β β
β β βββ Speech synthesis (Web Speech API) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
---
This addon is a development aid, not a replacement for testing with real screen readers:
| What We Can't Do | Why |
|------------------|-----|
| Access OS Accessibility Tree | Browser security restrictions |
| Virtual/Browse mode | VoiceOver reads all content, we only track focus |
| Braille output | Hardware requirement |
| System-wide announcements | Browser sandbox |
| 100% VoiceOver parity | Different underlying technology |
Always test with actual assistive technology before shipping:
- VoiceOver (macOS/iOS)
- NVDA (Windows, free)
- JAWS (Windows)
- TalkBack (Android)
---
- Storybook 8.x
- React, Vue, Angular, Web Components, HTML
- Works with Shadow DOM
Issues and PRs welcome! GitHub Repository
Originally created by VΓctor Lara.
Updated and maintained by Tarun Tomar.
MIT