# Breadcrumb

**When to use:** A trail showing the current page's position within a hierarchy, with links back to each ancestor, such as a file browser path, a category/subcategory drill-down, or a multi-level settings page. The last item is always rendered as the current page and isn't clickable.

**Keywords:** navigation path

**Import:** `import { Breadcrumb } from '@ahrowe/ui'`
**Types:** `import type { BreadcrumbItem, BreadcrumbProps } from '@ahrowe/ui'`

```tsx
import { Breadcrumb } from '@ahrowe/ui';
import type { BreadcrumbItem } from '@ahrowe/ui';

const items: BreadcrumbItem[] = [
  { label: 'Home', href: '/' },
  { label: 'Documents', href: '/documents' },
  { label: 'Report.pdf' }, // last item: rendered as the current page, not a link
];

<Breadcrumb items={items} />

// With leading icons
import { faHouse, faFolder } from '@fortawesome/free-solid-svg-icons';

<Breadcrumb
  items={[
    { label: 'Home', href: '/', icon: faHouse },
    { label: 'Projects', href: '/projects', icon: faFolder },
    { label: 'Current project' },
  ]}
/>

// With a client-side router, set `navigate` once on ConfigProvider (ConfigProvider.md):
// a plain click on a crumb then goes through the router, a middle click still opens a new tab.

// A disabled crumb: dimmed, not clickable, regardless of href/onClick
<Breadcrumb
  items={[
    { label: 'Home', href: '/' },
    { label: 'Archived', href: '/archived', disabled: true },
    { label: 'Old report' },
  ]}
/>

// Custom separator (default is a chevron icon)
<Breadcrumb items={items} separator="/" />

// Long trails: collapse the middle behind a clickable ellipsis once items.length
// exceeds maxItems. The ellipsis counts as one of the visible slots, so maxItems={3}
// on a 4-item trail shows: Home / ... / Settings. Clicking the ellipsis opens a menu
// (via Popover) listing the hidden items.
<Breadcrumb
  items={[
    { label: 'Home', href: '/' },
    { label: 'Invoices', href: '/invoices' },
    { label: 'Editor', href: '/invoices/editor' },
    { label: 'Settings' },
  ]}
  maxItems={3}
/>
```

**BreadcrumbItem:**

| Field | Type | Description |
|-------|------|-------------|
| `id` | `string` | Optional stable key; falls back to the item's index |
| `label` | `ReactNode` | The crumb's text |
| `href` | `string` | Renders the crumb as a real `<a>`, followed through `ConfigProvider`'s `navigate` when it is set. Omit to render a plain clickable element (with `onClick`) or static text |
| `icon` | `IconDefinition \| ReactElement` | Optional leading icon — FontAwesome icon or any React element |
| `onClick` | `(event: MouseEvent) => void` | Click handler. Alongside `href` it runs first, and `event.preventDefault()` stops the link from being followed. Also works on its own, with no `href` |
| `disabled` | `boolean` | Dims the crumb and makes it non-interactive, regardless of `href`/`onClick` |

**Key props:**

| Prop | Type | Description |
|------|------|-------------|
| `items` | `BreadcrumbItem[]` | The crumbs, in order. The last one is always rendered as the current page |
| `separator` | `ReactNode` | Overrides the default chevron separator between items |
| `maxItems` | `number` | Collapses the middle items behind a clickable ellipsis once `items.length` exceeds this. The ellipsis counts as one of the visible slots, alongside the always-shown first item (so `maxItems={3}` shows first item, ellipsis, last item) |

**Collapsing behaviour:** the hidden count grows and shrinks by exactly however many items are actually over the limit, rather than always jumping to the same minimal first/ellipsis/last shape. A trail with 11 items and `maxItems={10}` hides only 2 items, not the whole middle, so the trail doesn't visually lurch as one more level of navigation pushes it just over the limit.

**Global defaults:** adopts `ConfigProvider`, e.g. `defaultProps={{ Breadcrumb: { separator: '/' } }}`. See [ConfigProvider.md](ConfigProvider.md).

**Slots:** `root` `list` `item` `link` `icon` `separator` `current` `ellipsis` `hiddenList` `hiddenItem`

**Labels:** `showHidden` — the text this component renders of its own. Pass `labels` to override any of them, on the component or app-wide through `ConfigProvider`; they merge per key. Type: `BreadcrumbLabels`.
