tab: Add to support string children for TabBar. (#677)

## Break changes

- Removed `id` argument from `TabBar::new` method.
This commit is contained in:
Jason Lee 2025-03-03 17:34:17 +08:00 committed by GitHub
parent 1aa43b1bfe
commit bc89ce2536
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 53 additions and 31 deletions

View file

@ -99,8 +99,8 @@ impl Render for TabsStory {
})), })),
) )
.child( .child(
section("Normal Tabs", cx).child( section("Tabs", cx).child(
TabBar::new("normal-tabs") TabBar::new()
.w_full() .w_full()
.with_size(self.size) .with_size(self.size)
.selected_index(self.active_tab_ix) .selected_index(self.active_tab_ix)
@ -143,8 +143,8 @@ impl Render for TabsStory {
), ),
) )
.child( .child(
section("Pills Tabs", cx).child( section("Pill Tabs", cx).child(
TabBar::new("pills-tabs") TabBar::new()
.w_full() .w_full()
.pill() .pill()
.with_size(self.size) .with_size(self.size)
@ -162,7 +162,7 @@ impl Render for TabsStory {
) )
.child( .child(
section("Segmented Tabs", cx).child( section("Segmented Tabs", cx).child(
TabBar::new("segmented-tabs") TabBar::new()
.w_full() .w_full()
.segmented() .segmented()
.with_size(self.size) .with_size(self.size)
@ -170,17 +170,19 @@ impl Render for TabsStory {
.on_click(cx.listener(|this, ix: &usize, window, cx| { .on_click(cx.listener(|this, ix: &usize, window, cx| {
this.set_active_tab(*ix, window, cx); this.set_active_tab(*ix, window, cx);
})) }))
.child(Tab::new("tab-account", "Account")) .children(vec![
.child(Tab::new("tab-profile", "Profile").disabled(true)) "Account",
.child(Tab::new("tab-documents", "Documents")) "Profile",
.child(Tab::new("tab-mail", "Mail")) "Documents",
.child(Tab::new("tab-appearance", "Appearance")) "Mail",
.child(Tab::new("tab-settings", "Settings")), "Appearance",
"Settings",
]),
), ),
) )
.child( .child(
section("Underline Tabs", cx).child( section("Underline Tabs", cx).child(
TabBar::new("underline-tabs") TabBar::new()
.w_full() .w_full()
.underline() .underline()
.with_size(self.size) .with_size(self.size)
@ -188,12 +190,12 @@ impl Render for TabsStory {
.on_click(cx.listener(|this, ix: &usize, window, cx| { .on_click(cx.listener(|this, ix: &usize, window, cx| {
this.set_active_tab(*ix, window, cx); this.set_active_tab(*ix, window, cx);
})) }))
.child(Tab::new("tab-account", "Account")) .child("Account")
.child(Tab::new("tab-profile", "Profile").disabled(true)) .child("Profile")
.child(Tab::new("tab-documents", "Documents")) .child("Documents")
.child(Tab::new("tab-mail", "Mail")) .child("Mail")
.child(Tab::new("tab-appearance", "Appearance")) .child("Appearance")
.child(Tab::new("tab-settings", "Settings")), .child("Settings"),
), ),
) )
} }

View file

@ -650,7 +650,7 @@ impl TabPanel {
let tabs_count = self.panels.len(); let tabs_count = self.panels.len();
TabBar::new("tab-bar") TabBar::new()
.mt(-px(1.)) .mt(-px(1.))
.track_scroll(self.tab_bar_scroll_handle.clone()) .track_scroll(self.tab_bar_scroll_handle.clone())
.when( .when(

View file

@ -4,8 +4,8 @@ use crate::{ActiveTheme, Selectable, Sizable, Size, StyledExt};
use gpui::prelude::FluentBuilder as _; use gpui::prelude::FluentBuilder as _;
use gpui::{ use gpui::{
div, px, AnyElement, App, ClickEvent, Div, Edges, ElementId, Hsla, InteractiveElement, div, px, AnyElement, App, ClickEvent, Div, Edges, ElementId, Hsla, InteractiveElement,
IntoElement, ParentElement as _, Pixels, RenderOnce, Stateful, StatefulInteractiveElement, IntoElement, ParentElement as _, Pixels, RenderOnce, SharedString, Stateful,
Styled, Window, StatefulInteractiveElement, Styled, Window,
}; };
#[derive(Debug, Clone, Default, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Default, Copy, PartialEq, Eq, Hash)]
@ -333,6 +333,27 @@ pub struct Tab {
on_click: Option<Arc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>, on_click: Option<Arc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
} }
impl From<&'static str> for Tab {
fn from(label: &'static str) -> Self {
let label = SharedString::from(label);
Self::new(label.clone(), label)
}
}
impl From<String> for Tab {
fn from(label: String) -> Self {
let label = SharedString::from(label);
Self::new(label.clone(), label)
}
}
impl From<SharedString> for Tab {
fn from(label: SharedString) -> Self {
let label = SharedString::from(label);
Self::new(label.clone(), label)
}
}
impl Tab { impl Tab {
pub fn new(id: impl Into<ElementId>, label: impl IntoElement) -> Self { pub fn new(id: impl Into<ElementId>, label: impl IntoElement) -> Self {
let id: ElementId = id.into(); let id: ElementId = id.into();

View file

@ -3,8 +3,8 @@ use std::sync::Arc;
use crate::{h_flex, ActiveTheme, Selectable, Sizable, Size, StyledExt}; use crate::{h_flex, ActiveTheme, Selectable, Sizable, Size, StyledExt};
use gpui::prelude::FluentBuilder as _; use gpui::prelude::FluentBuilder as _;
use gpui::{ use gpui::{
div, rems, AbsoluteLength, AnyElement, App, Div, Edges, ElementId, IntoElement, ParentElement, div, rems, AbsoluteLength, AnyElement, App, Div, Edges, IntoElement, ParentElement, RenderOnce,
RenderOnce, ScrollHandle, StatefulInteractiveElement as _, Styled, Window, ScrollHandle, StatefulInteractiveElement as _, Styled, Window,
}; };
use gpui::{px, InteractiveElement}; use gpui::{px, InteractiveElement};
use smallvec::SmallVec; use smallvec::SmallVec;
@ -14,7 +14,6 @@ use super::{Tab, TabVariant};
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct TabBar { pub struct TabBar {
base: Div, base: Div,
id: ElementId,
scroll_handle: ScrollHandle, scroll_handle: ScrollHandle,
prefix: Option<AnyElement>, prefix: Option<AnyElement>,
suffix: Option<AnyElement>, suffix: Option<AnyElement>,
@ -27,10 +26,10 @@ pub struct TabBar {
} }
impl TabBar { impl TabBar {
pub fn new(id: impl Into<ElementId>) -> Self { /// Create a new TabBar.
pub fn new() -> Self {
Self { Self {
base: div().px(px(-1.)), base: div().px(px(-1.)),
id: id.into(),
children: SmallVec::new(), children: SmallVec::new(),
scroll_handle: ScrollHandle::new(), scroll_handle: ScrollHandle::new(),
prefix: None, prefix: None,
@ -86,14 +85,15 @@ impl TabBar {
} }
/// Add children of the TabBar, all children will inherit the variant. /// Add children of the TabBar, all children will inherit the variant.
pub fn children(mut self, children: impl IntoIterator<Item = Tab>) -> Self { ///
self.children.extend(children); pub fn children(mut self, children: impl IntoIterator<Item = impl Into<Tab>>) -> Self {
self.children.extend(children.into_iter().map(Into::into));
self self
} }
/// Add child of the TabBar, tab will inherit the variant. /// Add child of the TabBar, tab will inherit the variant.
pub fn child(mut self, child: Tab) -> Self { pub fn child(mut self, child: impl Into<Tab>) -> Self {
self.children.push(child); self.children.push(child.into());
self self
} }
@ -157,7 +157,6 @@ impl RenderOnce for TabBar {
}; };
self.base self.base
.id(self.id)
.group("tab-bar") .group("tab-bar")
.relative() .relative()
.flex() .flex()