Skip to content
Glint UI

Breadcrumb

The path to where you are, whose middle collapses into one affordance rather than off the edge of the strip.

Usage

import { Breadcrumb } from "@glint/components/breadcrumb.slint";
import { Tokens } from "@glint/theme/tokens.slint";
export component AppWindow inherits Window {
width: 520px;
height: 120px;
background: Tokens.color-background;
VerticalLayout {
padding: 24px;
alignment: center;
Breadcrumb {
accessible-label: "Breadcrumb";
items: [
{ label: "Home" },
{ label: "Settings" },
{ label: "Billing" },
];
navigate(index) => { debug("go to", index); }
}
}
}

items is the trail, left to right. The last item is where you are: it renders as plain foreground text, takes no tab stop and fires nothing. Every crumb before it is a link that fires navigate with its index.

A BreadcrumbItem carries two fields:

FieldWhat it is
labelThe crumb’s text, and the name assistive technology announces
menuSibling pages hanging off this crumb — a list of MenuSubEntry, the row every Glint menu is built from. Non-empty turns the crumb from a link into a trigger

Following the crumb is yours. The component reports where the reader wanted to go and changes nothing about the trail: items is what you hand it after the route changes.

Examples

The separator

separator is the glyph between two crumbs, and it is a lucide icon rather than a string — the default is IconSet.ChevronRight. An empty Icon draws none and takes no column, which is how a trail turns the glyph off instead of swapping it.

A trail too long to draw

max-visible caps how many crumbs render whole. Past it the middle of the trail leaves the strip and one ellipsis affordance stands where it was, keeping the first crumb and the last max-visible - 1. Two is the floor: a shorter cap would elide the current page along with the middle.

The ellipsis is a control, not a decoration — the run is reachable, not merely gone. Activating it opens the crumbs that left the strip as a picker, and taking one fires navigate with its place in the whole trail, not its place in the picker.

A crumb that opens its siblings

Give a crumb a menu and it stops being a link: it draws a chevron, announces itself expandable, and activating it opens a picker of the sibling pages under it. Taking one fires menu-selected(crumb, row) — never navigate, the way a menu row carrying children never fires itself (ADR-0020). The current page never becomes a trigger.

The rows are plain commands rather than checkable ones. A write into a nested array has nowhere to land in Slint (ADR-0020), which is the same reason MenuSubEntry carries no checkbox state — a picker of destinations is all this is.

Both at once

One picker serves both jobs, so the keyboard, the surface and the highlight are decided once. A trail may elide its middle and still carry menus on the crumbs that stayed.

API Reference

Properties

PropertyTypeDefaultDescription
itemsin [BreadcrumbItem]no defaultCrumbs left-to-right; the last item renders as the current page.
separatorin LucideIconIconSet.ChevronRightGlyph drawn between crumbs. An empty Icon draws none.
max-visiblein int0Longest trail rendered whole; 0 renders every crumb. Past it the middle collapses into the ellipsis.
ellipsis-labelin string@tr("Show hidden crumbs")Name of the ellipsis affordance; override to translate.
highlighted-indexin-out int0Row the keyboard stands on inside an open picker; consumers rarely set this.

Callbacks

CallbackDescription
navigate(int)Fired when a crumb is clicked; argument is its index. A picked row of the ellipsis picker fires it too, with the crumb's place in items.
menu-selected(int , int)Fired with the crumb a picker hung off and the row taken from it.

BreadcrumbItem is a data type rather than a component; its two fields are in Usage above. MenuSubEntry, the row a crumb’s picker draws, is documented on MenuPanel’s page.

Accessibility

  • A navigation landmark. The trail carries accessible-role: navigation; naming it is the call site’s, so a page with a breadcrumb and a header nav tells them apart.
  • Earlier crumbs are named controls. Each is announced by its label, answers the accessible default action, and is a tab stop a keyboard user reaches with Tab. Enter and Space follow the focused crumb.
  • A crumb with a menu says so. It reports accessible-expandable, and accessible-expanded while its picker is open. Enter or Space opens the picker rather than following the crumb.
  • The current page is text. The last crumb declares no role of its own, so it is announced as text and never as a control. It keeps its sizing box and still absorbs the clicks that land on it, so nothing behind the trail receives them.
  • The ellipsis is a control. It is named by ellipsis-label (@tr("Show hidden crumbs") by default), reports itself expandable, and opens the elided run as the same picker.
  • The picker is a list. It carries its row count and every row is a named list item. Inside it, ↑ and ↓ move the highlight and wrap at both ends, Home and End jump to its ends, Enter or Space takes the highlighted row, and Esc closes it — the walk every Glint list surface shares.