Skip to content

Split tab group UX round: explorer focus, pinned tool tabs, un-split gesture#232

Open
parsakhaz wants to merge 6 commits into
mainfrom
fix/default-tab-focus
Open

Split tab group UX round: explorer focus, pinned tool tabs, un-split gesture#232
parsakhaz wants to merge 6 commits into
mainfrom
fix/default-tab-focus

Conversation

@parsakhaz

@parsakhaz parsakhaz commented Jun 12, 2026

Copy link
Copy Markdown
Member

Description

A round of in-app UX feedback on split tab groups, tested live against the dev build:

  • New panes focus Explorer instead of Diff (which only won by a Promise.all race; it's also the slowest default to render), and the default order is now Explorer, Diff, Browser. Existing panes keep their stored order.
  • Tool tabs are pinned to the top bar. While split, the permanent tools (Explorer/Diff/Browser) are hoisted to the top bar from every group, in reading order, and group strips show only working tabs. Previously 'primary' was positional, so a drag that landed a new group on the left edge made the tools ride along into a group strip. Their membership still only changes when explicitly dragged; clicking a hoisted tab routes to and focuses its owning group.
  • Top-bar drop is the un-split gesture. Dropping any tab on the top bar merges every group back into the primary group (new mergeAllGroups tree op), with the dropped tab landing at the indicator. Previously this was a same-group reorder that looked like a dead drop.
  • A merge affordance badge ('drop to merge all tabs back here', inline SVG) appears while a drag hovers the top bar in split mode; pointer-events-none so drops pass through.
  • The primary group's strip renders bold tab text so the group the top bar belongs to is visually obvious.
  • The tab divider follows the rightmost default tool instead of being hardcoded after the Browser tab, so reordering defaults doesn't drag the separator into the middle of the strip.
  • 7 new tests (mergeAllGroups, subsetInsertIndex), 51 total in the layout suite.

Stacked on #229; merge that first.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have run pnpm typecheck and pnpm lint locally
  • I have tested the Electron app locally with pnpm electron-dev

Critical Areas Modified

  • State management (layout tree ops, top-bar drop path)

The floating glassmorphic pill hovered over group content and covered
terminal text. Replace it with a slim full-width strip row (same
compact pill-style tabs, centered) that occupies a layout row and
pushes content down so nothing is ever covered.

Once a pane is split, every group owns its tabs: the primary group now
renders the same strip row as the others, and the top bar hides its tab
strip, keeping only the controls (Add Tool, resource monitor, run,
layout toggles) with a spacer preserving their alignment. Unsplit panes
are unchanged: tabs stay in the top bar, pixel-identical.

Shortcut hints (Mod+Shift+1-9) follow the primary group's strip into
its row, still gated on the group having focus.
…t tabs

Round of in-app feedback on the strip rows:

- the top bar keeps the primary group's permanent tabs (Diff/Explorer/
  Browser) when split; only working tabs (terminals/agents) move into
  the group strips. Strip drop indexes translate through the new
  subsetInsertIndex util since both the top bar and the primary strip
  now display subsets of the group's full order
- splitting or moving a group's active working tab no longer flips the
  source group to the Diff view: the successor prefers the first
  remaining working tab (gated on the moved panel having been active,
  so a deliberately-active Diff stays put)
- drop the pill chrome: variant renamed pill -> compact, no rounded
  borders or glass background, plain slim tabs in the row
- compact tabs sized up ~20% (h-6, 11px text, 3.5 icons) per feedback
- shortcut hints disabled in the split top bar (subset indexes would
  lie); 4 new tests for subsetInsertIndex (48 total)
New panes were auto-focusing the diff tab, and only by accident: the
three default panels are created in a parallel Promise.all and each
createPanel marks itself active, so the race winner got focus. Diff is
also the slowest default to render.

- explicitly set the explorer panel active after default panel
  creation (session creation and main repo session creation)
- default tab order becomes Explorer, Diff, Browser in all three sort
  sites (top bar fallback, initial layout creation, session panel sort)

Existing panes keep their order: stored layouts bake panel order, and
the sorts only apply when no layout exists yet.
the divider was hardcoded to render after the browser tab, so
reordering the defaults dragged the separator into the middle of the
strip. it now sits after the rightmost diff/explorer/browser tab and
is suppressed when that tab is last in the strip
Dropping a tab on the top bar previously moved it into the primary
group, which is invisible when the tab already lives there (the strip
only shows working tabs), so the gesture read as a dead drop.

- top-bar drops are now the deliberate un-split gesture: every group
  merges back into the primary group (new mergeAllGroups tree op,
  primary id/active preserved, reading-order panel ids, deduped) and
  the dropped tab lands at the indicated position. Unsplit panes get
  the identity merge, i.e. the old reorder behavior
- the primary group's strip renders bold tab text so it's obvious
  which group the top bar and the un-split gesture belong to
- while a drag hovers the top bar in split mode, a pointer-events-none
  badge advertises 'drop to merge all tabs back here' (inline svg, no
  icon lib)
- 3 new tests for mergeAllGroups (51 total)
The defaults (explorer/diff/browser) were riding along into group
strips: 'primary' is positional (first group in reading order), so a
drag that landed a new group on the left edge demoted the tools' group
to secondary, whose strip showed full membership.

The top bar now hoists permanent tool tabs from EVERY group in reading
order, and group strips filter them out everywhere, so the defaults
stay pinned up top no matter which group owns them. Clicking a hoisted
tab already routes to its owning group and focuses it
(handlePanelSelect -> findGroupContainingPanel). The top bar's active
highlight follows the focused group's active panel while split, and
top-bar drop translation now maps against the merged panel order.
@parsakhaz parsakhaz changed the title New panes focus Explorer; default tab order Explorer, Diff, Browser Split tab group UX round: explorer focus, pinned tool tabs, un-split gesture Jun 12, 2026
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