Skip to content

chore: harden frontend accessibility beyond dropdown navigation #323

Description

@parsakhaz

Intent

Continue the accessibility work started in #319/#320 so Pane’s keyboard-first workflows are consistently operable and understandable with assistive technology. Address the confirmed cross-cutting gaps outside the shared Modal work, and establish automated guardrails that prevent the same classes of regressions from returning.

Scope

  • Replace or repair non-semantic clickable elements so all actions and selectable rows are keyboard-operable and expose the correct native semantics.
  • Bring AboutDialog onto an accessible dialog pattern, including an accessible name, focus entry/containment/restoration, and a labeled close control. Coordinate this with any separate shared Modal improvements rather than duplicating dialog infrastructure.
  • Add appropriate live-region/status announcements for meaningful asynchronous changes such as errors, connection state, progress, and command outcomes. Avoid announcing noisy high-frequency terminal output.
  • Audit custom ARIA widgets (tabs, menus, listboxes, comboboxes, and similar controls) for complete keyboard interaction, focus management, and state semantics rather than ARIA roles alone.
  • Add automated accessibility guardrails to frontend linting and Playwright smoke coverage.
  • Include a rendered manual pass for focus visibility, zoom/reflow, and color contrast across Pane themes; these cannot be established from static source inspection alone.

Starting Points

  • frontend/src/components/Sidebar.tsx: clickable version and Docs spans.
  • frontend/src/components/ExecutionList.tsx: clickable commit rows.
  • frontend/src/components/panels/diff/DiffViewer.tsx: clickable file expansion headers.
  • frontend/src/components/AboutDialog.tsx: bespoke visual overlay without complete dialog semantics or focus management.
  • frontend/src/components/PaneChatView.tsx: tab roles without the complete roving-focus/arrow-key tab interaction model.
  • frontend/eslint.config.js: no JSX accessibility rules.
  • tests/: no automated axe-based accessibility smoke coverage.
  • Search for clickable div/span elements, custom role usage, raw form controls, focus suppression, and status/error UI without aria-live, role="status", or role="alert".

This list is not exhaustive. Treat it as a starting point and investigate the local and remote frontends before implementation.

Acceptance Criteria

  • User actions and selectable rows are reachable and operable with keyboard alone, preferably through native buttons and links rather than emulated controls.
  • AboutDialog follows the project’s accessible dialog contract and returns focus to its opener when closed.
  • Important asynchronous success, error, loading, and connection changes have deliberate, non-noisy assistive-technology announcements.
  • Custom ARIA widgets implement the expected keyboard and focus behavior for their declared roles.
  • Frontend linting catches common JSX accessibility regressions without introducing an untriaged wall of ignored failures.
  • Playwright runs automated accessibility checks over at least Home, Settings, session creation, and one active-session workflow, with documented intentional exceptions.
  • Manual verification covers keyboard-only operation, visible focus, 200% zoom/reflow, and representative contrast across the supported theme families.
  • Existing terminal interaction and global hotkeys continue to work, including while dialogs and composite widgets are active.

Inputs Needed

  • Confirm whether WCAG 2.2 AA is the target baseline.
  • Decide whether accessibility lint rules should be introduced incrementally or enabled repository-wide after the initial remediation.

Notes

The shared Modal component has its own high-impact focus-trap, focus-restoration, and accessible-labeling concerns and should be handled as separate foundational work. This issue should consume that improved contract when available rather than growing a second modal implementation.

Related: #319, #320.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions