feat(a11y): skip link, message-list live region, composer + popup labels (LC-197) #248
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-197-a11y"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
LC-197 a11y polish. High-impact slice from the audit; the full axe/Lighthouse sweep + arrow-key nav map stay open in the ticket as follow-up.
What's in this PR
Skip link.
base.htmlgets a<a href="#main">as the first focusable element in<body>.sr-only focus:not-sr-onlykeeps it invisible until keyboard focus lands on it, then it becomes a positioned button anchored to the top-left. Satisfies WCAG 2.4.1 (Bypass Blocks) on every page that defines#main(the main app pages vialayout.html). Pages without#main(login, register, error) still render the link; it just scroll-jumps to the top of the page, which is harmless.Message-list live region.
room/messages.html's#messagescontainer now carriesrole="log",aria-live="polite",aria-relevant="additions", and a translatedaria-label. Polite over assertive so reading isn't interrupted;additionsonly so deletions / edits don't re-announce (an edited message announcing itself again would be noisy).Composer accessible name. The textarea had full combobox semantics (
role=combobox,aria-controls,aria-haspopup) but no accessible name - the dynamic placeholder doesn't count as a label. Addedaria-label="a11y-composer-message-input"; visible placeholder stays.Status picker dialog role. The popup root went from a generic
<div tabindex="-1">torole="dialog"+ translatedaria-labelso SR users hear "Set status dialog" on open. Existing keyboard escape handler and focus trap are unchanged.Reaction picker
aria-haspopup. The "+" button now matches the other popover triggers (notify dropdown, scheduled / reminder modals) so an SR user knows pressing it opens an overlay.i18n
4 new keys in
en/escommon.ftlunder a new## A11ysection:a11y-skip-to-content,a11y-messages-region-label,a11y-composer-message-input,a11y-status-picker-dialog-label.i18n_catalogparity test still green.Not in this PR (still open under LC-197)
Tests
just test+just test-saasgreen. LC-77 webhook + email-inbox render fixtures regenerated (only delta:aria-haspopup="true"on the reaction "+" button propagates into the message render). i18n catalog parity green.🤖 Generated with Claude Code
LC-189 polish epic, a11y slice. Targeted at the highest-impact gaps the audit surfaced; the broad axe/Lighthouse sweep + arrow-key map are out of scope for this commit and stay in LC-197 as follow-up. base.html: a `<a href="#main">` skip link as the first focusable element in the body, with `sr-only focus:not-sr-only` so it's invisible until keyboard focus lands on it (the WCAG 2.4.1 bypass-blocks pattern). Pages without #main (login etc.) still satisfy the requirement on every page that does. room/messages.html: `#messages` now carries `role="log"`, `aria-live="polite"`, `aria-relevant="additions"`, and `aria-label="a11y-messages-region-label"`. New OOB-appended messages are announced once via the live region; deletions/edits are suppressed (which is intentional - re-announcing an edited message would be noisy for SR users). room/composer.html: textarea gains an `aria-label` (translated). The placeholder is dynamic ("Message #room-name") and didn't survive as a label for SR users; the visible placeholder stays. status/picker.html: popup root gains `role="dialog"` + translated `aria-label` so SR users hear "Set status dialog" when the picker opens (it was a generic <div>). partials/reaction_bar.html: reaction "+" button gains `aria-haspopup="true"` to advertise the popover semantics consistent with the other picker triggers (notify dropdown, scheduled modal). i18n: 4 new keys in en/es common.ftl under an a11y section (skip link, messages region label, composer label, status picker dialog label). LC-77 webhook + email-inbox render fixtures regenerated to pick up the reaction-bar `aria-haspopup` attr (no other change). just test + just test-saas green; i18n_catalog parity green. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>