ComponentsNavigation

Breadcrumb

A path of links that shows where a page or folder sits. Seven small parts you compose yourself, with router links, button crumbs, hidden folders, and one-line trails.

Usage

Breadcrumb usageTSX
import {
  Breadcrumb,
  BreadcrumbEllipsis,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@tulipfarm/sprout/breadcrumb";

<Breadcrumb aria-label="Folder path">
  <BreadcrumbList>
    <BreadcrumbItem>
      <BreadcrumbLink render={<Link to="/files" />}>All files</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbEllipsis />
      <span className="sr-only">Folders you cannot open</span>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbPage truncate>{folder.name}</BreadcrumbPage>
    </BreadcrumbItem>
  </BreadcrumbList>
</Breadcrumb>

Breadcrumb is a nav. Its label defaults to "Breadcrumb"; pass aria-label for paths such as "Folder path" or "Destination path". BreadcrumbList is an ordered list,BreadcrumbItem a list item, and BreadcrumbSeparatora hidden list item with a chevron. Pass children to the separator to use another icon.

Links and buttons

Breadcrumb renderTSX
<BreadcrumbLink href="/home">
  <Home aria-hidden="true" />
  Home
</BreadcrumbLink>

<BreadcrumbLink
  truncate
  render={<Button variant="ghost" size="xs" disabled={moving} onClick={open} />}
>
  {folder.name}
</BreadcrumbLink>

BreadcrumbLink renders an a. The Base UI render prop swaps it for your router's link or a Sprõut Button, such as a ghost xs button inside a picker that does not change the URL. A leading icon is sized to 14px. BreadcrumbPage marks the current step with aria-current="page" and is not clickable.

Long names and one-line trails

Set truncate on a link or page to cut a long name to one line with an ellipsis. String names also get a title with the full name. The width is 12rem; set --sprout-breadcrumb-label-widthon any parent to change it.

The list wraps by default. wrap={false} keeps it on one line, as in an app header: every step keeps its width, and the item with aria-current="page" shrinks. Put the page heading inside that item and truncate it.

Accessibility

BreadcrumbEllipsis and separators are hidden from screen readers. Put the reason in a visually hidden sibling, for example "Higher folders not shown", "Loading folder path", or "Folder path unavailable". Loading spinners, retries, and error messages belong to your application. Links show a focus ring. Separators flip in right-to-left text. Color changes last 120ms and stop when reduced motion is requested.

Theme tokens

Steps use --sprout-muted, the current page and hovered links use --sprout-text, and the focus ring uses --sprout-focus.