Toolbar

A row of commands and embedded controls.

Try it

Use the Undo, Redo, Bold, Italic, and Save icon buttons, arranged in separated groups. This preview runs the exact code sample shown on this page.

Open example separately ↗

Basic use

Radix · integration snippet
use gpui::Context;
use xgpui_luma::controls::button::ControlIcon;
use xgpui_luma_look_radix as radix;

struct Example {
    control: xgpui_luma::controls::toolbar::Toolbar,
    last_command: String,
}

impl Example {
    fn new(cx: &mut Context<Self>) -> Self {
        let icon = |name: &str| ControlIcon::SvgPath(format!("assets/lucide/{name}.svg").into());
        let control = radix::Toolbar::new("editor")
            .command("undo", "Undo", icon("undo"))
            .command("redo", "Redo", icon("redo"))
            .separator("history-separator")
            .command("bold", "Bold", icon("bold"))
            .command("italic", "Italic", icon("italic"))
            .separator("format-separator")
            .command("save", "Save", icon("save"))
            .on_click(cx, |app: &mut Self, id, cx| {
                app.last_command = id.to_string();
                cx.notify();
            })
            .spawn(cx);
        Self { control, last_command: String::new() }
    }
}

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.

SDK behavior & customization

Compose buttons, toggles, and fields; the toolbar owns its navigation policy.

Relevant contracts: ToolbarItemRenderModel, ToolbarRenderModel, ToolbarTemplateModifier, ToolbarTemplate.

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
Click { id: SharedString }.on_click(cx, |app, id, cx| { … })
Change { id: SharedString, value: ToolbarValue }.on_value_changed(cx, |app, id, value, cx| { … })

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

Source

SDK module · Radix adapter