nili/ui
All components

Breadcrumb

Overview
9 exports3 variant axes14 props4 files
import { Breadcrumb, BreadcrumbDivider } from '@nili/ui';

This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.

Basic

A nav landmark holding a trail of links. Mark the last crumb current: it renders as text rather than a link and carries aria-current="page".

import { Breadcrumb, BreadcrumbItem } from "@nili/ui"

export function Example() {
  return (
    <Breadcrumb label={t('nav.label')}>
      <BreadcrumbItem href="#">{t('crumb.home')}</BreadcrumbItem>
      <BreadcrumbItem href="#">{t('crumb.projects')}</BreadcrumbItem>
      <BreadcrumbItem href="#">Nili</BreadcrumbItem>
      <BreadcrumbItem current>{t('crumb.components')}</BreadcrumbItem>
    </Breadcrumb>
  )
}

Dividers

Three built-in separators, or replace them entirely with separator. The divider is decorative and hidden from assistive tech — the list structure carries the nesting.

arrow
slash
dot
custom separator
import { Breadcrumb, BreadcrumbItem } from "@nili/ui"

export function Example() {
  return (
    <>
      <Breadcrumb divider="arrow" label={t('nav.label')}>…</Breadcrumb>
      <Breadcrumb divider="slash" label={t('nav.label')}>…</Breadcrumb>
      <Breadcrumb divider="dot" label={t('nav.label')}>…</Breadcrumb>

      {/* anything you like */}
      <Breadcrumb separator={<span aria-hidden>→</span>} label={t('nav.label')}>…</Breadcrumb>
    </>
  )
}

Icons

icon adds a leading glyph. For an icon-only crumb — a home button at the head of the trail — pass the icon as children and give the link an aria-label.

import { Breadcrumb, BreadcrumbItem, Icon } from "@nili/ui"
import { RiHomeLine, RiFolderLine } from "@remixicon/react"

export function Example() {
  return (
    <Breadcrumb label={t('nav.label')}>
      <BreadcrumbItem href="#" aria-label={t('crumb.home')}>
        <Icon icon={RiHomeLine} />
      </BreadcrumbItem>
      <BreadcrumbItem href="#" icon={<Icon icon={RiFolderLine} />}>
        Projects
      </BreadcrumbItem>
      <BreadcrumbItem current>Nili</BreadcrumbItem>
    </Breadcrumb>
  )
}

Collapsing long trails

maxItems folds the middle into an ellipsis, keeping the first crumb and the last itemsAfterCollapse. A five-level path on a phone either wraps or scrolls, and neither is good.

full trail
maxItems=3
import { Breadcrumb, BreadcrumbItem } from "@nili/ui"

export function Example() {
  return (
    <Breadcrumb maxItems={3} itemsAfterCollapse={1} label={t('nav.label')}>
      <BreadcrumbItem href="#">{t('crumb.home')}</BreadcrumbItem>
      <BreadcrumbItem href="#">{t('crumb.projects')}</BreadcrumbItem>
      <BreadcrumbItem href="#">Nili</BreadcrumbItem>
      <BreadcrumbItem href="#">{t('crumb.components')}</BreadcrumbItem>
      <BreadcrumbItem current>{t('nav.label')}</BreadcrumbItem>
    </Breadcrumb>
  )
}

Router links

asChild renders your element instead of the <a>, so a Next.js or React Router link keeps client-side navigation and still gets the crumb styling and ARIA wiring.

import Link from "next/link"
import { Breadcrumb, BreadcrumbItem } from "@nili/ui"

export function Example() {
  return (
    <Breadcrumb label={t('nav.label')}>
      <BreadcrumbItem asChild>
        <Link href="/">Home</Link>
      </BreadcrumbItem>
      <BreadcrumbItem asChild>
        <Link href="/components">Components</Link>
      </BreadcrumbItem>
      <BreadcrumbItem current>{t('nav.label')}</BreadcrumbItem>
    </Breadcrumb>
  )
}