Commit d375729
authored
Add basic tab group rendering for horizontal tabs (warpdotdev#12089)
## Description
Adds basic rendering for **horizontal tab groups** in the top tab bar,
on top of the existing vertical tab grouping data model. A group renders
as a single tab-bar slot containing a header (icon collage + name)
followed by its member tabs.
- Click the header → collapse/expand the group (collapsed shows just the
header).
- Double-click the header → rename inline.
- Right-click the header → open the group context menu (labels adapt to
"left/right" for horizontal layouts, "up/down/above/below" for
vertical).
- Right-click a member tab → standard tab menu, including "Remove from
group".
Dragging is out of scope for this PR — neither groups nor members can be
dragged yet.
All new behavior is gated behind `FeatureFlag::GroupedTabs`; when the
flag is off, the horizontal tab bar renders exactly as before.
## Changes
**`workspace/view.rs`**
- Added `TabBarSlot { Single | Group }` enum and a preprocessing pass in
`render_tab_bar_contents` that turns the flat tab list into a list of
slots (ungrouped tabs become `Single`, contiguous same-group runs
collapse into `Group`).
- Added `render_horizontal_tab_group` (container + member tabs) and
`render_horizontal_tab_group_header` (icon collage + name +
click/double-click/right-click handlers).
- Added `compute_group_member_kinds` — picks up to 4 distinct pane icons
for a group by reusing each member tab's "Summary pair" selection, so
the group icons are always a subset of what the member tabs would show
in vertical Summary.
- Added `render_group_member_icon_collage` — 1 or 2 icons reuse vertical
Summary's `Single`/`Pair` layout for visual parity; 3 or 4 fall back to
a corner collage. Designs for reference:
<img width="222" height="92" alt="Screenshot 2026-06-02 at 4 14 24 PM"
src="https://github.com/user-attachments/assets/53a04f14-6ff9-4385-8236-878ca8630947"
/>
<img width="193" height="80" alt="Screenshot 2026-06-02 at 4 14 52 PM"
src="https://github.com/user-attachments/assets/d0016562-10c3-4226-8828-ef16fb295511"
/>
- Added `select_unique_pane_kinds` — shared selection helper used by
both vertical Summary (`select_summary_pane_kind_icons`) and the
horizontal collage.
- Added per-group hover state map (`horizontal_tab_group_mouse_states`)
on `Workspace`.
- `tab_group_menu_items` now takes `is_vertical: bool` so labels adapt
to layout.
**`tab.rs`**
- `TabComponent` gained a `grouped_member` flag and
`.for_grouped_member()` builder. In that mode the tab skips side
dividers, paints an inset rounded highlight, and skips the `Draggable`
wrapper (member dragging is a follow-up).
**`workspace/view/vertical_tabs.rs`**
- `render_summary_pane_kind_icons` and `SummaryPaneKindIcons` are now
`pub(super)` and accept a `total_size` parameter so the horizontal
collage can reuse them at its own sizing.
- `select_summary_pane_kind_icons` now delegates to the shared
`select_unique_pane_kinds` helper.
## Linked Issue
https://linear.app/warpdotdev/issue/APP-4641/horizontal-tab-grouping-basic-rendering
## Testing
<!--
How did you test this change? What automated tests did you add? If you
didn't add any new tests, what's your justification for not adding any?
Manual testing is required for changes that can be manually tested, and
almost all changes can be manually tested. If your change can be
manually tested, please include screenshots or a screen recording that
show it working end to end.
You can run the app locally using `./script/run` - see WARP.md for more
details on how to get set up.
-->
- [x] I have manually tested my changes locally with `./script/run`
### Screenshots / Videos
[Demo
Video](https://www.loom.com/share/fff045cca12841bab0abd6b9764d89b9)1 parent 5967abf commit d375729
3 files changed
Lines changed: 615 additions & 127 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
764 | 764 | | |
765 | 765 | | |
766 | 766 | | |
| 767 | + | |
| 768 | + | |
767 | 769 | | |
768 | 770 | | |
769 | 771 | | |
| |||
924 | 926 | | |
925 | 927 | | |
926 | 928 | | |
| 929 | + | |
927 | 930 | | |
928 | 931 | | |
929 | 932 | | |
| |||
934 | 937 | | |
935 | 938 | | |
936 | 939 | | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
937 | 947 | | |
938 | 948 | | |
939 | 949 | | |
| |||
1452 | 1462 | | |
1453 | 1463 | | |
1454 | 1464 | | |
1455 | | - | |
1456 | | - | |
1457 | | - | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
1458 | 1472 | | |
1459 | 1473 | | |
1460 | 1474 | | |
| |||
1591 | 1605 | | |
1592 | 1606 | | |
1593 | 1607 | | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
1594 | 1621 | | |
1595 | 1622 | | |
1596 | 1623 | | |
| |||
1657 | 1684 | | |
1658 | 1685 | | |
1659 | 1686 | | |
| 1687 | + | |
1660 | 1688 | | |
1661 | 1689 | | |
1662 | 1690 | | |
| |||
1849 | 1877 | | |
1850 | 1878 | | |
1851 | 1879 | | |
| 1880 | + | |
| 1881 | + | |
| 1882 | + | |
| 1883 | + | |
1852 | 1884 | | |
1853 | 1885 | | |
1854 | 1886 | | |
| |||
0 commit comments