# Breadcrumb

Where you are, as a path.

- Group: Navigation
- Import: `import { Breadcrumb } from '@misoto22/folio'`
- Page: https://ui.misoto22.com/components/breadcrumb/
- Related: pagination

## Anatomy

- **Trail** (required) — A <nav> named by label, which defaults to “Breadcrumb”. It is a landmark whether or not the page wanted another one, set in mono-meta at --ink-3-aa.
- **List** (required) — An <ol> — the order is the hierarchy, not the reader’s history. It wraps rather than truncating, so a deep path takes a second line instead of losing a level.
- **Crumb link** — An <a> for every item that has an href and is not the last. The label is a ReactNode, so whatever you put in it becomes part of the link’s accessible name.
- **Current crumb** (required) — The last item, always: plain text at full --ink with aria-current="page", whether or not it was given an href.
- **Separator** — A slash by default, in its own <li aria-hidden> between crumbs. Decorative by construction — it is never part of what is read out.

## Best practices

### Do

- Pass label when a page can hold two trails: both nav landmarks are named “Breadcrumb” otherwise, and two landmarks with one name are two entries a reader cannot choose between.
- Give every crumb but the last an href — one without renders as plain text in the same colour as the links beside it, with no destination and no aria-current, so it reads as the page the reader is on when it is not. Development names the crumb rather than leaving an omission that is invisible in the browser and in review.
- Start the trail above the current page: a one-item Breadcrumb renders that item as the current crumb with no path at all, which is a landmark announcing a journey of length one.

### Don’t

- Leave the href off the last item rather than passing one it ignores: the last crumb is text whatever you hand it, so an href there reads as a link in review and is not one at run time.
- Do not hide it on a phone to save a line. That is the layout where the sidebar is behind a drawer, which makes the trail the only way up a level that is on the screen.

## Accessibility

- The last crumb is text with aria-current="page", never a link to itself.
- Separators are aria-hidden, so the trail is not read as “home slash work slash”.
- A middle crumb with no href takes no aria-current and no colour of its own, which is why the omission is reported in development instead of shipped as a crumb that impersonates the current page.

## Breadcrumb

Where you are, as a path. The last crumb is plain text with `aria-current="page"` rather than a link to itself — a self-link is the most common breadcrumb bug, and it makes a screen reader offer a navigation that goes nowhere. Separators live in `<li aria-hidden>` so the trail is read as its items and not as "home slash work slash". A middle crumb with no `href` is a defect that is invisible twice over: it renders as plain text in the same `--ink-3-aa` as the links beside it, and it carries no `aria-current` either — so it reads as the page the reader is on when it is not, and neither the browser nor a review says a word. The console does, in development.

### Props

- `items` (required) — `Crumb[]`.
- `label` — `string` default `'Breadcrumb'`. Names this trail when a page has more than one.
- `separator` — `ReactNode` default `'/'`. Rendered between crumbs. A slash by default; it is decorative either way.

Also accepts: `HTMLAttributes<HTMLElement>`.

## Example — default

```tsx
import { Breadcrumb } from '@misoto22/folio'

// Named, because the page that documents this component has a breadcrumb
// of its own and two landmarks with one name cannot be told apart.
<Breadcrumb
  label="Example trail"
  items={[
    { label: 'Home', href: '/' },
    { label: 'Components', href: '/components' },
    { label: 'Breadcrumb' },
  ]}
/>
```

## Example — a deep path

```tsx
import { Breadcrumb } from '@misoto22/folio'

<Breadcrumb
  label="Deep trail"
  separator="›"
  className="max-w-xs"
  items={[
    { label: 'Workspace', href: '/' },
    { label: 'Clients', href: '/clients' },
    { label: 'Northwind', href: '/clients/northwind' },
    { label: 'Invoices', href: '/clients/northwind/invoices' },
    { label: '2024-118' },
  ]}
/>
```

## Example — page header

```tsx
import { Breadcrumb, Heading, Text } from '@misoto22/folio'

<div className="flex w-full flex-col gap-4">
  <Breadcrumb
    label="Invoice trail"
    items={[
      { label: 'Clients', href: '/clients' },
      { label: 'Northwind', href: '/clients/northwind' },
      { label: 'Invoice 2024-118' },
    ]}
  />
  <Heading level={2}>Invoice 2024-118</Heading>
  <Text size="sm" tone="muted">
    Issued 4 March, due 3 April. Unpaid.
  </Text>
</div>
```
