react ~4 KB 0 deps v0.1.0 โ†— GitHub โ†—

@mshafiqyajid/react-breadcrumb

Headless breadcrumb hook and styled component. Collapsible items with expand animation, three separator styles, icon support per item, link/button/span rendering, ARIA-compliant.

Playground #

Props
TSX
import { BreadcrumbStyled } from "@mshafiqyajid/react-breadcrumb/styled";
import "@mshafiqyajid/react-breadcrumb/styles.css";

<BreadcrumbStyled />

Install #

npm install @mshafiqyajid/react-breadcrumb

Quick start #

import { BreadcrumbStyled } from "@mshafiqyajid/react-breadcrumb/styled";
import "@mshafiqyajid/react-breadcrumb/styles.css";

const items = [
  { label: "Home", href: "/" },
  { label: "Products", href: "/products" },
  { label: "Smartphones" },
];

<BreadcrumbStyled items={items} />

Separators #

Three built-in separators: "chevron" (โ€บ, default), "slash" (/), and "arrow" (โ†’). You can also pass any ReactNode for a custom separator.

<BreadcrumbStyled items={items} separator="chevron" />
<BreadcrumbStyled items={items} separator="slash" />
<BreadcrumbStyled items={items} separator="arrow" />
<BreadcrumbStyled items={items} separator={<span>ยท</span>} />

Collapsible #

Set maxItems to collapse long breadcrumbs. When collapsed, only the first and last items are shown with an expand button (โ€ฆ) in between. Clicking it reveals all items with a staggered fade-in animation.

<BreadcrumbStyled items={items} maxItems={2} />

Item types #

Each item renders the most semantically appropriate element based on its props:

const items = [
  // <a href="..."> โ€” link
  { label: "Home", href: "/" },

  // <button type="button"> โ€” click handler only
  { label: "Products", onClick: () => navigate("/products") },

  // <span> โ€” no href, no onClick, not last
  { label: "Region" },

  // <span aria-current="page"> โ€” last item is always a span
  { label: "Smartphones" },
];

Icons #

Add an icon to any item. The icon renders before the label.

const items = [
  { label: "Home", href: "/", icon: <HomeIcon /> },
  { label: "Products", href: "/products", icon: <BoxIcon /> },
  { label: "Smartphones" },
];

<BreadcrumbStyled items={items} />

Sizes #

<BreadcrumbStyled items={items} size="sm" />
<BreadcrumbStyled items={items} size="md" />
<BreadcrumbStyled items={items} size="lg" />

Headless #

import { useBreadcrumb } from "@mshafiqyajid/react-breadcrumb";

function MyBreadcrumb({ items }) {
  const {
    navProps,
    visibleItems,
    isCollapsed,
    expand,
    getItemProps,
  } = useBreadcrumb({ items, maxItems: 3 });

  return (
    <nav {...navProps}>
      <ol style={{ display: "flex", gap: "0.5rem", listStyle: "none" }}>
        {visibleItems.map(({ item, originalIndex, isEllipsis }, i) => (
          <li key={isEllipsis ? "e" : originalIndex}>
            {i > 0 && <span aria-hidden="true"> / </span>}
            {isEllipsis ? (
              <button onClick={expand}>โ€ฆ</button>
            ) : getItemProps(originalIndex).isLast ? (
              <span aria-current="page">{item.label}</span>
            ) : item.href ? (
              <a href={item.href}>{item.label}</a>
            ) : (
              <span>{item.label}</span>
            )}
          </li>
        ))}
      </ol>
    </nav>
  );
}

API โ€” BreadcrumbStyled #

PropTypeDefaultDescription
itemsBreadcrumbItem[]โ€”Array of breadcrumb items (required)
separator"chevron" | "slash" | "arrow" | ReactNode"chevron"Separator rendered between items
maxItemsnumberโ€”Collapse to first + ellipsis + last when length exceeds this
expandLabelstring"Show all"Accessible label for the expand button
size"sm" | "md" | "lg""md"Font size
classNamestringโ€”Extra class on the root element
styleCSSPropertiesโ€”Inline style override

API โ€” BreadcrumbItem #

KeyTypeDescription
labelReactNodeItem label (required)
hrefstringIf set, renders an <a> element
onClick() => voidClick handler. Renders <button> when no href
iconReactNodeLeading icon rendered before the label

API โ€” useBreadcrumb #

KeyTypeDescription
navPropsobjectrole="navigation" + aria-label="Breadcrumb"
listPropsobjectProps to spread on the <ol>
visibleItemsVisibleItem[]Items to render (respects collapse state)
isCollapsedbooleanWhether items are currently collapsed
expand() => voidReveal all items
getItemProps(index: number) => objectReturns aria-current, isLast, item for the original index
Edit this page on GitHub