Skip to content

[WC-3404]: Fix tooltip accessibility for screenreader - #2175

Open
HedwigAR wants to merge 7 commits into
mainfrom
AT-239/tooltip-accessibility-improvement-screenreader
Open

HedwigAR wants to merge 7 commits into
mainfrom
AT-239/tooltip-accessibility-improvement-screenreader

Conversation

@HedwigAR

@HedwigAR HedwigAR commented Apr 16, 2026 •

Copy link
Copy Markdown
Contributor

Pull request type

Bug fix (non-breaking change which fixes an issue)


Description

Screen reader users who tab to an interactive tooltip trigger hear nothing, because tooltip content is only in the DOM while open, and the aria-describedby from Floating UI sits on the non-focusable trigger wrapper (WC-3404).

This PR:

  • Keeps one content element in the DOM. It is visually hidden and inert while closed, and shown as the tooltip while open.
  • Adds its id to aria-describedby on focusable trigger elements, keeping existing values.
  • Uses a MutationObserver to cover late-mounted elements and attribute resets.
  • Uses the selected render method to decide whether content exists.
  • Skips aria-describedby handling in the Studio Pro preview.

I took over this PR from the original author. Since their last update, I rebased it on main, addressed the AI review comments, replaced the single hidden copy approach with one content element, and replaced AGENTS.md with OpenSpec changes in openspec/changes/.

Behavior change to review: custom content widgets now mount at page load instead of on first open, because a description needs content in the DOM. Data widgets inside a tooltip load earlier as a result.

Out of scope: default Hover mode still does not open on keyboard focus, which differs from the Deque tooltip pattern. This needs a separate ticket.

What should be covered while testing?

Unit tests and lint pass locally. Manual QA:

  • Tooltip opens, closes and positions as before in all Open on modes
  • VoiceOver and NVDA announce text and custom content on focus, with the tooltip closed and open
  • Custom content with a data-loading widget: one request and no duplicate ids
  • Custom content with a link or button: closed content takes no focus, open content is usable
  • Studio Pro preview shows one custom content drop zone
  • Validation message on an input inside the trigger stays announced
  • Trigger shown later through conditional visibility is announced

@HedwigAR
HedwigAR requested a review from a team as a code owner April 16, 2026 11:17
@HedwigAR
HedwigAR force-pushed the AT-239/tooltip-accessibility-improvement-screenreader branch from f727c6f to 1d9f4e3 Compare April 24, 2026 09:24
@HedwigAR HedwigAR changed the title [AT-239] Fix tooltip accessibility for screenreader [WC-3404]: Fix tooltip accessibility for screenreader Apr 24, 2026
@yordan-st
yordan-st force-pushed the AT-239/tooltip-accessibility-improvement-screenreader branch from 0a73e2d to 14f6b5a Compare November 2, 2026 15:50
@github-actions

This comment has been minimized.

@yordan-st yordan-st self-assigned this Nov 2, 2026
@github-actions

This comment has been minimized.

@yordan-st
yordan-st force-pushed the AT-239/tooltip-accessibility-improvement-screenreader branch from e333f0a to 77324f9 Compare November 4, 2026 10:45
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

AI Code Review

✅ Approved — no issues found


What was reviewed

File Change
tooltip-web/src/components/Tooltip.tsx Keeps one content element in the DOM (visually hidden and inert while closed). Adds its id to aria-describedby on focusable trigger elements through a MutationObserver, with cleanup on unmount.
tooltip-web/src/ui/Tooltip.scss Adds a widget-tooltip-sr-only visually-hidden class.
tooltip-web/src/components/__tests__/Tooltip.spec.tsx and snapshot Tests and snapshot updated for the new behavior.
tooltip-web/CHANGELOG.md ### Fixed entry under [Unreleased], in user-facing wording.
tooltip-web/openspec/changes/* Two OpenSpec changes, placed per-package as required.

Skipped (out of scope): none.

CI: pending: Plan E2E matrix, Run code quality check, sigridci · unrelated failures: security/snyk (external scanner, not tied to this diff)


Questions

  • The PR description says custom content widgets now mount at page load instead of on first open. Is that acceptable for data widgets inside tooltips? Each one now loads data up front. The changelog entry doesn't mention it, so consider adding a line if you consider it user-visible.

Positives

  • The MutationObserver is disconnected on cleanup, and the cleanup restores the original aria-describedby values.
  • The observer callback only writes when the id is missing, so it can't loop on its own mutations.
  • The changelog entry is user-facing, and the widget's behavior is covered by new tests.

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