Skip to content

fix: add radiogroup ARIA semantics to ColorPicker#350

Merged
leotrs merged 4 commits intomainfrom
std-vped
Mar 27, 2026
Merged

fix: add radiogroup ARIA semantics to ColorPicker#350
leotrs merged 4 commits intomainfrom
std-vped

Conversation

@leotrs
Copy link
Copy Markdown
Collaborator

@leotrs leotrs commented Mar 27, 2026

Summary

  • Adds role="radiogroup" with aria-label to the ColorPicker container
  • Each swatch now has role="radio", aria-checked, aria-label, and roving tabindex
  • Arrow key navigation (Left/Right/Up/Down) with wrapping for radiogroup keyboard pattern
  • Changed inner <button> to <span> since the div[role="radio"] handles all interaction
  • Moved focus-visible styling from circle to swatch (the focusable element)
  • Added 9 new ARIA-specific tests; updated 1 existing test for new markup

Fixes WCAG 4.1.2 (Name, Role, Value) — screen readers now announce color swatches as a radio group with checked state.

Test plan

  • All 14 ColorPicker unit tests pass
  • workspace-input-isolation tests updated and pass (1 selector change)
  • Full frontend suite: 148/154 pass (6 pre-existing failures unrelated to this change)
  • CI validates full suite

🤖 Generated with Claude Code

leotrs and others added 2 commits March 27, 2026 12:12
Swatches now use role=radiogroup/radio with aria-checked, aria-label,
roving tabindex, and arrow-key navigation for WCAG 4.1.2 compliance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 27, 2026

Deploy Preview for rsm-studio-frontend ready!

Name Link
🔨 Latest commit 5d0f5c9
🔍 Latest deploy log https://app.netlify.com/projects/rsm-studio-frontend/deploys/69c67d4599a4f6000998f800
😎 Deploy Preview https://deploy-preview-350--rsm-studio-frontend.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 27, 2026

Deploy Preview for rsm-studio-site canceled.

Name Link
🔨 Latest commit 5d0f5c9
🔍 Latest deploy log https://app.netlify.com/projects/rsm-studio-site/deploys/69c67d4587aa34000843e640

@leotrs
Copy link
Copy Markdown
Collaborator Author

leotrs commented Mar 27, 2026

Needs human review

What changed: ColorPicker now uses ARIA radiogroup semantics — swatches are role="radio" with arrow-key navigation, roving tabindex, and aria-checked state. The inner <button> was replaced with a <span>, and focus-visible styling moved from the circle to the swatch div.

Review checklist:

  1. Open the deploy preview: https://deploy-preview-350--rsm-studio-frontend.netlify.app
  2. Navigate to any view that uses the ColorPicker (e.g., annotation color selection in the workspace)
  3. Tab to the color picker — verify the focus ring appears on the swatch (not the inner circle)
  4. Press ArrowRight/ArrowDown — verify selection moves to the next color and wraps at the end
  5. Press ArrowLeft/ArrowUp — verify selection moves backward and wraps at the beginning
  6. Press Enter or Space on a swatch — verify it selects that color
  7. Click a swatch — verify it still works as before
  8. Test with a screen reader (VoiceOver: Cmd+F5) — verify it announces "Color, radio group" and each swatch as "red, radio button, checked/unchecked"

What to look for:

  • Focus ring is visible and correctly positioned on the swatch, not clipped
  • Arrow key navigation wraps correctly in both directions
  • No double-focus or ghost focus states
  • The removed <button> doesn't break any click/tap behavior on mobile
  • Screen reader announces checked state correctly when switching colors

@leotrs
Copy link
Copy Markdown
Collaborator Author

leotrs commented Mar 27, 2026

All steps worked EXCEPT for 4-5.

leotrs and others added 2 commits March 27, 2026 13:51
Arrow key handler updated activeColor but never called .focus() on the
new element, so keyboard navigation appeared broken in the browser.
Added focus management and a sequential navigation test.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Collaborator Author

leotrs commented Mar 27, 2026

Needs human review

What changed: ColorPicker now uses ARIA radiogroup semantics — swatches are announced as radio buttons with checked state, and arrow key navigation replaces tab-between-buttons interaction.

Review checklist:

  1. Open the deploy preview: https://deploy-preview-350--rsm-studio-frontend.netlify.app
  2. Navigate to any view that uses the ColorPicker (e.g., annotation color selection in the workspace)
  3. Tab to the color picker — verify only one swatch receives focus (roving tabindex)
  4. Use Arrow Right/Down to move forward through swatches; verify selection changes and wraps from last to first
  5. Use Arrow Left/Up to move backward; verify wrapping from first to last
  6. Press Enter or Space on a swatch — verify it selects the color
  7. Click a swatch with the mouse — verify it still works as before
  8. If available, test with VoiceOver (Cmd+F5 on macOS): navigate to the picker and verify it announces "Color, radio group" and each swatch as "red, radio button, not checked" / "green, radio button, checked" etc.

What to look for:

  • Focus ring (2px blue outline) appears on the swatch div, not the inner circle
  • No double focus rings or missing focus indicators
  • Arrow keys don't scroll the page while navigating swatches
  • Active/selected state styling still matches the previous appearance
  • The inner <button> was changed to <span> — verify no visual regression on the color circle

@leotrs leotrs merged commit a1c98f9 into main Mar 27, 2026
18 checks passed
@leotrs leotrs deleted the std-vped branch March 27, 2026 13:07
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