Accessibility: keyboard-reachable list rows, translated aria-labels, chart alt text - #55
Open
iamgroot400 wants to merge 2 commits into
Open
iamgroot400 wants to merge 2 commits into
iamgroot400 wants to merge 2 commits into
Conversation
Load starter plan used to hand you one fixed Push/Pull/Legs routine. It now opens a picker with four templates (PPL, Upper/Lower, Full Body, 5x5), each built from the same generic spec -> routines/week mapping in lib/starter.js, so adding another plan later is just a new entry, not new plumbing. Addresses the "additional starter plans" item in CONTRIBUTING.md's good-first-issues list.
…chart alt text Three related gaps, all in how the app talks to assistive tech: - Every clickable list row (<div className="item" onClick=...>, 16 of them across sheets.jsx, Plan/Admin/Library/Workout) was unreachable by keyboard and invisible to screen readers -- a div has no role or tabIndex on its own. Swapped to a real <button> everywhere nothing else was nested inside it; the one exception (Library's exercise row, which holds its own "Plan" button) got role="button" + tabIndex + Enter/Space instead, since a button can't contain another button. - Icon-only buttons across the app (steppers, calendar/week nav, delete/clear) had aria-label="Decrease" etc as raw English literals -- every other user-facing string goes through t(), these didn't, so a screen reader in any of the other 11 languages announced English button names. Wrapped them in t(). Left Admin.jsx's own three untranslated -- that file has no i18n at all by design (admin tool, not the translated user app), so partially translating it would be inconsistent with its existing convention. - LineChart's <svg> had no accessible name at all -- a screen reader got nothing from any chart in the app. Added role="img" with a one-line aria-label (entry count, first value, last value). Heatmap's day cells went from title-only (not reliably read by screen readers) to real buttons with the same summary as an aria-label; empty cells are marked aria-hidden since they carry no information. - Check (the per-set done toggle) gained an optional `label` prop; the workout screen's set checkbox now says "Set 1 done" instead of just "checkbox, not checked". Addresses the "Accessibility passes on the workout and chart screens" item in CONTRIBUTING.md's good-first-issues list.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #43 (uses the starter-plan picker it adds), so this diff includes 834744f until that one merges — only 2c768d8 is new here.
Addresses the "Accessibility passes on the workout and chart screens" item in CONTRIBUTING.md's good-first-issues list. Three related gaps, all in how the app talks to assistive tech:
Unreachable list rows
Every clickable list row (
<div className="item" onClick=...>, 16 of them acrosssheets.jsx, Plan/Admin/Library/Workout) was unreachable by keyboard and invisible to screen readers, a div has no role or tabIndex on its own. Swapped to a real<button>everywhere nothing else was nested inside it; the one exception (Library's exercise row, which holds its own "Plan" button) gotrole="button"+tabIndex+ Enter/Space instead, since a button can't contain another button.Untranslated aria-labels
Icon-only buttons across the app (steppers, calendar/week nav, delete/clear) had
aria-label="Decrease"etc as raw English literals, every other user-facing string goes throught(), these didn't, so a screen reader in any of the other 11 languages announced English button names regardless of the profile's language. Wrapped them int(). Left Admin.jsx's own three untranslated on purpose, that file has no i18n at all (admin tool, not the translated user-facing app), so partially translating it would be inconsistent with its own existing convention.Charts with no accessible name
LineChart's<svg>had no accessible name at all, a screen reader got nothing from any chart in the app (body weight, 1RM, effort, everything under Stats). Addedrole="img"with a one-linearia-label(entry count, first value, last value).Heatmap's day cells went from title-only (not reliably read by screen readers) to real buttons with the same summary as anaria-label; empty cells are markedaria-hiddensince they carry no information.Check(the per-set done toggle) gained an optionallabelprop; the workout screen's set checkbox now says "Set 1 done" instead of just "checkbox, not checked".Test plan
npm test(192 passing)npm run build.itemrow is a real button (ordiv[role=button]for the one with a nested button) with a meaningful accessible name from its own text; logged a body weight entry and confirmed the chart'saria-labelreads "70 kg, one entry"; confirmed the Library "Plan" button'sstopPropagationstill works standalone inside the newdiv[role=button]row