Repository navigation
Conversation
AnimatedNumber renders each digit in reverse DOM order (`row-reverse` puts the visual order back) and every digit carries a 30-cell odometer strip that is only visible while it animates. The strip and the reversed static digits stayed in the accessibility tree, so `12` was read as `2 1`, and a `5` to `6` update exposed `0123456789` three times. The `aria-label` on the root did not replace those children, so it never hid them. Expose the value once as `.sr-only` text and mark the visual layer (digits and strip) `aria-hidden`, so assistive technology reads the current, correctly ordered number in every motion state. Rendering, `row-reverse` ordering and the animation itself are untouched.
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
The fix works. I ran the new story and spec against the base component: 12 was read as 2 1, and during the 5→6 animation the snapshot was the 30-cell strip (0 1 2 3 4 5 6 7 8 9 ×3). With this PR, both states read as a single 12 / 6. Type-checks pass in packages/ui and packages/session-ui, and the session-ui component suite passes apart from one unrelated flaky test that passes alone.
The one consumer, tool-count-label.tsx, didn't depend on the old root aria-label, and .sr-only already exists in utilities.css. The public API is unchanged.
No blocking concerns. This doesn't change the reversed DOM order, so the RTL visual bug in #43643 remains.
Related: #43643
|
Superseded upstream — recording this so it is not read as abandoned.
So the defect this PR was opened for is fixed on I also checked the test half before rebasing, because that was the part that could still have been unique: For completeness I did run this PR's spec against current Leaving this open for a maintainer to close. The branch is untouched at |
|
Superseded upstream: I also carried a Storybook story and a Playwright component test for the behaviour while rebasing. I am dropping them rather than shipping unverified: this environment cannot download a Playwright browser (15 minutes of |
|
Closing as superseded — see the comment above. |
Issue for this PR
Closes #54653
Type of change
What does this PR do?
AnimatedNumberwas unreadable to assistive technology in every state, for two independent reasons.The component renders each digit in reverse DOM order and puts the visual order back with
row-reverse. Thestatic digits therefore sat in the accessibility tree in reverse, so
12was announced as2 1. On top ofthat, every digit carries a 30-cell odometer strip that is only meant to be visible while it animates; the strip
stayed in the tree too, so a
5to6update exposed0123456789three times over.The existing
aria-labelon the root did not replace those children — anaria-labelon a generic element doesnot hide its descendants — so it never silenced either of them.
The fix exposes the value once as
.sr-onlytext and marks the visual layer — the reversed digits and thestrips —
aria-hidden="true". Rendering, therow-reverseordering and the animation itself are untouched, sothe sighted output is byte-for-byte the same.
How did you verify your code works?
packages/session-ui/component-tests/animated-number.spec.tsmounts the story in this PR at a pinned state andasserts the accessibility snapshot is a single reading-ordered value.
reports. The assertion is a one-shot
await loc.ariaSnapshot()compared to a string — deliberately nottoMatchAriaSnapshot(), which retries until it passes and would have gone green on the broken tree as soon asthe animation ended. The test waits on a deterministic precondition (
data-animating="true") before reading.All 136 tests in the
packages/session-uicomponent suite pass.tsgo -bexits 0 andoxlintreports 0 warnings/ 0 errors on the changed files.
A story (
packages/ui/src/components/animated-number.stories.tsx) renders the component so the states can beexplored by hand; it is also what the component test mounts, so the fixture the test measures is the one a
reviewer can click through.
Screenshots / recordings
No response.
Checklist
Added by the opencode bot (AI-generated).
Related: #43643