Skip to content

feat(desktop): keyboard shortcuts cheatsheet + a11y landmarks / focus#3125

Closed
HUQIANTAO wants to merge 1 commit into
esengine:main-v2from
HUQIANTAO:feat/a11y-pass
Closed

feat(desktop): keyboard shortcuts cheatsheet + a11y landmarks / focus#3125
HUQIANTAO wants to merge 1 commit into
esengine:main-v2from
HUQIANTAO:feat/a11y-pass

Conversation

@HUQIANTAO

Copy link
Copy Markdown
Contributor

Three related improvements to make the desktop app reachable from the keyboard and readable by screen readers.

  1. Shortcuts cheatsheet (press ?). New component renders a kbd+description table, grouped by section. Triggered by a '?' keypress from anywhere outside an editable element, or from a Help icon in the topbar. role=dialog + aria-modal; focus moves to close button on open, returns to trigger on close.
  2. ARIA landmarks + labels. App.tsx's // get role=banner / role=main / role=contentinfo, every icon-only topbar button gets an explicit aria-label, the error banner is role=alert, the composer textarea gets id+aria-label so a skip-link can target it.
  3. Skip-to-composer link. The first Tab from the topbar lands on a visually-hidden link that jumps focus to the textarea.
  4. Focus rings. :focus-visible paints a 2px accent outline with a 2px offset.

@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jun 4, 2026
Three related improvements to make the desktop app reachable from the
keyboard and readable by screen readers.

1. Shortcuts cheatsheet (press ?). New component
   components/ShortcutsCheatsheet.tsx renders a single-column
   kbd+description table, grouped by section (Composer / Transcript /
   Global). Triggered by a '?' keypress from anywhere outside an
   editable element, or from a Help icon in the topbar. The dialog is
   role=dialog + aria-modal + aria-labelledby; on open, focus moves to
   the close button; on close, focus returns to the trigger.

2. ARIA landmarks + labels. App.tsx's <header>/<main>/<footer> get
   role=banner / role=main / role=contentinfo, and every icon-only
   topbar button gets an explicit aria-label. The error banner is
   role=alert. The composer textarea gets id=composer-input +
   aria-label so a skip-link can target it. The status-bar model name
   is aria-live=polite so a model switch is announced.

3. Skip-to-composer link. The first Tab from the topbar lands on a
   visually-hidden link that, when activated, jumps focus to the
   textarea. Saves keyboard-only users from tabbing through every
   topbar chip on every reload.

4. Focus rings. :focus-visible paints a 2px accent outline with a 2px
   offset across every interactive element. Disabled buttons skip the
   ring (it's not actionable). :focus (without -visible) is reset
   globally so the OS-default ring on mouse-clicks doesn't double up
   with the WebKitGTK focus rectangle on Linux.

i18n: en + zh both gain a 'shortcuts' section (title, close, open,
section.*, desc.*).
@esengine

esengine commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Thanks! This conflicts with the latest main-v2 in styles.css (other desktop PRs have since landed there). Could you rebase onto the latest main-v2? Happy to merge once green. Thank you!

@esengine esengine left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking finding: the component is never mounted — the diff adds ShortcutsCheatsheet.tsx, locales, and CSS, but no App.tsx wiring, so the "?" keybind and help entry don't exist and this ships as dead code. Three more for the same revision:

  1. Keep the DictKey typing instead of t: (id: string) => string — the dynamic "shortcuts.desc." + id lookups silently render raw keys on any typo.
  2. The shortcut table predates the keybinding unification: Shift+Tab now only toggles Plan, Ctrl+Y toggles YOLO. Sync the content.
  3. Rebase (styles.css moved substantially).

@SivanCola

Copy link
Copy Markdown
Collaborator

Thanks @HUQIANTAO for the shortcuts cheatsheet and accessibility work here.

I integrated this direction into #4515 on top of the latest main-v2. The new PR mounts the shortcuts sheet, keeps typed locale keys, renders the sheet from the shared shortcut registry so it stays in sync with custom bindings, and includes the skip-to-composer accessibility link.

Authorship note: @HUQIANTAO remains the primary author of the shortcuts help/a11y direction. @SivanCola contributed as a collaborator by integrating it with the current shortcut registry, folding in the related settings direction from #4202, and verifying the final state.

Closing this PR as superseded by #4515.

@SivanCola SivanCola closed this Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants