Breadcrumb
Breadcrumb shows the user's current location as a trail of links back through
the site hierarchy, so they can jump up the path without using the browser back
button.
Usage
import { Breadcrumb } from '@takeoff-ui/react-spar';
<Breadcrumb>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link />
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Page />
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb>
Playground
Size
Variant
type="outlined" wraps each crumb in a bordered, backgrounded chip;
type="basic" (the default) is the bare text trail. A label-less (icon-only)
chip opts into tighter padding with the tk-breadcrumb-item-icon-only class —
<Breadcrumb.Item className="tk-breadcrumb-item-icon-only"> — since the
compound API has no label prop to auto-detect it.
Separators
Breadcrumb.Separator defaults to a chevron. The variant prop switches to the
dot, slash, or vertical glyph presets:
Arbitrary content goes through children, which overrides the preset:
Icons
Compose an icon before the label inside Breadcrumb.Link or Breadcrumb.Page —
the recipe sizes direct svg/img children and tones them with the crumb's
text color:
External Link
Routing Integration
onNavigate runs for every Breadcrumb.Link activation (click,
Enter, or Space). Spar prevents the native navigation
before invoking it, so hand the destination straight to your client-side router
— no event.preventDefault() needed. A link-level onPress takes priority and
short-circuits onNavigate when both are set.
Custom link components
Every part is polymorphic via as, so a router's link component can replace the
anchor directly — no onNavigate interception needed:
<Breadcrumb.Link as={Link} to="/flights">
Flights
</Breadcrumb.Link>
Breadcrumb.Item also accepts a render function receiving
{ position, isCurrent, isDisabled } for state-driven content:
<Breadcrumb.Item>
{({ isDisabled }) => <Crumb muted={isDisabled} />}
</Breadcrumb.Item>
Disabled
Setting disabled on the root cascades to every Breadcrumb.Link: it removes
the anchor's href, sets aria-disabled on both the <nav> and each link,
drops the disabled links from the tab order (tabindex="-1"), and surfaces
data-disabled on the trail so theme recipes can tone the colors down.
Long Trails
Crumbs never wrap: labels stay on a single line and the trail scrolls horizontally (with a slim themed scrollbar) when it outgrows its container. The scroll container reserves a small gutter so the focus ring stays fully visible while tabbing through an overflowing trail.
Accessibility & Keyboard
Breadcrumbrenders a<nav>landmark labelled"Breadcrumb"by default; passaria-labelto localize it or scope it to the surrounding page.Breadcrumb.Listis an<ol>, so assistive tech announces the trail as an ordered list.Breadcrumb.Pagemarks the current location witharia-current="page".Breadcrumb.Separatorrenders an<li aria-hidden>so screen readers do not announce the chevron between items.- Links are native
<a>elements, so focus and tab order follow standard anchor semantics. When a routing handler (onNavigateoronPress) is attached, both Enter and Space activate it viaevent.preventDefault(); without one, only native Enter activation applies.
API Reference
Breadcrumb
See Spar Breadcrumb docs for primitive behavior.
Props
| Name | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Breadcrumb.List rendered inside the <nav> landmark. |
| size | BreadcrumbSize | 'base' | Density scale cascaded to every part through context. |
| type | BreadcrumbType | 'basic' | Visual style cascaded to every part through context. |
| classNames | Partial<Record<"root", string>> | - | Per-slot class name overrides. |
| slotProps | Partial<Record<"root", React.HTMLAttributes<HTMLElement>>> | - | Per-slot HTML attribute overrides. |
| className | string | - | Appends custom classes to the root slot of this part. |
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-size | Always | Reflects the resolved size prop so theme recipes can scope size variants. Emitted by the wrapper. |
| data-type | Always | Reflects the resolved type prop (basic | outlined) so theme recipes can scope the visual variant. Emitted by the wrapper. |
| data-disabled | When disabled is true. | Theme hook for the disabled trail. Emitted by Spar, alongside aria-disabled. |
Breadcrumb.List
See Spar Breadcrumb docs for primitive behavior.
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
Breadcrumb.Item
See Spar Breadcrumb docs for primitive behavior.
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-position | Always | "first", "middle", or "last". Emitted by Spar — with the pinned 0.2.0-beta.1 it always resolves to "middle" through this wrapper (position derivation is type-matched on Spar’s own item); the real values arrive with the Spar context-registration release. |
| data-current | Reserved — not emitted at item level with the pinned Spar. | Will mark the current crumb once the Spar context-registration release lands. Until then, style the current crumb via Breadcrumb.Page’s always-emitted data-current. |
Breadcrumb.Link
See Spar Breadcrumb docs for primitive behavior.
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-external | When isExternal is true. | Theme hook for the external link variant. Emitted by Spar. |
| data-disabled | When the link disabled is true, or the root is disabled. | Theme hook for the disabled link state. Emitted by Spar. |
Breadcrumb.Page
See Spar Breadcrumb docs for primitive behavior.
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-current | Always | Marks the current page; emitted by Spar on every Breadcrumb.Page, alongside aria-current="page". |
Breadcrumb.Separator
See Spar Breadcrumb docs for primitive behavior.
Props
| Name | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Override the separator glyph entirely; takes priority over variant. The owner <li aria-hidden> element stays invariant. |
| variant | BreadcrumbSeparatorVariant | 'chevron' | Glyph preset rendered when no children are given. |
| classNames | Partial<Record<"root", string>> | - | Per-slot class name overrides. |
| slotProps | Partial<Record<"root", React.HTMLAttributes<HTMLElement>>> | - | Per-slot HTML attribute overrides. |
| className | string | - | Appends custom classes to the root slot of this part. |
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-variant | Always | Reflects the resolved variant preset (chevron | dot | slash | vertical) so the recipe can paint glyph separators. Emitted by the wrapper. |
Type Definitions
| Name | Definition |
|---|---|
'base' | 'large' | |
'basic' | 'outlined' | |
'chevron' | 'dot' | 'slash' | 'vertical' |