Skip to content

fix(ui): keyboard a11y for the reply preview strip#211

Merged
sanity merged 1 commit intomainfrom
fix-210-reply-a11y
Apr 13, 2026
Merged

fix(ui): keyboard a11y for the reply preview strip#211
sanity merged 1 commit intomainfrom
fix-210-reply-a11y

Conversation

@sanity
Copy link
Copy Markdown
Contributor

@sanity sanity commented Apr 13, 2026

Problem

The quoted-reply preview at the top of a reply message (.reply-strip) had cursor-pointer and an onclick handler but was otherwise a plain <div>: no tabindex, no role, no key handler, and the hover-expand CSS only matched :hover. Keyboard users could neither reach it nor activate it, and they never saw the full preview text. PR #209 (the layout fix for #205/#206/#207) called this gap out and filed it as a follow-up.

Approach

Make the reply strip a proper button affordance:

  • role="button", tabindex="0", aria-label so screen readers announce it and Tab navigation reaches it.
  • onkeydown handler for Enter and Space that runs the same scroll-to-original logic as the existing onclick (Space calls preventDefault() so the page doesn't scroll).
  • A new .reply-strip:focus-visible CSS rule outside the (hover: hover) media query so it applies on all devices — mobile keyboard users (e.g. external Bluetooth keyboards on phones) are covered too. The rule expands the preview and adds a visible outline.

Testing

New Playwright tests in ui/tests/message-layout.spec.ts:

  1. ARIA contractrole, tabindex, aria-label are all present; the strip accepts focus.
  2. Focus-visible rule exists — walks the live stylesheet and asserts a .reply-strip:focus-visible rule is shipped. (Testing the computed style under actual keyboard focus is unreliable in headless browsers because :focus-visible is modality-dependent.)
  3. Enter-key activation — focus the strip, press Enter, assert the target message gets the reply-highlight class.

Full suite: 92 passed, 3 skipped (the pre-existing mobile-hover skips from PR #209).

Delegate / contract WASM

UI-only: ui/assets/main.css, ui/src/components/conversation.rs, ui/tests/message-layout.spec.ts. No delegate/contract/common touched, no migration entry required.

Fixes

Closes #210.

[AI-assisted - Claude]

The quoted-reply preview at the top of a reply message had cursor-pointer
and an onclick handler but was otherwise a plain div: no tabindex, no
role, no key handler, and the hover-expand CSS only matched `:hover`.
Keyboard users could neither reach it nor activate it, and they never
saw the full preview text.

Make the strip a proper button affordance:
- role="button", tabindex="0", aria-label
- onkeydown handler for Enter and Space that runs the same scroll-to-
  original logic as onclick (Space calls preventDefault so the page
  doesn't scroll)
- new `.reply-strip:focus-visible` CSS rule (outside the hover/pointer
  media query so it applies on touch devices too) that expands the
  preview and adds a visible outline

Playwright regression tests cover: ARIA attributes, focusability,
presence of the :focus-visible rule in the shipped stylesheet, and
Enter-key activation of the scroll-to-original handler. 92 passed,
3 pre-existing mobile-hover skips.

Closes #210.

[AI-assisted - Claude]
@sanity sanity merged commit 2eeee88 into main Apr 13, 2026
3 checks passed
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.

a11y: reply strip needs keyboard focus affordance to expand/activate

1 participant