Skip to content

fix(a11y-tabs): improve a11y compliance of the tabs component [AC-4742] - #1407

Open
Stefan3002 wants to merge 1 commit into
canonical:mainfrom
Stefan3002:tabs-a11y-fixes
Open

fix(a11y-tabs): improve a11y compliance of the tabs component [AC-4742]#1407
Stefan3002 wants to merge 1 commit into
canonical:mainfrom
Stefan3002:tabs-a11y-fixes

Conversation

@Stefan3002

@Stefan3002 Stefan3002 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Done

  • According to this, the tabs component must implement a roving tabIndex.
  • This PR just sets up the base for further a11y work that will be done by the consumer of the react-components library, but, we still need to say that the
      element is the "tablist" as users can't do that from the outside.
    • Also, the content of the
    • has also a role of "tab"
    • The
    • should be removed from a11y engines, as they sit in-between the "tablist" and the "tab". The realtion between the two MUST be parent-child.

    Note: Here, you can see: "Until implementations include sufficient support for role="none", web authors are advised to use the presentation role alone role="presentation" or redundantly as a fallback to the none role role="none presentation"."

    QA

    Check that the three changes adhere to this guideline.

    Fixes

    Fixes: #AC-4742

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Updates the Tabs component’s rendered markup to better align with the WAI-ARIA Tabs pattern by introducing explicit ARIA roles so that consumers can build on top of a more semantically-correct baseline.

Changes:

  • Adds role="tablist" to the tabs <ul>.
  • Removes <li> from the accessibility tree via a presentational role.
  • Adds role="tab" to the link/component rendered inside each list item.
Comments suppressed due to low confidence (1)

src/components/Tabs/Tabs.tsx:79

  • role="tab" introduces the ARIA Tabs pattern, but the component does not currently implement the roving tabIndex that the APG requires for keyboard navigation. Also, if active is omitted, aria-selected is not set at all. Consider defaulting aria-selected to a boolean and setting tabIndex based on active so that only the selected tab is tabbable.
              <Component
                role="tab"
                aria-selected={active}
                className={classNames("p-tabs__link", className)}
                data-testid={`tab-link-${label}`}
                {...rest}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/Tabs/Tabs.tsx

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/components/Tabs/Tabs.tsx:72

  • role must be a single valid ARIA role token. role="none presentation" is invalid and may be ignored by assistive tech; use either none or presentation (they’re synonyms) to remove the <li> from the accessibility tree.
              role="none presentation"

src/components/Tabs/Tabs.tsx:78

  • With role="tab", the element should participate in the roving tabIndex pattern and aria-selected should always be a boolean. Currently aria-selected can be undefined (omitting the attribute) and no tabIndex is set, which is out of alignment with the APG tabs pattern.
              <Component
                role="tab"
                aria-selected={active}
                className={classNames("p-tabs__link", className)}
                data-testid={`tab-link-${label}`}

@edlerd edlerd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks for the fixes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants