Split View

A resizable sidebar and content region.

Basic use

Radix · integration snippet
use xgpui_luma_look_radix as radix;
use gpui::{Context};
use gpui::{div, prelude::*};

struct Example {
    control: gpui::Entity<xgpui_luma::controls::split_view::SplitView>,
    sidebar_width: gpui::Pixels,
}

impl Example {
    fn new(cx: &mut Context<Self>) -> Self {
        let look = radix::Look::built_in();
        let control = radix::split_view_builder(&look, "workspace")
            .sidebar(|| div().child("Navigation"))
            .content(|| div().child("Document"))
            .on_sidebar_width_changed(cx, |app, width, cx| {
                app.sidebar_width = width;
                cx.notify();
            })
            .spawn(cx);

        Self { control, sidebar_width: gpui::px(280.0) }
    }
}

Integration snippet, checked against the current SDK and Radix crates. cx is the initialized owner context. The control retains its callbacks; callback owners are held weakly. Render self.control.clone() in the owner’s view.

Radix styling

split_view_builder(&look, id) captures Look motion and initial pane geometry, and resolves separator colors and geometry live. SDK width constraints, collapse/restore, pane renderers, and callbacks remain available.

Pass an explicit Look, including forks. Theme adapters retain that binding; notify affected controls and their owners after palette, mode, or stylesheet edits. Resolved look values are snapshots and must be resolved again during render.

See the Radix control support table for adapter and utility status.

SDK behavior & customization

The SDK coordinates sidebar width and resize events; compose your own region contents.

Relevant contracts: SplitViewRenderModel, SplitViewTemplateHandlers, SplitViewTemplateModifier, SplitViewTemplate.

Use the module’s template contract for structural changes. Builder modifiers and item templates vary by control.

Events

Callbacks follow the existing SDK event stream. Registrations append, hold the owner weakly, and live until the control is released. cx.notify() requests an owner redraw. Compound payloads are borrowed; scalar values are passed by value.

Event / payloadCallback
ResizeStart.on_resize_start(cx, |app, cx| { … })
SidebarWidthChanged { width: Pixels }.on_sidebar_width_changed(cx, |app, width, cx| { … })
ResizeEnd { width: Pixels }.on_resize_end(cx, |app, width, cx| { … })
CollapsedChanged { collapsed: bool }.on_collapsed_changed(cx, |app, collapsed, cx| { … })
SeparatorHoverChanged { hovered: bool }.on_separator_hover_changed(cx, |app, hovered, cx| { … })
EnabledChanged { enabled: bool }.on_enabled_changed(cx, |app, enabled, cx| { … })

Use .on_event(cx, |app, event, cx| { … }) for all events. Factory-created controls support the same callbacks through SplitViewEventExt. Existing cx.subscribe observers remain supported.

Source

SDK module · Radix adapter