4.4 KiB
APP-3578: Tech Spec — Vertical Tabs Dropdown Menu
Problem
The vertical tabs panel reuses the horizontal tab bar's new-session menu. The Figma mock requires a distinct menu with different items, ordering, icons, and a single + trigger button.
Relevant Code
app/src/workspace/view/vertical_tabs.rs—render_new_tab_button(single+button, formerlyrender_new_tab_split_button)app/src/workspace/view/vertical_tabs.rs—VerticalTabsPanelState(mouse states),VERTICAL_TABS_ADD_TAB_POSITION_ID(menu anchor)app/src/workspace/view.rs—new_session_menu_items()(horizontal tab bar item builder)app/src/workspace/view.rs—vertical_tabs_new_session_menu_items()(vertical tabs item builder)app/src/workspace/view.rs—toggle_new_session_dropdown_menu(position, is_vertical_tabs, ctx)(opens the menu)app/src/workspace/action.rs—WorkspaceAction::ToggleNewSessionMenu { position, is_vertical_tabs }
Changes Made
1. is_vertical_tabs field on ToggleNewSessionMenu
WorkspaceAction::ToggleNewSessionMenu now carries is_vertical_tabs: bool. Horizontal tab bar dispatch sites pass false; the vertical tabs + button passes true.
2. vertical_tabs_new_session_menu_items() method
New method on Workspace in view.rs. Builds items in Figma order with icons:
- "Default" —
AddTab,LayoutAlt01icon, ⌘T keybinding - "Agent" —
AddAgentTab,LayoutAlt01icon (if AI enabled) - "Terminal" —
AddTerminalTab,LayoutAlt01icon - "Cloud agent tab" —
AddAmbientAgentTab,LayoutAlt01icon (if flags enabled) - Shells —
AddTabWithShell,LayoutAlt01icon (ifShellSelectorenabled) - Launch configs —
LayoutAlt01icon, skip "Learn about Launch Configs..." - Tab configs —
LayoutAlt01for non-worktree,Dataflow02for worktree configs MenuItem::Separator- "New worktree" —
CreateNewTabConfig,Plusicon
Worktree detection: a tab config is a worktree if any pane has worktree_name_autogenerated or commands containing "git worktree".
3. toggle_new_session_dropdown_menu selects item builder and width
Accepts is_vertical_tabs: bool. When true: calls vertical_tabs_new_session_menu_items() and sets menu width to 268px. When false: calls new_session_menu_items() and resets width to MENU_DEFAULT_WIDTH (186px).
4. Single + button replaces split button
render_new_tab_split_button replaced by render_new_tab_button — a single + icon button. On click dispatches ToggleNewSessionMenu { position, is_vertical_tabs: true }. Removed new_tab_menu_state from VerticalTabsPanelState.
5. Menu positioning
For vertical tabs, the dropdown is anchored to the + button via offset_from_save_position_element(VERTICAL_TABS_ADD_TAB_POSITION_ID, ...) with BottomLeft → TopLeft anchoring (4px gap). For horizontal tabs, the existing offset_from_parent positioning is unchanged.
6. New SVG assets and Icon variants
Added layout-alt-01.svg, layout-alt-02.svg, layout-alt-03.svg, layout-alt-04.svg, layout-bottom.svg to app/assets/bundled/svg/. Added corresponding LayoutAlt01 through LayoutBottom variants to warp_core::ui::Icon. Currently only LayoutAlt01 is used; the others are available for future icon differentiation.
End-to-End Flow
- User clicks
+in vertical tabs panel. ToggleNewSessionMenu { position, is_vertical_tabs: true }dispatched.- Handler calls
toggle_new_session_dropdown_menu(position, true, ctx). - Menu width set to 268px, items built via
vertical_tabs_new_session_menu_items(). - Menu rendered as overlay anchored below the
+button viaVERTICAL_TABS_ADD_TAB_POSITION_ID. - User selects an item → action dispatched (
AddTab,AddAgentTab,SelectTabConfig, etc.).
Files Changed
app/src/workspace/action.rs— addedis_vertical_tabsfieldapp/src/workspace/view.rs— newvertical_tabs_new_session_menu_items(), updatedtoggle_new_session_dropdown_menu, updated menu positioning inrender(), updated action handlerapp/src/workspace/view/vertical_tabs.rs— replaced split button with single+button, simplified state, made position IDpub(super)warp_core/src/ui/icons.rs— addedLayoutAlt01,LayoutAlt02,LayoutAlt03,LayoutAlt04,LayoutBottomvariantsapp/assets/bundled/svg/— added 5 new layout SVG iconsspecs/APP-3578/— PRODUCT.md and TECH.md