Separator
Separate content with a horizontal or vertical line.
use herogpui::components::separator::Separator;Separator on docs.rsSource at v0.14.0
Usage
Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.
An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Separator;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.w_full()
.flex()
.flex_col()
.gap(px(12.))
.child(gpui::div().child("Above"))
.child(Separator::new())
.child(gpui::div().child("Below"))An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Separator, Surface};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
Surface::new()
.padding(px(20.))
.gap(px(12.))
.child(gpui::div().child("Notifications"))
.child(Separator::new())
.child(gpui::div().child("Privacy"))An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{ActiveTheme, Separator};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.max_w(px(448.))
.children(
[
("Set Up Notifications", "Receive account activity updates"),
(
"Set up Browser Extension",
"Connect your browser to your account",
),
("Mint Collectible", "Create your first collectible"),
]
.into_iter()
.enumerate()
.map(|(index, (title, subtitle))| {
gpui::div()
.child(
gpui::div()
.flex()
.flex_col()
.child(
gpui::div()
.text_size(px(14.))
.font_weight(gpui::FontWeight::MEDIUM)
.child(title),
)
.child(
gpui::div()
.text_size(px(14.))
.text_color(cx.colors().muted)
.child(subtitle),
),
)
.when(index < 2, |el| el.child(Separator::new().my(px(16.))))
}),
)An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{ActiveTheme, Separator, SeparatorVariant};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(SeparatorVariant::ALL
.iter()
.flat_map(|v| {
vec![
gpui::div()
.text_size(px(12.))
.text_color(cx.colors().muted)
.child(v.label())
.into_any_element(),
Separator::new().variant(*v).into_any_element(),
]
}))An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Orientation, Separator};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.items_center()
.gap(px(12.))
.h(px(24.))
.child("Docs")
.child(Separator::new().orientation(Orientation::Vertical))
.child("Blog")
.child(Separator::new().orientation(Orientation::Vertical))
.child("Support")HeroGPUI extension, not a example: `ResizablePanelGroup` shares its space between `ResizablePanel`s by percentage, with a drag handle between each pair. Drag a handle, or Tab to it and use the arrow keys (Shift for a larger step, Home and End to the limits); each panel stays within its minimum and maximum. The right-hand panel holds a vertical group. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{ActiveTheme, Orientation, ResizablePanel, ResizablePanelGroup, Separator};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, App, SharedString, px};
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
gpui::div()
.w(px(560.))
.h(px(240.))
.rounded(px(12.))
.border_1()
.border_color(cx.colors().border)
.overflow_hidden()
.child(
ResizablePanelGroup::new("separator-resizable-group")
.panel(
ResizablePanel::new()
.default_size(30.)
.min_size(20.)
.max_size(50.)
.child(resizable_pane("Sidebar", cx)),
)
.panel(
ResizablePanel::new().min_size(30.).child(
ResizablePanelGroup::new("separator-resizable-nested")
.orientation(Orientation::Vertical)
.panel(
ResizablePanel::new()
.default_size(65.)
.min_size(25.)
.child(resizable_pane("Editor", cx)),
)
.panel(
ResizablePanel::new()
.min_size(15.)
.child(resizable_pane("Terminal", cx)),
),
),
)
.on_resize({
let view = cx.entity().downgrade();
move |sizes, _, cx| {
let text: Vec<String> = sizes.iter().map(|v| format!("{v:.0}")).collect();
view.update(cx, |this, cx| {
this.resizable_sizes = SharedString::from(text.join(", "));
cx.notify();
})
.ok();
}
}),
)
.into_any_element(),
para(&format!("Sidebar and main, in percent: {}", self.resizable_sizes), cx),
])Also calls resizable_pane, para (included when you copy).
HeroGPUI extension: the sidebar is at least 120px wide whatever the group's width (`min_size_px`) and is `collapsible`. Drag its handle past halfway to its minimum to collapse it and back to expand it, or focus the handle and press Enter to collapse and restore it. `on_resize_end` reports once per gesture, when a drag is released or a key lands, which is where a layout would be saved. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{ActiveTheme, ResizablePanel, ResizablePanelGroup, Separator};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, App, SharedString, px};
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
gpui::div()
.w(px(560.))
.h(px(200.))
.rounded(px(12.))
.border_1()
.border_color(cx.colors().border)
.overflow_hidden()
.child(
ResizablePanelGroup::new("separator-collapsible-group")
.panel(
ResizablePanel::new()
.default_size(25.)
.min_size_px(px(120.))
.max_size(50.)
.collapsible(true)
.child(resizable_pane("Sidebar", cx)),
)
.panel(ResizablePanel::new().child(resizable_pane("Main", cx)))
.on_resize_end({
let view = cx.entity().downgrade();
move |sizes, _, cx| {
let text: Vec<String> = sizes.iter().map(|v| format!("{v:.0}")).collect();
view.update(cx, |this, cx| {
this.resizable_settled = SharedString::from(text.join(", "));
cx.notify();
})
.ok();
}
}),
)
.into_any_element(),
para(&format!("Last settled layout, in percent: {}", self.resizable_settled), cx),
])Also calls resizable_pane, para (included when you copy).
Helpers used by these examples
Plain functions over the public API, defined once here and copied with each example that calls them.
/// One labelled pane of the Resizable Panels demo.
fn resizable_pane(label: &'static str, cx: &gpui::App) -> AnyElement {
gpui::div()
.size_full()
.p(px(12.))
.text_size(px(14.))
.text_color(cx.colors().muted)
.child(label)
.into_any_element()
}fn para(text: &str, cx: &App) -> gpui::AnyElement {
let colors = cx.colors();
gpui::div()
.text_size(px(14.5))
.line_height(px(24.))
.text_color(colors.foreground)
.max_w(px(720.))
.child(text.to_owned())
.into_any_element()
}Anatomy
Rust types
Separator is assembled from these builders. The API reference lists each one.
Customization
Shared appearance belongs on ThemeBuilder::components and .recipe("name"). Typed builders change how Separator looks at one call site. Every builder also carries sx for placement, width and flex: it takes GPUI's own styling methods and refines them over the component's root after the theme, so an instance override wins. Behaviour builders live in the API reference below.
Styling
| Method | Values | Description |
|---|---|---|
orientation(Orientation) | Orientation::Horizontal | Orientation::Vertical | The orientation of the separator. |
variant(SeparatorVariant) | SeparatorVariant::Default | SeparatorVariant::Secondary | SeparatorVariant::Tertiary | The visual variant of the separator. |
// The one slot for caller-owned low-level styling: GPUI's
// styling methods, refined over the root element last.
.sx(|el| {
el.bg(gpui::rgba(0xffa500ff)) // background
.text_color(gpui::rgba(0x000000ff)) // text
.w(gpui::px(13.)) // size
.h(gpui::px(12.))
})API reference
Against HeroUI v3.2.6: 3 entries ported, 1 partial, 2 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.
Builders
| Builder | Values | Default | Description |
|---|---|---|---|
id(Partial | string | — | Optional GPUI identity. AccessKit 0.24 has no Role::Separator, so a named instance still produces no node. |
orientation( | Orientation:: | Orientation:: | The orientation of the separator. |
variant( | SeparatorVariant:: | SeparatorVariant:: | The visual variant of the separator. |
Not ported2 HeroUI entries not ported
| HeroUI v3 | Why it is not ported |
|---|---|
Separator.className | ; gpui has no class-name surface. |
Separator.render | Replaces the element; gpui does not substitute nodes. |
Parts
| Part | Description |
|---|---|
Separator | Root separator primitive and data-slot owner. |