Template
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F22Ms5Cxam5UHyxaCrtZzu
52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
import Link from "next/link";
|
|
|
|
export type Crumb = {
|
|
label: string;
|
|
href?: string;
|
|
};
|
|
|
|
type BreadcrumbsProps = {
|
|
items: Crumb[];
|
|
};
|
|
|
|
/**
|
|
* Server-rendered breadcrumb trail. The last crumb is `aria-current="page"`.
|
|
* Reused by collection, collections, search, and product routes (F13).
|
|
*/
|
|
export function Breadcrumbs({ items }: BreadcrumbsProps) {
|
|
return (
|
|
<nav aria-label="Breadcrumb">
|
|
<ol
|
|
role="list"
|
|
className="text-on-surface-secondary flex flex-wrap items-center gap-1 text-sm"
|
|
>
|
|
<li key="home">
|
|
<Link href="/" className="hover:text-on-surface no-underline">
|
|
Home
|
|
</Link>
|
|
</li>
|
|
{items.map((item, index) => {
|
|
const isLast = index === items.length - 1;
|
|
return (
|
|
<li key={`${item.label}-${index}`} className="flex items-center gap-1">
|
|
<span aria-hidden="true">/</span>
|
|
{item.href && !isLast ? (
|
|
<Link href={item.href} className="hover:text-on-surface no-underline">
|
|
{item.label}
|
|
</Link>
|
|
) : (
|
|
<span
|
|
className="text-on-surface"
|
|
{...(isLast ? { "aria-current": "page" as const } : {})}
|
|
>
|
|
{item.label}
|
|
</span>
|
|
)}
|
|
</li>
|
|
);
|
|
})}
|
|
</ol>
|
|
</nav>
|
|
);
|
|
}
|