Components / navigation
Tabs builder
A row of tabs. The strip publishes one Role::Tab node per tab.
A builder is RenderOnce. Construct and mount it in one expression.
use gpui_kit::navigation::Tabs;
Reviewed in tabs document-tabs.
Also drawn by motion-state motion-primitives deferred-drop reading-direction, which arranges components rather than reviewing them.
Construct
new(ident: impl Into<Ident>) -> Self
Options
Chain onto the value.
capsules() -> Self
tab(tab: TabItem) -> Self
tabs(tabs: impl IntoIterator<Item = TabItem>) -> Self
selected(id: impl Into<SharedString>) -> Self
on_select(handler: impl Fn(SharedString, &mut Window, &mut App) + 'static) -> Self
on_close(handler: impl Fn(SharedString, &mut Window, &mut App) + 'static) -> Self
overflow_after(count: usize) -> Self
scrolling() -> Self
overflow_menu(menu: Entity<Menu>) -> Self
reorderable(reorderable: bool) -> Self
accepts(predicate: impl Fn(&DragItem, &DropPosition) -> bool + 'static) -> Self
deferred_acceptance(controller: dnd::DeferredDrop, revision: u64) -> Self
on_reorder(handler: impl Fn(&DropIntent, &mut Window, &mut App) + 'static) -> Self
Example · tabs
fn tabs(_window: &mut Window, cx: &mut App) -> AnyElement {
let theme = cx.theme().clone();
stack(&theme)
.w(px(520.0))
.child(caption(
&theme,
"In-content tabs: raised control, quiet track, tabular count",
))
.child(
Tabs::new("scene.tabs.workspace")
.tabs([
TabItem::new("overview", "Overview").icon(Icon::Widget),
TabItem::new("runs", "Runs").badge("12"),
TabItem::new("logs", "Logs"),
TabItem::new("billing", "Billing").disabled(true),
])
.selected("runs")
.on_select(|_, _, _| {}),
)
.child(caption(
&theme,
"places, not documents: Regular Liquid capsules, \
with a translucent selected fill on the material",
))
.child(
Tabs::new("scene.tabs.capsules")
.capsules()
.control_size(ControlSize::Sm)
.tabs([
TabItem::new("code", "Portal")
.icon(Icon::Terminal)
.tint(theme.colors.accent),
TabItem::new("game", "Harbour")
.icon(Icon::Play)
.tint(theme.colors.warning),
TabItem::new("design", "notes")
.icon(Icon::Pen)
.tint(theme.colors.info),
])
.selected("code")
.on_select(|_, _, _| {}),
)
// The body belongs to the caller: tabs render the strip only.
.child(crate::foundation::text(
&theme,
TypeScale::Body,
"Runs are rendered by the caller, not by the strip.",
))
.child(caption(
&theme,
"the other answer to a strip with no room: it scrolls, and the \
edge with more behind it fades",
))
// Deliberately narrower than its tabs, because a strip that fits shows
// nothing about what a strip that does not fit does.
.child(
div().w(px(300.0)).child(
Tabs::new("scene.tabs.spaces")
.tabs((1..=9).map(|n| {
TabItem::new(format!("space-{n}"), format!("Workspace {n}"))
.icon(Icon::Widget)
}))
.selected("space-5")
.scrolling()
.on_select(|_, _, _| {}),
),
)
.into_any_element()
}