Skip to content

Bugfix - NUI-6283: [a11y] role="tab" elements do not have aria-controls pointing to their panel, etc. (WCAG 4.1.2) - #897

Merged
ludmilaFialova merged 24 commits into
solarwinds:release/v20.0.xfrom
kubeska:bugfix/NUI-6283-a11y-incorrect-aria-controls-on-tab-elements
Sep 22, 2026
Merged

ludmilaFialova merged 24 commits into
solarwinds:release/v20.0.xfrom
kubeska:bugfix/NUI-6283-a11y-incorrect-aria-controls-on-tab-elements

Conversation

@kubeska

@kubeska kubeska commented Aug 12, 2026 •

Copy link
Copy Markdown

Frontend Pull Request Description

This PR improves the accessibility of the tab and tab-panel relationship across the @nova-ui/bits library. The main change is to ensure that tab and panel elements have properly aligned IDs and ARIA attributes. This includes updates to both the implementation and the demos, as well as the addition of tests to verify the correct associations.

Accessibility Improvement:

  • Tab and tab-panel elements now use consistent, accessible IDs (tab-{id} for tabs and panel-{id} for panels), and the ARIA attributes aria-controls and aria-labelledby are set accordingly in both TabComponent and TabHeadingComponent. This ensures screen readers and assistive technologies can correctly associate tabs with their panels.

Code:

  • The tab ID and panel ID prefixes are defined as constants in tabgroup.constants.ts and used throughout the codebase for consistency.
  • Automatic unique ID generation is provided for tabs and headings when an explicit ID is not supplied, ensuring all tabs/panels have valid, unique identifiers.

Documentation:

  • The changelog has been updated to reflect the accessibility fix for tab and tab-panel ID alignment.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have updated change log
  • I have been following Definition of done
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new lint warnings
  • New and existing unit tests pass locally and on CI with my changes
  • Any dependent changes have been merged and published in downstream modules

Screenshots (if applicable)

Additional Context (if necessary)

The PR includes the following main changes:

  • Added correct ARIA relationships between tabs and panels:

    • role="tab", role="tablist", and role="tabpanel
    • aria-controls on tabs
    • aria-labelledby on panels
    • Consistent tab-* and panel-* ID generation
    • Shared constants for ID prefixes
  • Extended Tab, TabHeading, TabGroup, and TabHeadingGroup:

    • Added tabId support
    • Added ariaControls support
    • Added ariaLabel support for tabs without a text label
    • Correct handling of aria-selected, aria-disabled, and tabindex
  • Implemented APG keyboard navigation:

    • Arrow keys for moving between tabs
    • Home and End for moving to the first or last enabled tab
    • Enter and Space for activation
    • Roving tabindex
    • Support for both horizontal and vertical orientation
  • Improved focus and disabled-tab handling:

    • Disabled tabs are skipped correctly
    • The active tab is selected correctly during initialization and updates
    • Lifecycle cleanup logic was added or corrected
  • Improved Switch accessibility:

    • Corrected the public id placement
    • Added accessible naming through projected label content
    • Added ariaLabel support
    • Added a localized fallback accessible name, Switch
    • Added Enter and Space keyboard activation
  • Updated demo examples:

    • Corrected ARIA bindings in routed tab examples
    • Removed duplicate IDs
    • Fixed active-tab synchronization when removing the last tab in the list
    • Updated tab and switch documentation
  • Expanded test coverage:

    • Unit tests for ARIA attributes, IDs, focus, disabled state, and keyboard navigation
    • E2E tests for tabs, routed tabs, and switches
    • Coverage for cleanup and edge cases
  • Updated the changelog, package versions, and related repository formatting settings.

@kubeska
kubeska marked this pull request as ready for review August 12, 2026 16:21
ludmilaFialova
ludmilaFialova previously approved these changes Aug 19, 2026
@ludmilaFialova
ludmilaFialova force-pushed the bugfix/NUI-6283-a11y-incorrect-aria-controls-on-tab-elements branch from 19243df to 14b5b21 Compare September 1, 2026 21:21
ludmilaFialova
ludmilaFialova previously approved these changes Sep 4, 2026
@ludmilaFialova
ludmilaFialova force-pushed the bugfix/NUI-6283-a11y-incorrect-aria-controls-on-tab-elements branch from ffd3916 to 8c7ef4c Compare September 7, 2026 15:21
@ludmilaFialova
ludmilaFialova force-pushed the bugfix/NUI-6283-a11y-incorrect-aria-controls-on-tab-elements branch from 8c7ef4c to 102f369 Compare September 17, 2026 17:34
Comment thread .gitattributes
autocrlf=false
eol=lf
* text=auto
* text=auto eol=lf

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.

The .gitattributes file was updated to enforce consistent LF line endings across the repository.
This prevents Windows-specific CRLF conversions from causing unnecessary diffs and Prettier or CI failures. It ensures that all developers and CI use the same line-ending format.

pavlo-poimanov
pavlo-poimanov previously approved these changes Sep 21, 2026
kubeska and others added 18 commits September 21, 2026 14:10
- Implement roving tabindex so only active tab is in tab sequence
- Add ArrowLeft / ArrowRight / ArrowUp / ArrowDown navigation
- Add Home / End keys support to jump to first / last enabled tab
- Add aria-orientation attribute to vertical tablists
- Expose aria-disabled on disabled tabs
- Add unit and e2e test coverage for keyboard interactions
- Make active tabpanels focusable with tabindex=0

- Keep inactive tabpanels out of the tab sequence

- Cover Tab navigation into tabpanels

- Test arrow wrap-around and disabled tab handling

- Add vertical ArrowUp and ArrowDown coverage
- Add ariaLabel input to TabHeadingComponent and bind to role=tab

- Provide accessible name for Settings tab in router demo

- Add aria-controls to all tabs referencing shared routed panel

- Update unit tests and Playwright test suite
Add accessible names to icon-only tabs, fix prefixed active-tab bindings, and scope force-click behavior to the disabled-tab test.
Handle Enter activation for switch controls and add unit and e2e regression coverage.
ludmilaFialova and others added 6 commits September 21, 2026 14:15
Keep public ids on nui-switch hosts, provide fallback labels for unlabeled switches, and add accessible names to chart demo switches.
Restore keyboard activation for routed tabs, add edge-case coverage for disabled tabs and generated IDs, and strengthen switch and tab accessibility assertions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ludmilaFialova
ludmilaFialova force-pushed the bugfix/NUI-6283-a11y-incorrect-aria-controls-on-tab-elements branch from 102f369 to de948e1 Compare September 21, 2026 12:18
@ludmilaFialova
ludmilaFialova merged commit 142288d into solarwinds:release/v20.0.x Sep 22, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants