Breadcrumbs
Show the path to the current resource.
1use herogpui::components::breadcrumbs::{Breadcrumbs, Crumb};Usage
1use herogpui::prelude::{Breadcrumbs, Crumb};
2use gpui::prelude::*;
3use gpui::px;
4
5gpui::div()
6 .flex()
7 .flex_col()
8 .items_start()
9 .gap(px(12.))
10 .children(vec![
11 // `cx.listener` takes one event argument, and
12 // `on_navigate` receives the index and the crumb
13 // alongside the click, so the view state is reached
14 // through the entity directly.
15 Breadcrumbs::new(crumbs())
16 .id("breadcrumbs")
17 .on_navigate({
18 let view = cx.entity().downgrade();
19 move |idx: usize, crumb: &Crumb, _, _, cx: &mut gpui::App| {
20 let _ = view.update(cx, |this, cx| {
21 this.set_demo_text_value(
22 "bc-nav",
23 format!("{idx}: {}", crumb.label),
24 );
25 cx.notify();
26 });
27 }
28 })
29 .into_any_element(),
30 para(
31 &format!(
32 "The current page is \"Breadcrumbs\" -- inert, no tab stop. \
33 Last navigation: {}",
34 if last_nav.is_empty() {
35 "none yet".to_owned()
36 } else {
37 last_nav
38 }
39 ),
40 cx,
41 ),
42 ])Live HeroGPUI compiled to WebAssembly. Select any example without loading another WASM instance.
Anatomy
Rust types
Breadcrumbs
Breadcrumbs is assembled from these builders. The API reference lists each one.
Customization
Appearance builders and theme tokens Breadcrumbs uses.
Styling
| Style | Description |
|---|---|
root flex items_center | One line, items centred, no wrap. |
text_size(px(14.)) + line_height(px(20.)) + FontWeight::MEDIUM + px(px(2.)) + muted | 14px medium muted link text on a fixed 20px line box with 2px horizontal padding; leading-5 is a fixed height, not a ratio of the text size. |
hover(|s| s.underline()) when navigable | Underline only; the colour stays muted. |
is_last -> current_color colors.link + opacity kept | The current page takes the link token and never the disabled fade. |
row flex + flex_shrink_0 + items_center + justify_center + gap(px(2.)) + px(px(2.)) | A 2px gap between link and separator, 2px of horizontal padding, and content that never compresses when the bar outgrows its parent. |
separator slot size(px(12.)) + text_color(muted) | A 12px muted slot that holds the chevron icon, the slash/dash glyphs or a custom node; gpui has no rtl direction, so the rtl flip has nothing to mirror. |
API reference
Builders
| Builder | Type | Default | Description |
|---|---|---|---|
separator_render( | closure) + separator( | chevron-right icon | Custom separator between breadcrumb items; separator_render is its Rust port — a closure rebuilt for every non-last crumb and painted inside the 12px separator slot — while separator(BreadcrumbSeparator) covers the built-in presets. The closure overrides the preset. |
is_disabled( | bool | false | Whether all breadcrumb links are disabled; disabled crumbs leave the tab order and fade, but the current page keeps opacity-100 as v3's [data-current] rule does. |
new( | items | — | The breadcrumb items; takes a Vec<Crumb> instead of composed Breadcrumbs.Item elements. |
href( | href | — | The URL to link to (omit for the current page); a href crumb opens it through the OS URL handler, with or without an on_navigate callback. |
new( | label | — | Item content or render function; takes a label string per Crumb, so composed children are not supported. |
Parts
| Part | Description |
|---|---|
Breadcrumbs | Root container: one flex line, items centre, no wrap. |
Breadcrumbs | Per-crumb wrapper that hugs its content and holds the link and the trailing separator; draws it from a Crumb, so it is not a composed element. |
States
| Builder | State | Description |
|---|---|---|
is_last -> colors.link + no tab stop + no on_click | Current | The last crumb is the current page: it renders in the link token, is not a tab stop, answers no press even with an href, and never takes the disabled fade. |
hover(|s| s.underline()) when navigable | Hover | Link crumbs underline on hover; the colour stays muted. |
tab_stop_handle per link crumb + ring_if_focused + gpui focused-click | Focus | Every link crumb is a tab stop ( link semantics) and draws the focus-visible status ring when keyboard-focused; mouse focus leaves the ring off. Enter and Space activate the focused crumb through gpui's focused-click, so no second key handler is bound. The current page and disabled crumbs are not tab stops at all. |
is_disabled -> disabled_opacity when !is_last + focus gated on !disabled | Disabled | IsDisabled disables every link: none takes a press, none stays a tab stop, and all of them fade — except the current page, which [data-current] holds at opacity-100. |