Propel

Breadcrumb

Shows the path to the current page as a trail of navigable crumbs.

Show code
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";

export default function BasicDemo() {
  return (
    <Breadcrumb aria-label="Breadcrumb">
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Plane" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Projects" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Design" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage label="Work items" />
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

Installation

import {
  Breadcrumb,
  BreadcrumbEllipsisTrigger,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbMenuTrigger,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";

Usage

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";

export default function BasicDemo() {
  return (
    <Breadcrumb aria-label="Breadcrumb">
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Plane" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Projects" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Design" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage label="Work items" />
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

Examples

With icon

BreadcrumbLink and BreadcrumbPage take an optional leading icon; the crumb sizes it to 16×16, so the <Icon> needs no size.

Show code
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";
import { Icon } from "@makeplane/propel/components/icon";
import { FileText, Layers } from "lucide-react";

export default function WithIconDemo() {
  return (
    <Breadcrumb aria-label="Breadcrumb">
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink
            href="#"
            onClick={(event) => event.preventDefault()}
            icon={<Icon icon={Layers} tint="secondary" />}
            label="Plane Design"
          />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage icon={<Icon icon={FileText} tint="secondary" />} label="Work items" />
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

Collapsed crumbs

When the trail grows too long, collapse the middle crumbs behind an ellipsis menu that opens the hidden crumbs.

Show code
import {
  Breadcrumb,
  BreadcrumbEllipsisTrigger,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";
import { Menu, MenuContent, MenuItem } from "@makeplane/propel/components/menu";

export default function CollapsedCrumbsDemo() {
  return (
    <Breadcrumb aria-label="Breadcrumb">
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Plane" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <Menu>
            <BreadcrumbEllipsisTrigger aria-label="Show more breadcrumbs" />
            <MenuContent sizing="auto">
              <MenuItem label="Projects" />
              <MenuItem label="Design" />
            </MenuContent>
          </Menu>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Components" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage label="Breadcrumb" />
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

A crumb whose label opens a menu to switch the current step between sibling contexts without leaving the trail. Its own chevron is the breadcrumb chevron, so no separator follows it.

Show code
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbMenuTrigger,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";
import { Icon } from "@makeplane/propel/components/icon";
import { Menu, MenuContent, MenuItem } from "@makeplane/propel/components/menu";
import { Layers } from "lucide-react";

export default function MenuCrumbDemo() {
  return (
    <Breadcrumb aria-label="Breadcrumb">
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Plane" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <Menu>
            <BreadcrumbMenuTrigger
              icon={<Icon icon={Layers} tint="tertiary" size="md" />}
              label="Plane Design"
            />
            <MenuContent>
              <MenuItem label="Plane Web" />
              <MenuItem label="Plane Mobile" />
              <MenuItem label="Plane Server" />
            </MenuContent>
          </Menu>
        </BreadcrumbItem>
        <BreadcrumbItem>
          <BreadcrumbPage label="Components" />
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

View switcher

The menu crumb composes propel’s Menu rows, so it supports a single-select list — the active view carries selected and shows the leading check.

Show code
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbMenuTrigger,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@makeplane/propel/components/breadcrumb";
import { Menu, MenuContent, MenuItem } from "@makeplane/propel/components/menu";

export default function ViewSwitcherDemo() {
  return (
    <Breadcrumb aria-label="Breadcrumb">
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#" onClick={(event) => event.preventDefault()} label="Plane" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage label="Work items" />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <Menu>
            <BreadcrumbMenuTrigger label="List" />
            <MenuContent>
              <MenuItem selected label="List" />
              <MenuItem label="Board" />
              <MenuItem label="Calendar" />
              <MenuItem label="Spreadsheet" />
            </MenuContent>
          </Menu>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

API Reference

Breadcrumb

Breadcrumb trail landmark: a `<nav>` wrapping a `BreadcrumbList`. Requires an `aria-label` (its landmark name, conventionally "Breadcrumb") — the consumer supplies it so it can be localized.

PropTypeDefaultDescription
aria-label(required)string
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.

BreadcrumbLink

A navigable crumb — an anchor styled as a hoverable pill, laying out an optional leading icon and the label. Pass `render` to use a router link.

PropTypeDefaultDescription
label(required)stringThe crumb label.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
iconReactNodeLeading icon before the label, e.g. `<Icon icon={Layers} tint="secondary" />`. Renders 16×16 — the crumb sets `--node-size`, so the `<Icon>` needs no `size`.

BreadcrumbPage

The current page — the last, non-navigable crumb (`aria-current="page"`), laying out an optional leading icon and the label.

PropTypeDefaultDescription
label(required)stringThe current-page label.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
iconReactNodeLeading icon before the label, e.g. `<Icon icon={FileText} tint="secondary" />`. Renders 16×16 — the crumb sets `--node-size`, so the `<Icon>` needs no `size`.

BreadcrumbMenuTrigger

The crumb that opens a `BreadcrumbMenu`.

PropTypeDefaultDescription
label(required)stringThe crumb label. Required — it is the trigger's accessible name (the icon and caret are decorative).
iconReactNodeLeading icon, e.g. `<Icon icon={Layers} tint="secondary" />` (renders 16×16 via the crumb's `--node-size`).

BreadcrumbEllipsisTrigger

The icon-only crumb standing in for collapsed crumbs — grafts Base UI's `Menu.Trigger` onto the styled `BreadcrumbTrigger`, with an ellipsis glyph by default (defaults are a `components` concern). Unlike `BreadcrumbMenuTrigger` it carries no label and no chevron indicator: a `BreadcrumbSeparator` follows it in the trail. Place a `MenuContent` of the hidden crumbs as its sibling inside a `Menu`.

PropTypeDefaultDescription
aria-labelstringDefines a string value that labels the current element. Accessible name for the trigger (e.g. "Show more breadcrumbs"). Required (icon-only). @see aria-labelledby.
iconReactNodean ellipsisThe glyph shown inside the trigger.