Repository navigation
fix(apollo-react): expose stage pill tooltips to keyboard and screen readers [MST-12262] [MST-12339] - #1581
fix(apollo-react): expose stage pill tooltips to keyboard and screen readers [MST-12262] [MST-12339]#1581venkateshcherukuri wants to merge 2 commits into
Conversation
…readers [MST-12262] [MST-12339]
A status pill ("Optional", "Ends case") without an onClick rendered as a
plain span inside CanvasTooltip, so its tooltip only opened on mouse
hover and its text never reached assistive technology. Read-only
canvases, such as case runtime views, render the pills this way.
A pill with a tooltip is now a tab stop: it opens the tooltip on focus
and closes it on blur and Escape. It has no action, so it is exposed as
a named image rather than a button. The tooltip text is also rendered
as visually hidden text right after the pill and is the pill's
aria-describedby target, so screen readers read it in reading order and
on focus without the tooltip being open. Clickable pills keep their
button and gain the same description.
Dependency License Review
License distribution
Excluded packages
|
There was a problem hiding this comment.
🟡 Changes recommended
Outstanding accessibility issues include focusable chips with empty tooltips, duplicated interactive tooltip content, and low-contrast keyboard focus indicators.
3 open issues
What changed in this PR
This PR improves stage status pill accessibility in Apollo React’s canvas, addressing keyboard access and persistent screen-reader descriptions for tooltips.
Changes:
- Makes non-clickable pills with tooltips focusable and adds persistent accessible descriptions to tooltip-bearing pills.
- Adds tests for keyboard tooltip behavior and accessible descriptions.
- Adds runtime pill tooltips to the Execution Status story.
| File | Description |
|---|---|
packages/apollo-react/src/canvas/components/StageNode/StageNodeHeader.integration.test.tsx |
Tests tooltip opening on focus and closing on blur or Escape. |
packages/apollo-react/src/canvas/components/StageNode/StageNode.stories.tsx |
Adds tooltip content to runtime status pills. |
packages/apollo-react/src/canvas/components/StageNode/StageHeaderChips.tsx |
Adds focusability, focus styling, and persistent tooltip descriptions. |
packages/apollo-react/src/canvas/components/StageNode/StageHeaderChips.test.tsx |
Tests tab order and descriptions for clickable and non-clickable pills. |
Review effort: Balanced
| </span> | ||
| ); | ||
| const descriptionId = useId(); | ||
| const describedBy = tooltip ? descriptionId : undefined; |
| aria-describedby={describedBy} | ||
| // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable so keyboard users can open the tooltip. It has no action, so it stays an image rather than a button. | ||
| tabIndex={0} | ||
| className={`${STATUS_BADGE_BASE_CLASS} ${className} focus-visible:outline-2 focus-visible:outline-offset-2`} |
| <span id={descriptionId} className="sr-only"> | ||
| {tooltip} |
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
Storybook visual diffBaseline is the deployed main Storybook, so changes merged to main after this branch was last updated can also appear here. Logs Updated (PT): Nov 13, 2026, 04:42:31 PM |

Summary
A stage status pill ("Optional", "Ends case") that has a tooltip now keeps that tooltip available to every user: keyboard users can reach the pill and open the tooltip, and screen readers get the tooltip text as the pill's description whether or not the tooltip is open.
Issue
Without an
onClick,StageStatusBadgerendered the pill as a plain<span>insideCanvasTooltip. The tooltip opened only on mouse hover, the pill was not in the Tab order, and the tooltip text existed in the DOM only while the tooltip was open, in a portal at the end of the document. Read-only canvases, such as the case runtime views, render the pills this way.Changes
onClickis a tab stop with a visible focus ring. Focus opens the tooltip; blur and Escape close it; hover works as before. The pill has no action, so it is exposed as an image named by its label (role="img",aria-label) rather than a button.aria-describedbytarget, so it is read in reading order and announced on focus without the tooltip being open.Behavior changes for consumers