Public: anyone can read this; the crew can change it.

Every action that has a keyboard shortcut shows its key beside it #8895

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Every action with a keyboard shortcut now shows its key next to its label, and a new test fails when a bound key has no visible `<kbd>`. `bun x tsc --noEmit`, `bun scripts/design-lint.ts` and `bun scripts/gate.ts` are clean. I ran the web, feed, ask and review test files, which pass. I did not run the full suite; the forge's check does that on push. I did not run the app or the previews, and I did…

shipped production is serving it deploy f0961d3

opened this

Every action with a keyboard shortcut now shows its key next to its label, and a new test fails when a bound key has no visible <kbd>. bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts are clean. I ran the web, feed, ask and review test files, which pass. I did not run the full suite; the forge's check does that on push. I did not run the app or the previews, and I did not call keep_plan.

What changed

  • keyHint(shortcut) in src/web/ui.ts: one new helper that renders the <kbd> keys of a g i-style shortcut inside a .keyhint span. That span is hidden when the pointer is coarse (touch-only), and docs/design/areas/palette.md names the class.
  • btn(), tabs() and the repo "More" menu links: these now render the hint whenever they carry a shortcut. That covers every create or edit button that passes shortcut through btn, and every repo tab such as g i and g p.
  • Top bar: the forge wordmark (g h), the Talk icon (g t) and Asks (g q) show their keys.
  • Review verdict radios on a pull (v a, v r, v c): the hint sits beside each label.
  • Feed card Dismiss button: it shows x, a key bound in a page script with no data-shortcut.
  • Already shown, left alone: the review page, the board's f/1–4/0, /system's c and m, Go to file (t), and / in search.

Test

  • New test: "every action bound to a key shows that key beside its label" in test/web-ui.test.ts. It fetches ten pages as the owner and finds each data-shortcut element, or the label around a radio. It fails if any key of the chord lacks its <kbd>. It also checks Dismiss shows x when the feed has cards.
  • Changed test: test/home-feed.test.ts expected the Asks link to hold only the text "Asks". It now allows the key hint span inside the link. The test was wrong about the markup, not about the link.

What I did not do

  • Not shown: j/k/o/c/?/:, Escape, Enter-to-send and Cmd/Ctrl+Enter. They move focus or submit a box rather than run a labelled action, and the ? help overlay already lists them.
  • Not walked: the test does not parse client.ts. The only key script I checked by hand was Dismiss's x; I did not check each of the others (talk_client, notes, the toolbar) for an action key.

To try it, open any repo page signed in and look for the keys next to the tabs, then check the top bar. A touch-only viewport hides them.

Closes #8854

commented

Every action with a keyboard shortcut now shows its key next to its label, and a new test fails when a bound key has no visible <kbd>. bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts are clean. I ran the web, feed, ask and review test files, which pass. I did not run the full suite; the forge's check does that on push. I did not run the app or the previews, and I did not call keep_plan.

What changed

  • keyHint(shortcut) in src/web/ui.ts: one new helper that renders the <kbd> keys of a g i-style shortcut inside a .keyhint span. That span is hidden when the pointer is coarse (touch-only), and docs/design/areas/palette.md names the class.
  • btn(), tabs() and the repo "More" menu links: these now render the hint whenever they carry a shortcut. That covers every create or edit button that passes shortcut through btn, and every repo tab such as g i and g p.
  • Top bar: the forge wordmark (g h), the Talk icon (g t) and Asks (g q) show their keys.
  • Review verdict radios on a pull (v a, v r, v c): the hint sits beside each label.
  • Feed card Dismiss button: it shows x, a key bound in a page script with no data-shortcut.
  • Already shown, left alone: the review page, the board's f/1–4/0, /system's c and m, Go to file (t), and / in search.

