Skip to content

a11y: screen-reader data for dashboard charts, non-color status cues, plus next build repair - #338

Open
rudra496 wants to merge 3 commits into
MergeFi:mainfrom
rudra496:feat/a11y-charts-badges
Open

a11y: screen-reader data for dashboard charts, non-color status cues, plus next build repair#338
rudra496 wants to merge 3 commits into
MergeFi:mainfrom
rudra496:feat/a11y-charts-badges

Conversation

@rudra496

Copy link
Copy Markdown

Fixes #15
Fixes #49

What changed

#15 — charts were invisible to screen readers

  • BarChart: bars are visual-only divs whose only value reveal was a hover title — unreachable for keyboards and screen readers. Now wrapped in a <figure> with a visually-hidden caption list announcing every label: value pair (formatValue-aware, so the dashboards announce real currency figures); the bar layer is aria-hidden so nothing gets double-announced. Visual output unchanged.
  • Sparkline: unlabeled SVG → role=img with a computed trend summary ("Trend from 10 to 42 (320% increase)"), plus a decorative opt-out. StatCard uses the opt-out since its trend line already announces the same movement as text — no duplicate announcements.
  • New BarChart.test.tsx (4 cases) and Sparkline.test.tsx (6 cases).

#49 — status color audit + non-color cues

Audited the live mapping in Badge.tsx (not the speculation in the issue — the real palettes):

  • funded (sky) vs paid (emerald): both read as positive at a glance, but mean escrowed vs released — the exact confusion the issue warns about.
  • refunded vs open: near-identical slate tones (600 vs 700 on the same bg/ring) — a real confusable pair the issue didn't even call out.
  • Fix: each status carries a fixed lucide glyph (Lock=escrowed, Banknote=released, Undo2=refunded, …) as a non-color cue — hue-independent under any color-vision deficiency. Palette untouched; aria-hidden icons since the label text renders anyway. Difficulty badges keep text+hue (4 well-separated hues, visible text labels).

Bonus — next build has been broken on main

42fc033 introduced logout: jest.fn as a type annotation (TS2749); tsc --noEmit fails and next build dies at type-check for every fresh clone. One-line ReturnType<typeof jest.fn> repair included so this PR leaves the repo buildable.

Verification

  • npx jest: 269 passing on this branch vs 252 on current main; the 7 remaining failures are in pre-existing failing suites (WalletContext, ConnectPanel, NetworkBadge, Tabs, AuthContext, BountyCard) that fail identically without my changes — none touch Badge/BarChart/Sparkline/StatCard (46/46 there).
  • npx tsc --noEmit: clean (was failing on main).
  • npm run build: succeeds (was failing on main).
  • eslint on all touched files: clean.

Honest scope note: WCAG contrast of the existing Tailwind pairings (50/700 light, /10 + -300 dark) passes AA by inspection and is unchanged by this PR; the colorblind-safety argument here rests on the cues no longer depending on hue at all. I don't have a screen-reader rig in this environment, so the SR behavior is covered by the RTL assertions rather than a manual VoiceOver pass.

BarChart's hover-only titles and Sparkline's unlabeled SVG left the
dashboards' financial data unreachable for screen-reader users. BarChart
now wraps its bars in a figure with a visually-hidden caption list
announcing every label:value pair (formatValue-aware), with the visual
layer marked aria-hidden; Sparkline announces a computed trend summary
via role=img, with a decorative opt-out used by StatCard where the
trend percentage is already announced as text. Visual output unchanged.
Hue alone can't carry eight financial states: funded and paid both read
as the good-green at a glance while meaning escrowed vs released, and
refunded/open share near-identical slate tones. Each status now carries
a fixed lucide glyph (aria-hidden, since the label text renders anyway)
as a non-color cue; palette untouched. Difficulty badges keep their
text-plus-hue encoding.
42fc033 used jest.fn as a type annotation, failing tsc under
noUnusedLocals-strict settings (TS2749) and with it the whole
next build. Wrap in ReturnType<typeof jest.fn>.
Copilot AI lite review requested due to automatic review settings August 27, 2026 21:45
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

@rudra496 is attempting to deploy a commit to the chonilius' projects Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants