Skip to content

Headless Core — Breadcrumb

Powers Breadcrumb internally. The simplest navigation factory — items are just a list you set once (or replace), with no active/inactive toggle beyond which one is current.

import { createBreadcrumb } from '@andersseen/headless-components/breadcrumb';
const breadcrumb = createBreadcrumb({
ariaLabel: 'Breadcrumb',
items: [
{ id: 'home', label: 'Home', href: '/' },
{ id: 'products', label: 'Products', href: '/products' },
{ id: 'detail', label: 'Widget', current: true },
],
onNavigate: item => console.log('Navigate:', item.href),
});
const linkProps = breadcrumb.getLinkProps(item);
OptionTypeDefaultNotes
ariaLabelstring'Breadcrumb'
itemsBreadcrumbItemConfig[][]{ id, label, href?, current? }.
onNavigate(item: BreadcrumbItemConfig) => voidFired by handleKeyDown, not by the link click itself — see below.

items, ariaLabel.

setItems(items) (replaces the list wholesale), setCurrentItem(itemId) (marks exactly one item current: true, un-marking the rest — a convenience over calling setItems yourself with a remapped array).

GetterReturns
getNavProps()role: 'navigation', aria-label
getListProps()role: 'list'
getItemProps(item)aria-current: 'page' (only if item.current), data-state
getLinkProps(item)href (omitted for the current item, even if it has one), aria-current, tabindex (undefined — i.e. natural tab order — unless current, in which case undefined too since a non-link current item usually isn’t focusable at all; only non-current items with an href get tabindex: 0)

This factory has no click handler of its own — a breadcrumb link with a real href navigates natively, so wire onNavigate only if you need to intercept it (e.g. client-side routing): handleKeyDown(event, item) calls onNavigate(item) on Enter/Space, and only for non-current items.

Navbar — for a primary nav that tracks one active item reactively, rather than a static current-page trail.