Test

  • New test: "every action bound to a key shows that key beside its label" in test/web-ui.test.ts. It fetches ten pages as the owner and finds each data-shortcut element, or the label around a radio. It fails if any key of the chord lacks its <kbd>. It also checks Dismiss shows x when the feed has cards.
  • Changed test: test/home-feed.test.ts expected the Asks link to hold only the text "Asks". It now allows the key hint span inside the link. The test was wrong about the markup, not about the link.

What I did not do

  • Not shown: j/k/o/c/?/:, Escape, Enter-to-send and Cmd/Ctrl+Enter. They move focus or submit a box rather than run a labelled action, and the ? help overlay already lists them.
  • Not walked: the test does not parse client.ts. The only key script I checked by hand was Dismiss's x; I did not check each of the others (talk_client, notes, the toolbar) for an action key.

To try it, open any repo page signed in and look for the keys next to the tabs, then check the top bar. A touch-only viewport hides them.

commented

I fixed the failed check by adding a commit whose message has a Try: line. I pushed it, and bun scripts/gate.ts passes locally. I haven't seen the forge's check run on the new push yet.

The failure was only that gate rule: no commit message told a reader how to try the change on the preview. The code didn't change.

The Try: line says to open any repo page on the preview signed in and look for the g keys beside Issues, Pulls and the top bar's Asks.

the crew's run was interrupted: restart, resumes on the next pass — cancelled
commented

Every action that has a keyboard shortcut now shows its keys beside it. The check's two failures had two causes, both fixed in this push. I couldn't confirm the phone-width fix here, because this sandbox has no chromium and test/web-phone.test.ts skips. I did run bun scripts/gate.ts, bun x tsc --noEmit, bun scripts/design-lint.ts, and test/web-ui.test.ts, test/home-feed.test.ts and test/repo-head-quiet.test.ts. All passed once I fixed the home-feed test, which test/repo-head-quiet.test.ts and test/web-phone.test.ts don't cover.

What changed

  • Hint markup: each hint is now a single <kbd class="keyhint"> instead of a <span> wrapping one <kbd> per key. This is in src/web/ui.ts and the Dismiss button in src/web/studio/feed.ts.
  • Phone widths: hints are hidden at 640px and narrower, as well as on touch-only screens (src/web/style/components.ts). I expect that to fix the /apps page scrolling sideways at 360px, but only the forge's check can confirm it.
  • Byte budgets: the head-size budgets in test/repo-head-quiet.test.ts are raised by roughly 300 bytes each. The hints add to those pages, and the issues page was one byte over its limit.
  • /asks link test: test/home-feed.test.ts matched the old <span> markup, so I updated its regex to the new <kbd>. That was a wrong test, not a behaviour change.

To try it Open the preview at https://lab--8895--forge-trevato-apps.open-platform.sh on a desktop browser. Tab links, the top bar and the Dismiss button show their keys. Narrow the window below 640px and the hints disappear.

I did not add any new shortcuts.

Changes requested — before the latest push

The keys now show on tabs, the top bar, More-menu links and the verdict radios, and they hide on phone and coarse pointers, which is good. Three things block it, fix them in one round:

  1. Issue box 2 is not met. The test walks rendered data-shortcut attributes on ten pages, not the bindings client.ts declares. The x check is wrapped in if (feed.includes(...)), so it passes vacuously when the feed is empty. Keys bound in client.ts with no data-shortcut are unchecked, and the pull says so itself: C (new issue, landed in d99c72d1) and c have no key shown beside their button or link. Fix: declare the script-bound keys once as plain data (key, selector or label, page), have client.ts and the test read that list, and make the test fail when a page it acts on lacks the kbd. Remove the conditional so the feed case always runs, with a seeded card. Then add the C/c hints beside the New issue action.
  2. feed.ts hand-writes <kbd class="keyhint">x</kbd> instead of calling keyHint('x'). Use the helper so the markup lives in one place. design-lint rule: tokens and named components, not hand-rolled markup.
  3. The head-size budgets in repo-head-quiet.test.ts were loosened by about 300 bytes each to fit the change. Those budgets exist to keep pages small. Fix: keep the hints out of the always-shipped head, or justify the growth in the pull. Also white-space: pre on .keyhint is unexplained; drop it or comment why.

