chore: drop tab icon in favor of lead

This commit is contained in:
2026-11-10 07:17:23 +07:00
parent dc2c612cff
commit 322f037289
4 changed files with 40 additions and 34 deletions
+2 -2
View File
@@ -63,8 +63,8 @@ badge = []
input = ["button"] input = ["button"]
clipboard = ["button"] clipboard = ["button"]
popover = [] popover = []
scroll_area = [] scroll_area = ["scrollbar"]
scrollbar = ["scroll_area"] scrollbar = []
segmented = [] segmented = []
separator = [] separator = []
spinner = [] spinner = []
+5 -29
View File
@@ -10,7 +10,7 @@ use gpui_native_core::button::{Button, ButtonVariant};
use gpui_native_core::common::Sizable as _; use gpui_native_core::common::Sizable as _;
use gpui_native_core::spinner::Spinner; use gpui_native_core::spinner::Spinner;
use gpui_native_core::tooltip::Tooltip; use gpui_native_core::tooltip::Tooltip;
use gpui_native_icons::{Icon, IconRole}; use gpui_native_icons::IconRole;
use gpui_native_theme::{ActiveTheme as _, Size}; use gpui_native_theme::{ActiveTheme as _, Size};
use gpui_native_utils::adjacent_selectable; use gpui_native_utils::adjacent_selectable;
@@ -35,7 +35,6 @@ pub struct Tab {
/// The stable identity for element state; must survive reordering. /// The stable identity for element state; must survive reordering.
key: ElementId, key: ElementId,
label: SharedString, label: SharedString,
icon: Option<Icon>,
lead: Option<AnyElement>, lead: Option<AnyElement>,
busy: bool, busy: bool,
disabled: bool, disabled: bool,
@@ -53,7 +52,6 @@ impl Tab {
Self { Self {
key: key.into(), key: key.into(),
label: label.into(), label: label.into(),
icon: None,
lead: None, lead: None,
busy: false, busy: false,
disabled: false, disabled: false,
@@ -62,16 +60,7 @@ impl Tab {
} }
} }
/// Shows an icon leading the label. /// Sets the leading element, e.g. an icon or an avatar.
pub fn icon<I>(mut self, icon: I) -> Self
where
I: Into<Icon>,
{
self.icon = Some(icon.into());
self
}
/// Sets the leading element.
pub fn lead<E>(mut self, lead: E) -> Self pub fn lead<E>(mut self, lead: E) -> Self
where where
E: IntoElement + 'static, E: IntoElement + 'static,
@@ -346,22 +335,9 @@ fn render_tab(
}), }),
}; };
let lead = tab.lead.take(); if let Some(lead) = tab.lead.take() {
let icon = tab.icon.take(); strip_tab = strip_tab.child(lead);
}
strip_tab = match lead {
Some(lead) => strip_tab.child(lead),
None => match variant {
TabsVariant::Underline => {
strip_tab.child(div().flex_none().pb_0p5().when_some(icon, |slot, icon| {
slot.child(icon.size(metrics.dense_icon_size).color(label_color))
}))
}
TabsVariant::Pill => strip_tab.when_some(icon, |strip_tab, icon| {
strip_tab.child(icon.size(metrics.dense_icon_size).color(label_color))
}),
},
};
strip_tab = strip_tab.child(tab.label.clone()); strip_tab = strip_tab.child(tab.label.clone());
+5 -2
View File
@@ -1038,12 +1038,15 @@ fn render_pane(
.selected(selected) .selected(selected)
.tabs({ .tabs({
let tabs = pane.tabs.clone(); let tabs = pane.tabs.clone();
move |_, _| { move |_, cx| {
let theme = cx.theme();
let metrics = theme.sizes.resolve(Size::default());
tabs.iter() tabs.iter()
.map(|tab| { .map(|tab| {
let mut entry = Tab::new(tab.panel.clone(), tab.title.clone()); let mut entry = Tab::new(tab.panel.clone(), tab.title.clone());
if let Some(icon) = tab.icon.clone() { if let Some(icon) = tab.icon.clone() {
entry = entry.icon(icon); entry = entry.lead(icon.size(metrics.icon_size));
} }
entry.closeable(true).wrap({ entry.closeable(true).wrap({
let panel = tab.panel.clone(); let panel = tab.panel.clone();
+28 -1
View File
@@ -509,6 +509,7 @@ impl Gallery {
SharedString::from("Blame"), SharedString::from("Blame"),
], ],
pill_selected: 0, pill_selected: 0,
lead_selected: 0,
}) })
.into() .into()
})); }));
@@ -2193,6 +2194,7 @@ struct TabsDemo {
selected: usize, selected: usize,
pill_tabs: Vec<SharedString>, pill_tabs: Vec<SharedString>,
pill_selected: usize, pill_selected: usize,
lead_selected: usize,
} }
impl Render for TabsDemo { impl Render for TabsDemo {
@@ -2200,6 +2202,7 @@ impl Render for TabsDemo {
let view = cx.entity(); let view = cx.entity();
let view_pill = view.clone(); let view_pill = view.clone();
let view_close = view.clone(); let view_close = view.clone();
let view_leads = view.clone();
let colors = cx.theme().colors; let colors = cx.theme().colors;
let pill_count = self.pill_tabs.len(); let pill_count = self.pill_tabs.len();
@@ -2281,7 +2284,31 @@ impl Render for TabsDemo {
.child(format!( .child(format!(
"{pill_count} tabs left; \"Syncing\" spins while it loads" "{pill_count} tabs left; \"Syncing\" spins while it loads"
)), )),
), )
.child(demo_section(
"leads",
colors,
Tabs::new("tabs-demo-leads")
.variant(TabsVariant::Pill)
.selected(self.lead_selected)
.on_change(move |selected, _, cx| {
view_leads.update(cx, |demo, cx| {
demo.lead_selected = selected;
cx.notify();
});
})
.tabs(|_, cx| {
let theme = cx.theme();
let metrics = theme.sizes.resolve(Size::default());
vec![
Tab::new("files", "Files")
.lead(icon(IconRole::Folder).size(metrics.dense_icon_size)),
Tab::new("people", "People")
.lead(Avatar::new("ada").name("Ada Lovelace").small()),
Tab::new("plain", "Plain"),
]
}),
)),
) )
} }
} }