Skip to content

feat(ui): keyboard accessibility — focus ring, / search, 1-7 view shortcuts (v1.17 D) - #44

Merged
argszero merged 1 commit into
mainfrom
feat/ui-ue-deep-polish-2-a11y
Aug 17, 2026
Merged

argszero merged 1 commit into
mainfrom
feat/ui-ue-deep-polish-2-a11y

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

Rant 2026-08-17T16:57:17 (UI/UE 多角度深化优化), item D — 键盘可达性 / 无障碍: keyboard Tab navigation should show a clear focus ring, plus global shortcuts (/ to focus the market search, Esc to cancel inline edits, digits 1-7 to switch sidebar views) and aria/title hints on buttons.

Changes

  • :focus-visible global focus ring (previously missing): accent-color outline: 2px + offset for Tab navigation; input controls (.input / .th-filter) already have border-color focus so the outline is suppressed there to avoid double indicators;
  • Global shortcuts (document-level keydown; skipped while typing in input/textarea/select/contenteditable; Cmd/Ctrl/Alt modifiers not hijacked):
    • / → focus market search (#mk-search);
    • digits 1-7 → switch sidebar views via NAV_ORDER (dashboard/marketplace/sharing/wallet/transactions/admin/settings); guest mode falls through to the existing login-prompt toast;
    • Esc → close inline new-Key editor (#ak-new-inline);
  • Nav items: title = "快捷键 N · 名称" + right-side .nav-key kbd badge (omitted on the admin item which already carries the 管理员 tag);
  • Docs: docs/user-stories.md v1.17 changelog adds item D; ui/README.md 键盘可达性约定 section.

Acceptance

Tab navigation shows clear focus ring; / focuses market search; digits 1-7 switch views; Esc cancels inline edit/confirm; buttons have title/aria hints.

Tests

  • node --check on app.js — syntax OK
  • Shortcut smoke test (DOM stub): / focuses #mk-search; digits run without error; digits ignored while typing; Cmd+digit ignored; Esc closes #ak-new-inline — 5/5 PASS
  • DOM-stub init smoke — no ReferenceError
  • cargo test — 1 passed
  • cargo fmt --check — clean

@argszero
argszero merged commit ad631ae into main Aug 17, 2026
1 check passed
argszero added a commit that referenced this pull request Sep 15, 2026
The sidebar prints a keycap digit and a "Shortcut N" tooltip on every nav item,
and one global number-key handler resolves the digit. Both sides must read the
same array:

  const NAV_ORDER = NAV.flatMap((g) => g.items);
  const short = NAV_ORDER.indexOf(item) + 1;     // the keycap
  const item = NAV_ORDER[Number(e.key) - 1];     // the handler

renderNav()'s guest branch hand-built an equivalent-looking literal that is not
a member of NAV_ORDER, so indexOf(item) was -1 and the guest sidebar advertised
keycap 0 with the tooltip "Shortcut 0 . Marketplace" -- while 0 resolves to
NAV_ORDER[-1], i.e. nothing at all. The digit that does open the marketplace is
2, which the guest is never told.

The shape dates from #44 (v1.17 D keyboard accessibility), which added the
keycap machinery without noticing that the guest item is not a registry member;
it survived #86 (i18n) and the recent nav work. ui/README.md documents the
opposite (the badge is NAV_ORDER's index + 1, and the digits are 1..N of that
same array), so this is drift, not a trade-off.

Fix: the guest group draws from the registry it shares with the handler --
NAV_ORDER.filter((it) => GUEST_VIEWS.includes(it.id)).

Gate: state_gate::the_sidebar_advertises_only_digits_that_work -- four rules
with independent teeth: (1) renderNav renders no hand-built nav-item literal;
(2) the keycap is derived once and never branches on the session; (3) exactly
one line indexes the registry and it selects with the pressed digit; (4) the
registry is derived from NAV, not a second hand-written list. A companion test
pins the scanners on synthetic input, comments included.

Also recalibrates the i18n positive controls (T_LITERAL_COUNT 543 -> 542,
T_LITERAL_DISTINCT 434 -> 433): removing that one T("nav.marketplace") call
site is the only change to the T() literal population.
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