GPUI Box GitHub

Components / navigation

Sidebar builder

A collapsible navigation rail.

A builder is RenderOnce. Construct and mount it in one expression.

use gpui_kit::navigation::Sidebar;

Reviewed in sidebar sidebar-overflow.

Also drawn by adaptive-navigation, which arranges components rather than reviewing them.

Construct
new(ident: impl Into<Ident>) -> Self
Options

Chain onto the value.

section(section: SidebarSection) -> Self
sections(sections: impl IntoIterator<Item = SidebarSection>) -> Self
active(id: impl Into<SharedString>) -> Self
collapsed(collapsed: bool) -> Self
width(width: f32) -> Self
fill_width() -> Self
fit_height() -> Self
expanded_ids(ids: &[&str]) -> Self
on_toggle(handler: impl Fn(SharedString, bool, &mut Window, &mut App) + 'static) -> Self
on_collapse(handler: impl Fn(bool, &mut Window, &mut App) + 'static) -> Self
header(header: impl IntoElement) -> Self
footer(footer: impl IntoElement) -> Self
on_select(handler: impl Fn(SharedString, &mut Window, &mut App) + 'static) -> Self
Example · sidebar
fn sidebar(_window: &mut Window, cx: &mut App) -> AnyElement {
    if !cx.has_global::<SceneSidebar>() {
        cx.set_global(SceneSidebar::default());
    }
    let theme = cx.theme().clone();
    let active = cx
        .global::<SceneSidebar>()
        .active
        .clone()
        .unwrap_or_else(|| "runs.active".into());
    let collapsed = cx.global::<SceneSidebar>().collapsed;
    let rail = |ident: &'static str, collapsed: bool| {
        Sidebar::new(ident)
            .sections(navigation_sections())
            .active(active.clone())
            .collapsed(collapsed)
            .footer(
                crate::foundation::text(
                    &theme,
                    TypeScale::Caption,
                    if collapsed {
                        SharedString::new_static("v0")
                    } else {
                        SharedString::new_static("Fixture workspace")
                    },
                )
                .text_tone(&theme, TextTone::Faint),
            )
            .on_select(|id, window, cx| {
                cx.global_mut::<SceneSidebar>().active = Some(id);
                window.refresh();
            })
    };

    stack(&theme)
        .child(caption(
            &theme,
            "Fixture navigation — select a destination, toggle a branch, or collapse the rail",
        ))
        .child(
            div()
                .flex()
                .flex_row()
                .h(px(400.0))
                .gap(px(theme.space(Space::Lg)))
                .child(
                    rail("scene.sidebar.expanded", collapsed)
                        .width(260.0)
                        .header(caption(
                            &theme,
                            if collapsed { "W" } else { "Fixture workspace" },
                        ))
                        .on_collapse(|collapsed, window, cx| {
                            cx.global_mut::<SceneSidebar>().collapsed = collapsed;
                            window.refresh();
                        }),
                )
                .child(rail("scene.sidebar.collapsed", true)),
        )
        .child(caption(
            &theme,
            "Current destination is caller-owned; arrow keys move focus without navigating",
        ))
        .into_any_element()
}

Source: crates/gpui-kit/src/navigation/sidebar.rs