Skip to content

Redesign terminal toolbar with real SVG icons + Layout dropdown (fixes invisible new-tab dropdown) #34

@kevmtt

Description

@kevmtt

Summary

Redesign the terminal pane toolbar (the + ▾ ⏐ ⎯ × controls) with real inline SVG icons and consolidate the two split buttons into a single Layout split-button with a dropdown. Also fixes a bug where the existing "new tab type" caret dropdown never appears.

All of this lives in one component: src/renderer/components/SplitPane/SurfaceTabBar.tsx (styled in src/renderer/styles/splitpane.css). PaneWrapper.tsx already wires up every handler needed (onNew, onNewTyped, onNewProfile, onSplitRight, onSplitDown, onClosePane), so this is a presentational redesign — no new plumbing.

Bug fixed by this work

The "new tab type" caret () currently does nothing when clicked, even with profiles configured. Root cause: .surface-tab-bar has overflow: hidden and is only 28px tall (splitpane.css:52), while the dropdown renders at position: absolute; top: 30px (splitpane.css:151) — i.e. below the bar — so it is clipped away and never visible. The click and state toggle work fine; the menu is just invisible.

Fix: render both dropdowns through a React portal to document.body with position: fixed, anchored to the trigger button's getBoundingClientRect(). This removes any dependency on parent overflow and works for both the New menu and the new Layout menu.

Control cluster (right-aligned, ~10px gaps, rounded hover pills)

Compact split-button style: clicking the main icon performs the default action; the attached caret opens a dropdown.

Control Icon Main click Caret dropdown Hover accent
New plus inside a rounded square open default terminal (onNew) Terminal · Browser · Markdown — separator — quick-launch profiles green
Layout two side-by-side panes split right (onSplitRight) Split right Ctrl+D · Split down Ctrl+Shift+D blue
Close clean X close pane (onClosePane) red

Implementation notes

  • Icons: inline stroke-based SVG, extracted into a small icons.tsx next to SurfaceTabBar.tsx — one component per glyph: IconAdd, IconSplit, IconSplitRight, IconSplitDown, IconClose, IconCaret. Keeps SurfaceTabBar.tsx readable.
  • New dropdown: keep current contents (tab types + profiles). Main + click keeps the instant-default-terminal fast path.
  • Layout dropdown: replaces today's two separate / split buttons. Main icon click = split right (fast path); caret = right/down menu.
  • Dropdown menus: only one open at a time; close on outside-click and Escape (existing logic preserved); show keyboard hints in the Layout menu.
  • Per-tab close × on individual tabs is unchanged. Keyboard shortcuts unchanged.

Out of scope (follow-up issue)

  • Migrating from hand-rolled inline SVG to lucide-react — to be filed as a separate issue. We intentionally start with inline SVG (no new dependency) and keep lucide as a later option.

Testing

SurfaceTabBar is presentational — add/extend a render test asserting:

  • the three controls (New / Layout / Close) render;
  • clicking a caret toggles its menu's visibility;
  • main-icon click vs. caret-click fire different handlers (e.g. onNew vs. opening the menu; onSplitRight vs. opening the layout menu).

Acceptance criteria

  • Toolbar uses real SVG icons (no + ▾ ⏐ ⎯ × glyphs).
  • New, Layout, and Close render as a right-aligned cluster with clear spacing and rounded hover states (green / blue / red accents).
  • New caret dropdown opens and is fully visible (clipping bug fixed) and lists tab types + profiles.
  • Layout caret dropdown opens with Split right / Split down (+ keyboard hints); main icon splits right.
  • Close button closes the pane.
  • Dropdowns close on outside-click / Escape; only one open at a time.
  • Render test added/updated and passing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions