HextaUI

Breadcrumb

Un fil d’Ariane vers la page courante qui passe à la ligne sans risque, s’inverse dans les mises en page de droite à gauche et déploie les segments réduits sur place.

import {
  Breadcrumb,
  BreadcrumbCollapse,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"

export function BreadcrumbDemo() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbCollapse>
          <BreadcrumbItem>
            <BreadcrumbLink href="#">Workspace</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbLink href="#">Design system</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
        </BreadcrumbCollapse>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/breadcrumb.json

Ajoute le composant, les tokens de thème HextaUI et les composants HextaUI dont il dépend.

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
<Breadcrumb>
  <BreadcrumbList>
    <BreadcrumbItem>
      <BreadcrumbLink href="/">Home</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
    </BreadcrumbItem>
  </BreadcrumbList>
</Breadcrumb>
Breadcrumb
└── BreadcrumbList
    ├── BreadcrumbItem
    │   └── BreadcrumbLink
    ├── BreadcrumbSeparator
    ├── BreadcrumbCollapse
    │   ├── BreadcrumbItem
    │   └── BreadcrumbSeparator
    └── BreadcrumbItem
        └── BreadcrumbPage
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"

export function BreadcrumbBasic() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Avec des icônes

Les icônes se placent dans les liens et la page courante. Donnez un aria-label à un lien réduit à une icône.

import { IconFolder, IconHome } from "@tabler/icons-react"

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

export function BreadcrumbWithIcons() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#" aria-label="Home">
            <IconHome />
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">
            <IconFolder />
            Projects
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>
            <IconFolder />
            hextaui
          </BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Séparateur personnalisé

Passez n’importe quel élément comme children de <BreadcrumbSeparator /> pour remplacer le chevron.

import { IconPointFilled } from "@tabler/icons-react"

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

export function BreadcrumbCustomSeparator() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator>
          <IconPointFilled className="size-2" />
        </BreadcrumbSeparator>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator>
          <IconPointFilled className="size-2" />
        </BreadcrumbSeparator>
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Rendez un <BreadcrumbLink /> comme déclencheur d’un <DropdownMenu /> pour proposer des pages sœurs.

import { IconChevronDown } from "@tabler/icons-react"

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function BreadcrumbDropdown() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <DropdownMenu>
            <DropdownMenuTrigger
              render={<BreadcrumbLink render={<button type="button" />} />}
            >
              Components
              <IconChevronDown />
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start">
              <DropdownMenuGroup>
                <DropdownMenuItem>Documentation</DropdownMenuItem>
                <DropdownMenuItem>Themes</DropdownMenuItem>
                <DropdownMenuItem>GitHub</DropdownMenuItem>
              </DropdownMenuGroup>
            </DropdownMenuContent>
          </DropdownMenu>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Replié

Enveloppez les segments du milieu dans <BreadcrumbCollapse />. Ils se cachent derrière des points de suspension et s’ouvrent en glissant sur place, et le focus passe au premier lien révélé. Passez open et onOpenChange pour le contrôler.

"use client"

import * as React from "react"

import {
  Breadcrumb,
  BreadcrumbCollapse,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
import { Button } from "@/components/ui/button"

export function BreadcrumbControlled() {
  const [open, setOpen] = React.useState(false)

  return (
    <div className="flex flex-col items-center gap-4">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink href="#">Home</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbCollapse open={open} onOpenChange={setOpen}>
            <BreadcrumbItem>
              <BreadcrumbLink href="#">Documents</BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbLink href="#">2026</BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
          </BreadcrumbCollapse>
          <BreadcrumbItem>
            <BreadcrumbPage>Invoices</BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>
      <Button variant="outline" size="sm" onClick={() => setOpen(!open)}>
        {open ? "Collapse" : "Expand"}
      </Button>
    </div>
  )
}

Points de suspension

Un <BreadcrumbEllipsis /> statique marque les niveaux omis. Il est masqué aux technologies d’assistance sauf si vous le rendez interactif.

import {
  Breadcrumb,
  BreadcrumbEllipsis,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"

export function BreadcrumbEllipsisDemo() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbEllipsis />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Utilisez la prop render pour remplacer l’ancre par le lien de votre routeur, comme <Link /> de Next.js.

import Link from "next/link"

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

export function BreadcrumbLinkComponent() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink render={<Link href="/" />}>Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink render={<Link href="/docs" />}>Docs</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Contenu long

Les noms sans coupure passent à la ligne au lieu de déborder, et les segments avec une largeur maximale sont tronqués.

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

export function BreadcrumbLongContent() {
  return (
    <div className="flex w-72 flex-col gap-4">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink href="#">Home</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbLink href="#">
              averyveryverylongunbrokenfoldernamethatshouldneverescape
            </BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbPage>
              An unusually long page title that wraps onto a second line
            </BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink href="#">
              <span className="max-w-24 truncate">
                Customer success playbooks
              </span>
            </BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbPage>
              <span className="max-w-32 truncate">
                Onboarding checklist for enterprise accounts
              </span>
            </BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>
    </div>
  )
}

De droite à gauche

Les séparateurs s’inversent et le repli s’anime du bon côté.

import {
  Breadcrumb,
  BreadcrumbCollapse,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"

export function BreadcrumbRtl() {
  return (
    <div dir="rtl">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink href="#">الرئيسية</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbCollapse label="عرض المسار الكامل">
            <BreadcrumbItem>
              <BreadcrumbLink href="#">المكونات</BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbLink href="#">التنقل</BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
          </BreadcrumbCollapse>
          <BreadcrumbItem>
            <BreadcrumbPage>مسار التنقل</BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>
    </div>
  )
}

Les liens et le bouton de repli sont des arrêts de tabulation ordinaires. Les séparateurs et des points de suspension statiques sont ignorés.

ToucheAction
TabShift + TabPasse d’un lien à l’autre et au bouton de repli.
EnterSuit le lien ayant le focus.
EnterSpaceSur le bouton de repli, révèle les segments masqués. Une fois qu’ils ont fini de s’ouvrir en glissant, le focus passe au premier lien révélé.

Chaque partie accepte les attributs de l’élément qu’elle rend, ainsi qu’une prop render pour remplacer cet élément.

PropTypePar défaut
renderÉtiqueté « Breadcrumb » pour les technologies d’assistance.
ReactElement | (props, state) => ReactElement<nav>
AttributDescription
data-slot="breadcrumb"Le repère <nav>.
PropTypePar défaut
render
ReactElement | (props, state) => ReactElement<ol>
AttributDescription
data-slot="breadcrumb-list"La liste ordonnée. Les éléments passent à la ligne lorsque la place manque.
PropTypePar défaut
render
ReactElement | (props, state) => ReactElement<li>
AttributDescription
data-slot="breadcrumb-item"Ciblez les items en CSS.
data-collapsedPrésent tant que l’élément est masqué dans un BreadcrumbCollapse fermé.
data-breadcrumb-groupPrésent sur les éléments d’un BreadcrumbCollapse. Partagé par toutes les parties d’un même groupe.
PropTypePar défaut
href
string–
renderPassez ici le composant de lien de votre routeur.
ReactElement | (props, state) => ReactElement<a>
AttributDescription
data-slot="breadcrumb-link"Ciblez les liens en CSS.
PropTypePar défaut
renderMarquée avec aria-current="page".
ReactElement | (props, state) => ReactElement<span>
AttributDescription
data-slot="breadcrumb-page"La page courante, avec aria-current="page".
PropTypePar défaut
childrenS’inverse automatiquement dans les mises en page de droite à gauche.
ReactNode<IconChevronRight />
render
ReactElement | (props, state) => ReactElement<li>
AttributDescription
data-slot="breadcrumb-separator"Purement visuel et masqué aux technologies d’assistance.
data-collapsedPrésent tant que le séparateur est masqué dans un BreadcrumbCollapse fermé.
data-breadcrumb-groupPrésent sur les séparateurs d’un BreadcrumbCollapse.
PropTypePar défaut
children
ReactNode<IconDots />
renderMasqué aux technologies d’assistance, sauf si render ou onClick le rend interactif.
ReactElement | (props, state) => ReactElement<span>
AttributDescription
data-slot="breadcrumb-ellipsis"Ciblez les points de suspension en CSS.
PropTypePar défaut
childrenLes éléments et séparateurs à masquer derrière les points de suspension.
ReactNode–
open
boolean–
defaultOpen
booleanfalse
onOpenChange
(open: boolean) => void–
labelNom accessible du bouton de points de suspension.
string"Show full path"
AttributDescription
data-slot="breadcrumb-collapse"Le <li> qui contient le bouton de points de suspension.
data-collapsedPrésent sur l’élément de points de suspension une fois le groupe ouvert, ce qui le masque.