Skip to content

Conversation

@Nischit-Ekbote
Copy link
Contributor

@Nischit-Ekbote Nischit-Ekbote commented Oct 7, 2025

Fixes screen reader announcing incorrect selected state on non-selected tabs. Added aria-selected attribute to TabButton components to properly communicate tab state to assistive technologies like Windows Narrator.

Closes #32654

What I did

Added aria-selected attribute to TabButton components in the Tabs component to fix accessibility issues where screen readers (Windows Narrator) were announcing incorrect "selected" state on non-selected tabs.

The fix includes:

  • aria-selected={active} - Properly communicates selected state to screen readers

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Manual testing is required for this accessibility fix.

Testing steps:

  1. Run a sandbox: yarn start
  2. Open Storybook in browser (http://localhost:6006)
  3. Enable Windows Narrator (Ctrl + Win + Enter)
  4. Navigate to any story with tabs (e.g., Controls tab)
  5. Press Tab key to navigate to tab buttons
  6. Verify Narrator announces:
    • Active tab: "Controls, tab, selected, 1 of X"
    • Inactive tab: "Interactions, tab, 2 of X" (WITHOUT "selected")

Tested on:

  • OS: Windows 11 (24H2, Build 26407.5000)
  • Browser: Edge 136.0.3240.92
  • Screen Reader: Narrator

Result: ✅ Screen reader now correctly announces selected/not selected state on tabs.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Note: No documentation update needed as this is an internal accessibility fix with no API changes.

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts
  • Make sure this PR contains one of the labels below:
    • bug ✓ (This fixes incorrect screen reader behavior)

Summary by CodeRabbit

  • Accessibility
    • Improved ARIA support in Tabs: the selected state is now correctly announced by screen readers, making it clearer which tab is active.
    • Enhances usability for keyboard and assistive technology users and aligns with accessibility best practices.
    • No changes to visual design or tab interaction; existing behavior remains the same.

yannbf and others added 4 commits September 24, 2025 14:47
Fixes screen reader announcing incorrect selected state on non-selected tabs.
Added aria-selected and tabIndex attributes to TabButton components to properly
communicate tab state to assistive technologies like Windows Narrator.

Fixes storybookjs#32654
fix(a11y): add aria-selected attribute to tab buttons
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

📝 Walkthrough

Walkthrough

Adds aria-selected attribute to TabButton elements in the Tabs component to reflect each tab’s active state. No other behavior changes.

Changes

Cohort / File(s) Summary of changes
Tabs component accessibility
code/core/src/components/components/tabs/tabs.tsx
Add aria-selected={active} to TabButton to mirror active state; onClick and active logic unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~7 minutes

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
code/core/src/components/components/tabs/tabs.tsx (1)

230-230: LGTM! The accessibility fix is correct.

Adding aria-selected={active} properly communicates the selected state to assistive technologies. React automatically converts the boolean value to the string "true" or "false" required by the ARIA spec, so this implementation is correct.

For complete WCAG/ARIA tab pattern compliance, consider also adding aria-controls to link each tab to its corresponding panel:

                  role="tab"
                  aria-selected={active}
+                 aria-controls={`panel-${sanitize(id) ?? indexId}`}
                >

And ensure the corresponding tab panels (rendered in Content) have role="tabpanel" and aria-labelledby attributes. This is a broader enhancement beyond the current fix.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e08667 and 74c6c63.

📒 Files selected for processing (1)
  • code/core/src/components/components/tabs/tabs.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Adhere to ESLint and Prettier rules across all JS/TS source files

Files:

  • code/core/src/components/components/tabs/tabs.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Fix type errors and prefer precise typings instead of using any or suppressions, consistent with strict mode

Files:

  • code/core/src/components/components/tabs/tabs.tsx
🔇 Additional comments (1)
code/core/src/components/components/tabs/tabs.tsx (1)

232-232: Ensure functional title components render correctly
TabsProps.title accepts an FC, but <title/> renders an HTML element; use the component properly:

- {typeof title === 'function' ? <title /> : title}
+ {typeof title === 'function' ? React.createElement(title) : title}

No current Tabs usage passes a function component to title, but this fix is required to support it.

@nx-cloud
Copy link

nx-cloud bot commented Oct 7, 2025

View your CI Pipeline Execution ↗ for commit 9cec261

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 47s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-13 19:20:58 UTC

@Sidnioulz Sidnioulz self-assigned this Oct 10, 2025
@Sidnioulz Sidnioulz changed the title fix(a11y): add aria-selected attribute to tab buttons A11y: Add aria-selected attribute to tab buttons Oct 10, 2025
@Sidnioulz Sidnioulz added bug ci:normal a11y: aria Accessibility issues related to ARIA markup usage labels Oct 10, 2025
Copy link
Member

@Sidnioulz Sidnioulz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution @Nischit-Ekbote! I hope to see more to come!

We have a broader fix available in #32458, but I'll go ahead and merge your fix once CI is green, as the other PR will take longer to merge.

If you want to fix more accessibility issues, don't hesitate to browse through https://github.com/orgs/storybookjs/projects/23/views/1 to see what's not yet fixed on the other PR.

Sidnioulz and others added 3 commits October 10, 2025 12:53
@Sidnioulz Sidnioulz changed the base branch from next to 10.1 October 20, 2025 08:06
@Sidnioulz Sidnioulz merged commit b924a0c into storybookjs:10.1 Oct 20, 2025
52 of 53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a11y: aria Accessibility issues related to ARIA markup usage bug ci:normal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Screen reader announces incorrect state as selected on non-selected tab controls in windows.

4 participants