Skip to content

Accessibility: keyboard-reachable list rows, translated aria-labels, chart alt text - #55

Open
iamgroot400 wants to merge 2 commits into
arvids-unavailable:mainfrom
iamgroot400:accessibility-list-rows-and-labels
Open

iamgroot400 wants to merge 2 commits into
arvids-unavailable:mainfrom
iamgroot400:accessibility-list-rows-and-labels

Conversation

@iamgroot400

Copy link
Copy Markdown

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 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.

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 through t(), 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 in t(). 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). 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".

Test plan

  • npm test (192 passing)
  • npm run build
  • Clicked through in a dev browser: loaded a starter plan, confirmed every .item row is a real button (or div[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's aria-label reads "70 kg, one entry"; confirmed the Library "Plan" button's stopPropagation still works standalone inside the new div[role=button] row

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant