Breadcrumbs
ProntoTrilha de navegação hierárquica. Mostra onde o usuário está na árvore + permite voltar ao nível anterior.
Usar quando
Hierarquias profundas (Configurações > Equipe > Membro). Detalhe de processo (Processos > 0001234 > Documentos).
Não usar quando
Páginas top-level (sem hierarquia). Wizards (use Stepper). Lista flat sem profundidade.
Variantes
Microinterações
| Microinteração | Disparada por | Comportamento | Timing |
|---|---|---|---|
| Hover link | mouseenter | inkMuted → ink + underline aparece | 150ms ease |
| Truncate expand | click no ... | Itens ocultos aparecem entre os fixos | 200ms slide |
| Focus ring | Tab | Outline 2px borderInk no link em foco | instant |
Acessibilidade
Acessibilidade — checklist
ARIA esperado
- <nav aria-label="Breadcrumb">
- <ol> com <li> em cada nível
- Último item: aria-current="page"
- Separadores: aria-hidden="true" (decorativos)
Notas
- Use <nav aria-label="Breadcrumb"> para landmark de acessibilidade.
- Último item NÃO é link (você está nele) e tem aria-current="page".
- Truncamento (...) deve ser clicável para expandir.
- Em mobile: mostre só os 2 últimos níveis se overflow.
Código
'use client';
import Link from 'next/link';
import { ChevronRight } from 'lucide-react';
import { T, TYPE } from '@/lib/tokens';
interface Crumb { label: string; href?: string; icon?: React.ComponentType }
export function Breadcrumbs({ items }: { items: Crumb[] }) {
return (
<nav aria-label="Breadcrumb">
<ol style={{ display: 'flex', alignItems: 'center', gap: 6, listStyle: 'none', padding: 0, margin: 0 }}>
{items.map((it, i) => {
const isLast = i === items.length - 1;
return (
<li key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
{i > 0 && <ChevronRight size={12} color={T.inkSubtle} aria-hidden />}
{isLast ? (
<span aria-current="page" style={{ fontSize: TYPE.sm, color: T.ink }}>{it.label}</span>
) : (
<Link href={it.href!} style={{ fontSize: TYPE.sm, color: T.inkMuted }}>{it.label}</Link>
)}
</li>
);
})}
</ol>
</nav>
);
}Regras
Faça
- ✓Use <nav aria-label="Breadcrumb">.
- ✓<ol> + <li> para semantica.
- ✓Último item NÃO é link + aria-current="page".
- ✓Separador ChevronRight pequeno (12px), inkSubtle.
- ✓Em mobile: 2 últimos níveis se truncar.
Não faça
- ✗Não use breadcrumb em páginas sem hierarquia.
- ✗Não torne último item clicável (você JÁ está nele).
- ✗Não use mais de 5-6 níveis sem truncar.
- ✗Não esconda separadores em screen reader (mas eles devem ser aria-hidden).
- ✗Não force fontSize grande (breadcrumb é navegação secundária).
Tokens usados
| Token | Valor | Papel |
|---|---|---|
T.inkMuted | #5A5A5E | links inativos |
T.ink | #0A0A0A | item atual + hover |
T.inkSubtle | #8A8A8D | separador chevron |
TYPE.sm | 12 | fontSize |