Found while working the lifecycle-path readout card in packages/plugin-detail/src/renderers/record-path.tsx. Pre-existing, not introduced by that change, and outside its fence — filing rather than folding it in.
What a screen-reader user gets
record:path distinguishes travelled stages from upcoming ones with colour and a check glyph, and the glyph is aria-hidden:
<span aria-hidden="true" className="... text-emerald-600 ...">✓</span>
{stage.label}
The only programmatic signal on any stage is aria-current="step" on the current one. So a screen-reader user hears a list of six identically-announced items with one marked "current step" — and cannot tell that 草稿 and 审核中 are already behind the record while 已接受 and 已过期 are ahead of it. The same holds for a lost terminal: its ✗ is aria-hidden too, so 已拒绝 announces exactly like an ordinary upcoming stage.
Sighted users get this distinction from colour alone (emerald = travelled, muted = upcoming, destructive = lost terminal), which is WCAG 2.2 SC 1.4.1 Use of Color.
Reproduce
Any object declaring a stageField renders this chrome on its record page. Put the record on a middle stage and read the path with a screen reader, or inspect the accessible tree: the list items' accessible names are the bare stage labels.
Shape of a change
The stage's state needs a text equivalent that reaches the accessible name — e.g. visually-hidden text per stage, or an aria-label composing label + state. Both introduce user-facing strings, so this needs i18n keys rather than the hardcoded English the component currently uses for its container labels; that is why it is its own card rather than a one-line addition.
Related but distinct: #5569 tracks duplication of the approval stepper, a different surface with its own markup.
Context: the readout markup was reworked in claude/issue-5768-inert-lifecycle-path, which de-buttoned the path but deliberately did not move its accessible semantics.
Generated by Claude Code
Generated by Claude Code
Found while working the lifecycle-path readout card in
packages/plugin-detail/src/renderers/record-path.tsx. Pre-existing, not introduced by that change, and outside its fence — filing rather than folding it in.What a screen-reader user gets
record:pathdistinguishes travelled stages from upcoming ones with colour and a check glyph, and the glyph isaria-hidden:The only programmatic signal on any stage is
aria-current="step"on the current one. So a screen-reader user hears a list of six identically-announced items with one marked "current step" — and cannot tell that 草稿 and 审核中 are already behind the record while 已接受 and 已过期 are ahead of it. The same holds for alostterminal: its ✗ isaria-hiddentoo, so 已拒绝 announces exactly like an ordinary upcoming stage.Sighted users get this distinction from colour alone (emerald = travelled, muted = upcoming, destructive = lost terminal), which is WCAG 2.2 SC 1.4.1 Use of Color.
Reproduce
Any object declaring a
stageFieldrenders this chrome on its record page. Put the record on a middle stage and read the path with a screen reader, or inspect the accessible tree: the list items' accessible names are the bare stage labels.Shape of a change
The stage's state needs a text equivalent that reaches the accessible name — e.g. visually-hidden text per stage, or an
aria-labelcomposing label + state. Both introduce user-facing strings, so this needs i18n keys rather than the hardcoded English the component currently uses for its container labels; that is why it is its own card rather than a one-line addition.Related but distinct: #5569 tracks duplication of the approval stepper, a different surface with its own markup.
Context: the readout markup was reworked in
claude/issue-5768-inert-lifecycle-path, which de-buttoned the path but deliberately did not move its accessible semantics.Generated by Claude Code
Generated by Claude Code