Skip to content

feat(ui): W leader chords and palette commands for tabs and panes (RIG-4445) - #1770

Merged
trunk-io[bot] merged 3 commits into
compass-ui/rig-4444-tab-stripfrom
compass-ui/rig-4445-tab-chords
Oct 7, 2026
Merged

trunk-io[bot] merged 3 commits into
compass-ui/rig-4444-tab-stripfrom
compass-ui/rig-4445-tab-chords

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

This PR is part of a stack containing 7 PRs:

  1. main
  2. refactor(ui): extract parseRoute and add ViewScope with useView (RIG-4439) #1652
  3. refactor(ui): move routed surfaces and agent-workspace state onto the view scope (RIG-4442) #1675
  4. feat(ui): window layout model, hash sync and session persistence (RIG-4443) #1743
  5. feat(ui): view tab strip with keep-alive and open-in-tab links (RIG-4444) #1755
  6. "feat(ui): W leader chords and palette commands for tabs and panes (RIG-4445)" (this PR)
  7. feat(ui): two-pane split with a resizable splitter (RIG-4446) #1780
  8. fix(ui): chrome cleanup: drop ADE and usage bar, Session Log naming, pane edges, row re-measure (RIG-4771) #1811

Tabs T5 of docs/designs/ui/compass-in-window-tabs/design.md §T5 (RIG-4445), stacked on T4 #1755. It adds the §A6 W leader chords (OQ-1: leader W in both hosts, focus-gated like G).

  • keyboard/keymap.ts: the §A6 table rows, exactly as listed:
    • W N new tab, W X close
    • W ] and W [ next and previous
    • W 1–W 9 go to tab N
    • W V and W S split right and down
    • W O closes the other pane
    • W H and W L focus the first and second pane
  • tab.moveLeft and tab.moveRight have no chord, because §A6 lists none; they are palette commands only.
  • keyboard/spine.ts: registers the commands below against dispatchLayout.
    • Tab commands: tab.new, tab.close, tab.next, tab.prev, tab.goto.1–tab.goto.9, tab.moveLeft, tab.moveRight.
    • Pane commands: pane.splitRight, pane.splitDown, pane.closeOther, pane.focusFirst, pane.focusSecond.
  • store.ts: passes the layout accessor and dispatchLayout to the spine. Two shared paths serve both the strip and the commands:
    • closeTab keeps focus on the new active tab button when the closed tab's button had focus.
    • focusPane moves DOM focus into the target pane when focus is outside both panes.
  • App.tsx: focus moving into a pane makes that pane the focused one, so layout focus follows DOM focus. view-panel.ts holds the panel ids and panel focus helper that App and the store share.
  • Palette entries come from the registry, with titles per §A3/§A6 ("New tab", "Close tab", "Move tab left", "Go to tab N", …).

Readings:

  • W N opens /, using the §A3 open dedupe: on a tab already showing Bridge, it focuses that tab. RIG-4676 asks Matt whether "New tab" should always open a new tab.
  • Next and previous wrap, matching the tab strip's arrow keys.
  • Go-to and move ignore out-of-range targets.
  • Pane commands on a single-view tab are no-ops in the reducer. Until T6 (RIG-4446) adds the splitter, a split tab renders its two panes stacked, so "Split right" and "Split down" look the same.

Tests

  • New and extended tests:
    • keymap.test.ts: the full W chord-to-command map. The existing authoring-invariant test covers the new rows.
    • spine.test.ts and tab-keep-alive.test.tsx: outcomes on a real store, not emitted actions. Covered: New tab from Bridge and from a topic tab, New tab at the tab cap (notice), closing the last tab (goes to /), wrap, go-to past the end, move bounds, split and close-other, and pane focus moving DOM focus both ways.
    • dispatch.test.ts: w n runs tab.new on a non-editable target and runs nothing in a focused composer.
    • TabStrip.test.tsx: Close tab from a focused tab button, and from the palette, leaves focus on the new active tab.
    • Palette.test.tsx: lists every command.
  • ShortcutsOverlay.test.tsx: the "Bridge" filter now expects 3 rows, because tab.new carries a bridge keyword.
  • e2e tab-strip.spec.ts: W N opens a tab and W X closes it, and composer text is untouched.
  • moon run compass-ui:test: 1285 pass, 0 fail. Typecheck, stylelint and biome are clean.
  • Playwright visual-smoke + dev-boot + tab-strip: 16 passed, with no baseline change.

Spec-impact: none.
Ledger-impact: none

Co-authored-by: Matt Wilkinson matt@rigel.build

rigel-mintaka and others added 2 commits October 6, 2026 01:10
…G-4445)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
…IG-4445)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Oct 6, 2026

Copy link
Copy Markdown

RIG-4445

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-ui-rig-4445-tab-chor.compass-eng-docs.pages.dev

Deployed from compass-ui/rig-4445-tab-chords at d7a5fe9.

…s (RIG-4445)

Pane focus commands move DOM focus into the target pane, and focus moving
into a pane makes it the focused pane. One store closeTab path keeps focus on
the new active tab for both the strip and the Close tab command. Spine tests
now assert layout outcomes on a real store instead of emitted actions.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@trunk-io

trunk-io Bot commented Oct 7, 2026

Copy link
Copy Markdown

This pull request is queued for merge as part of 1798, which will merge 1652, 1675, 1743, 1755, 1770, 1780, 1787, 1798.

@trunk-io
trunk-io Bot merged commit 2afaa08 into main Oct 7, 2026
18 checks passed
@trunk-io
trunk-io Bot deleted the compass-ui/rig-4445-tab-chords branch October 7, 2026 04:16
@trunk-io

trunk-io Bot commented Oct 7, 2026

Copy link
Copy Markdown

This pull request was merged into main as part of stacked PR 1798.

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.

2 participants