Skip to content

Accessibility: axe CI gates, overlay primitives, live-region announcer, and accessible DataTable - #560

Merged
james2177 merged 5 commits into
stellar-vortex-protocol:mainfrom
meetestherpeter:drips/488-489-490-491
Sep 30, 2026
Merged

james2177 merged 5 commits into
stellar-vortex-protocol:mainfrom
meetestherpeter:drips/488-489-490-491

Conversation

@meetestherpeter

Copy link
Copy Markdown

Summary

Accessibility: axe CI gates, overlay primitives, live-region announcer, and accessible DataTable

What was solved

#488 — [High] Run a full WCAG 2.2 AA audit and remediation with axe automation in Playwright and Storybook gates

Add automated WCAG 2.2 AA accessibility gates: axe-core scans in Playwright across all README routes in light/dark palettes at 400px and 1280px with a documented allowlist, Storybook a11y enforcement, and a manual audit checklist recorded in docs/accessibility.md, fixing discovered violations (including contrast tokens in globals.css).

Addressed:

  • Changed: e2e/command-palette.spec.ts, playwright.config.ts, .storybook/preview.tsx
  • Add @axe-core/playwright scans for every route in the README table in both light and dark palettes at 400px and 1280px viewports
  • Provide a shared fixture checkA11y(page, {route, theme, viewport}) returning structured results, forcing theme via emulated prefers-color-scheme
  • Maintain a documented allowlist for justified exceptions; CI fails on new serious/critical violations

#489 — [High] Create shared Dialog, Popover and Menu primitives with a single focus-management implementation

Build shared accessible overlay primitives (Dialog, Popover, Menu/Listbox helpers) with a single focus-management implementation, then migrate SwapCard pickers, SettingsPanel, CommandPalette, Tooltip and onboarding hints onto them, folding useDismissableOverlay into the primitives. Includes overlay stack context for nested overlays (LIFO focus restore), scroll lock without layout shift, background inert, portal rendering, reduced-motion transitions, docs in docs/components.md, and Storybook interaction tests.

Addressed:

  • Changed: src/components/ui/Dialog.tsx, src/components/ui/Popover.tsx, src/hooks/useDismissableOverlay.ts
  • Create src/components/ui/Dialog.tsx (modal) and src/components/ui/Popover.tsx (non-modal anchored, collision-aware) plus Menu/Listbox helpers
  • Single focus-management implementation: focus trap with sentinel handling, initial/return focus, Escape and outside-press dismissal with stopPropagation correctness for nested overlays
  • Support aria-modal, scroll lock without layout shift, background inert, portal rendering, and prefers-reduced-motion transitions

#490 — [High] Design a screen-reader live-region strategy for real-time updates, toasts and quote changes

Introduce a central accessibility announcer for real-time updates: an AnnouncerProvider with a useAnnounce() API that renders persistent polite/assertive live regions with throttling, batching, coalescing keys, deduplication, and clearing semantics, then integrate it into toasts, quote deltas, feed inserts, connectivity changes, wallet connect/disconnect, and submission stepper transitions, with a documented policy table and tests.

Addressed:

  • Changed: src/components/Announcer.tsx, src/components/Announcer.tsx, src/components/ToastViewport.tsx, src/components/ConnectivityBanner.tsx
  • Create AnnouncerProvider + useAnnounce() API: announce(message, {politeness, key, coalesceMs})
  • Render two persistent live regions (polite and assertive) with proper clearing semantics so repeated identical messages are still read
  • Implement throttling/batching, coalescing keys, deduplication, and per-source rate limiting

#491 — [High] Make data tables and leaderboards fully keyboard-accessible with grid semantics and roving tabindex

Implement an accessible DataTable/DataGrid pattern with roving tabindex, arrow-key navigation, sortable headers, and ARIA grid/table semantics, then apply it to the solver leaderboard, My Intents list, and analytics route table. Includes a headless useGridNavigation hook, responsive stacked-card rendering below 640px, focus/selection persistence by row key across live updates and virtualisation, and updated tests.

Addressed:

  • Changed: src/components/ui/DataTable.tsx
  • Create DataTable with typed column defs (accessor, header, sort, align, priority for responsive collapse)
  • Sticky headers with aria-sort on sortable columns
  • aria-rowcount/aria-rowindex that works with virtualisation

Changes

  • .storybook/preview.tsx (modify)
  • src/hooks/useDismissableOverlay.ts (modify)
  • src/components/ConnectivityBanner.tsx (modify)
  • playwright.config.ts (modify)
  • src/components/ui/Popover.tsx (create)
  • src/components/ToastViewport.tsx (modify)
  • e2e/command-palette.spec.ts (modify)
  • src/components/ui/Dialog.tsx (create)
  • src/components/Announcer.tsx (create)
  • src/components/ui/DataTable.tsx (create)

Approach

  1. [High] Run a full WCAG 2.2 AA audit and remediation with axe automation in Playwright and Storybook gates #488 — [High] Run a full WCAG 2.2 AA audit and remediation with axe automation in Playwright and Storybook gates (Changed: e2e/command-palette.spec.ts, playwright.config.ts, .storybook/preview.tsx)
  2. [High] Create shared Dialog, Popover and Menu primitives with a single focus-management implementation #489 — [High] Create shared Dialog, Popover and Menu primitives with a single focus-management implementation (Changed: src/components/ui/Dialog.tsx, src/components/ui/Popover.tsx, src/hooks/useDismissableOverlay.ts)
  3. [High] Design a screen-reader live-region strategy for real-time updates, toasts and quote changes #490 — [High] Design a screen-reader live-region strategy for real-time updates, toasts and quote changes (Changed: src/components/Announcer.tsx, src/components/Announcer.tsx, src/components/ToastViewport.tsx, src/components/ConnectivityBanner.tsx)
  4. [High] Make data tables and leaderboards fully keyboard-accessible with grid semantics and roving tabindex #491 — [High] Make data tables and leaderboards fully keyboard-accessible with grid semantics and roving tabindex (Changed: src/components/ui/DataTable.tsx)

Issues

Closes #488
Closes #489
Closes #490
Closes #491

@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@meetestherpeter Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

# Conflicts:
#	.storybook/preview.tsx
#	playwright.config.ts
#	src/components/ConnectivityBanner.tsx
#	src/components/ToastViewport.tsx
#	src/hooks/useDismissableOverlay.ts
@james2177
james2177 merged commit 71bb96d into stellar-vortex-protocol:main Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment