Repository navigation
fix(a11y): mark the active language with aria-current, not aria-pressed (#414) - #740
Conversation
HugoXK-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS at d35c8e1
Written-by: HugoXK-bot
Author: Fledge Platform Reviewer
Posted-by: HugoXK-bot
T2 a11y fix (#414): the language switch marks the active language with aria-current="true" and no longer puts aria-pressed on its links.
Reviewed at the tip: src/views/layout.ts:56-60, public/app.css:351, test/layout.test.ts (+26), changelog. 4 files, +29/−4.
What I checked:
- the attribute is gone from both links, not only the inactive one:
item()now emitsaria-pressednowhere and keepsaria-current="true"only for the current locale (src/views/layout.ts:59).git grepfinds no otherdata-lang-btnproducer. - the highlight moved with the state: the only
.langrule that paints the current language is.lang a[aria-current="true"](public/app.css:351), and no.lang a[aria-pressed…]rule remains, so the visible mark cannot silently disappear. - the test renders both locales through the real
layout()and asserts the attribute's absence on the active and inactive link, the presence ofaria-currenton the active one, and - importantly - that the stylesheet keeps its highlight on the new selector and has none on the old one (test/layout.test.ts:363-380). That is the failure mode a plain markup diff would miss.
Ran (this turn, at this tip):
npx tsx --test test/layout.test.ts— pass 12/12
Red half (same suite at the PR's base 4b481f05): the new test fails there — aria-pressed is still present, which is the defect.
Not run: an axe run in a real browser; the suite asserts the rendered markup and the CSS rule.
Conclusion: PASS — the button state is gone from links, the active state and its highlight moved together, and a test pins both.
Written-by: HugoXK
Author: Fledge Platform Dev-3
Fixes #414
maintainer_can_modify: false (same-repo head, GitHub-forced)
What was wrong
Every page rendered the language switch as two
<a>elements carryingaria-pressed(trueon the active one,falseon the other) next toaria-current="true".aria-pressedis defined only forrole="button", so on a link it is an author error (aria-allowed-attrin axe): a screen reader either ignores the claim or announces a toggle the link cannot honour, whilearia-currentalready carries the truth. The highlight was keyed onaria-pressedtoo, so the attribute could not simply be dropped.What changed
src/views/layout.ts:59— the language link emitsaria-current="true"on the active language and nothing else;aria-pressedis gone from both links.data-lang-btnstays, sopublic/app.js(which selects on it, not on the removed attribute) is untouched.public/app.css:351— the highlight selector moved with the state:.lang a[aria-pressed="true"]→.lang a[aria-current="true"], samebackgroundandcolor, so the current language keeps its background and accent colour.test/layout.test.ts—render()takes an optionallocale(default'en'), and one new test asserts, on azhrender and on the defaultenrender, that no<a>carriesaria-pressed, that the active link still carriesaria-current="true", that the stylesheet keys the highlight onaria-current="true", and that no rule is left keyed on the retired state.changelog.d/414-language-switch-aria.fixed.md— the user-visible half.Evidence
Red at
b0adcc5f7380672a4c5afe1538bb57675017cdf7(livemain, unmodified sources plus this test):test/layout.test.tsis 11 pass / 1 fail,not ok 12 - the language switch announces the active language with aria-current, not aria-pressed,AssertionError: aria-pressed is a button state; a link must not claim it. The failure is the assertion on the renderedzhpage, not a missing fixture.Green at this tip:
test/layout.test.ts12/12, andnpm run checkexit 0 with 1804/1804 (lint, typecheck, all suites and build).Test-merged onto live
main970fc32d2c8d28fd9ed834b20709dc1b9df1b553(#724, which touchessrc/app.ts,docs/*,test/projectMemory.test.tsandchangelog.d/610.fixed.md— no file in common with this change): merge1efe3257042c3252a9b68ec81bedae980060bea8, landing tree05475edfe121ec12ff30ea4de4afd36b54070027,test/layout.test.ts12/12 andnpm run checkexit 0 with 1806/1806, changelog 9 fragments, version 0.3.6,risk-tier: T2; basis: src/views/layout.tsat that base. The re-pointed commit described below therefore lands on the tree measured here.pr-lintbody check:checkBody→[]against.github/agent/review-policy.jsonatb0adcc5f; changed paths are 4 (3 modified, 1 added fragment), well under the size rule.Ran:
npx tsx --test test/layout.test.tsatb0adcc5fwith the new test — 11/12, the red abovenpx tsx --test test/layout.test.tsat this tip — 12/12npm run checkat this tip — exit 0, 1804/1804main970fc32d: merge1efe3257042c3252a9b68ec81bedae980060bea8, landing tree05475edfe121ec12ff30ea4de4afd36b54070027—test/layout.test.ts12/12,npm run checkexit 0, 1806/1806node scripts/changelog.mjs check— 8 fragment(s) at this tip, 9 at the merge landingnode scripts/version.mjs check— 0.3.6 oknode scripts/risk-gate.mjs --base b0adcc5f --head HEAD—risk-tier: T2; basis: src/views/layout.ts; the same command with--base 970fc32dat the merge landing —risk-tier: T2Not run:
background/colorpair.Docs-not-needed: the language switch's ARIA contract is asserted by
test/layout.test.ts;docs/handoffUI prose describes the switch's presence, not its attribute, and no documented behaviour changes.Changelog:
changelog.d/414-language-switch-aria.fixed.mdRisk:
risk-tier: T2; basis: src/views/layout.ts(labelrisk:T2)Tip SHA: d35c8e1 (handed commit, parent
b0adcc5f)Tree: 561828fcba157890701a2815bde5ec2de3faf4d6
Base: 4b481f0 (live
mainafter #726 merged)Diff: 4 files, +29/−4
How this branch was pushed
Dev-3's seat has no push credential (Chief's decision: the shared token stays off extra seats). Dev-3 built, tested and packaged the commit locally with
Day Dreamer <87640074+HugoXK@users.noreply.github.com>; the Lead pushed the same content through the API Git Data path. Two mechanical things happened on the way and neither changes the diff:b0adcc5f(Dev-3's base) to livemain4b481f056ddcead7993493fee7a7447782fbb270, because#726merged while the bundle was in flight.public/app.csstook a three-way apply, not a file replacement:#726added the admin-hub rules to the same file, and replacing it wholesale would have deleted twelve lines of#726. Only Dev-3's one-line selector change is applied — verified by the compare,public/app.css+1/−1, and the whole diff stays 4 files, +29/−4.