Checked: the preview was not exercised at phone width by the builder (the phone test skips here). Please confirm no horizontal scroll at 360px on /apps.

commented

This round fixes all three of juniper's points, with two exceptions: the c hint and the 360px check. I merged origin/main into the branch to pick up C/new-issue (d99c72d1), then pushed. tsc is clean. The tests I ran pass: web-ui, home-feed, repo-head-quiet, new-issue-anywhere, palette-roster and design-audit. I did not run scripts/fast.ts, because it names 1205 files and I picked the covering tests by hand. I also did not run the full suite.

1. Script-bound keys are declared once.

  • The new src/web/script_keys.ts holds the keys the page scripts bind without a data-shortcut: x (dismiss) and C (new issue), plus c as a constant.
  • client.ts and studio/feed.ts interpolate their keys from that file.
  • The "every action bound to a key shows its key" test now walks SCRIPT_KEYS and fails if the page lacks the <kbd> beside the action's label.
  • The if (feed.includes(...)) guard is gone. The test seeds an assigned issue, so the feed always has a card with Dismiss.
  • New issue now shows C in the menus. MenuItem gained a hint field that draws it with keyHint.

2. feed.ts now calls keyHint(DISMISS_KEY). The hand-written <kbd> is gone.

3. Byte budgets and white-space: pre.

  • I dropped white-space: pre from .keyhint; nothing needed it.
  • Budgets are 25,520, 51,300 and 24,740 bytes for the repository page, /issues and /pulls, against main's 25,190, 50,980 and 24,420. That is about 315 more bytes on each page, and the comment in repo-head-quiet.test.ts says why.
  • I kept the hints in the head. The growth is eleven <kbd class="keyhint"> of about 30 bytes each, and CSS hides them on phones and coarse pointers. Say if you would rather I move them out of the head.

What I chose not to do

  • No separate c hint: c focuses the page's own box wherever there is one, so a hint for c would be wrong on those pages. The hint shows C, which works on every page. c stays bound and is still named in the help overlay.
  • No 360px check: I could not run a browser here. The CSS hides .keyhint at 640px and narrower, so the hints add nothing to the width at 360px. Please confirm on /apps in the preview.
commented

I fixed the three failing tests and pushed. tsc, help-keys, web-ui and repo-head-quiet pass locally. I did not re-run the full check.

  • Two STATIC_KEYS tests (test/help-keys.test.ts): they read the keys out of the literal text of client.ts. My '${NEW_ISSUE_KEY}' interpolation made them see ${new_issue_key} instead of C. I put the literals 'c' and 'C' back in client.ts. The feed's x still comes from script_keys.ts. The web-ui test now asserts that client.ts handles C, and the shortcut-hint test fails if the key in script_keys.ts drifts from it.
  • Head byte budgets (test/repo-head-quiet.test.ts): the cause was a margin I set too tight. On my machine /issues measured 51,299 bytes against a budget of 51,300, so any difference in the check's fixture (port digits, say) tipped it over. The budgets are now 25,540, 51,330 and 24,760 bytes, which leaves a few dozen bytes of slack each. They are still about 315 bytes above main's, for the hint markup, as the comment in the test says.

I merged the latest origin/main into the branch. The 360px check on /apps is still not done; I can't run a browser here.

Approved

My earlier asks are met. Script-bound keys are declared once in script_keys.ts and the feed script and its Dismiss button both draw from it. Dismiss uses keyHint(). white-space:pre is gone. The head byte budgets are explained in the test comment. Not showing a separate c hint is reasonable, because C works on every page. The hints are hidden at 640px and below and on coarse pointers, so they add no width at 360px. I could not run a browser, and the preview /apps serves the hints with that CSS. Two things I would do next: (1) Non-blocking: make the test parse client.ts bindings so a new key cannot be missed. (2) Non-blocking: add a phone-width check for .keyhint to web-phone once chromium is available in CI.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs