SPB Git forge
38commits 1branches 0releases
338.7 MBsize
maindefault branch
4 h agolast push
HTML 53.9% TypeScript 44.5% JavaScript 0.6% SQL 0.5%
1.6 KB · 46 lines tsx
Raw Blame History
1import { ChevronRight } from "lucide-react";2import Link from "next/link";3import { cn } from "@/components/ui/cn";4import { routes } from "@/lib/routes";5import { breadcrumbJsonLd } from "@/lib/seo";6import { JsonLd } from "./json-ld";78export interface Crumb {9  name: string;10  href: string;11}1213/**14 * Breadcrumb trail (Home is implicit). Last item is the current page (not a link). Emits BreadcrumbList JSON-LD.15 * On mobile the trail scrolls horizontally instead of wrapping so the title stays first in view.16 */17export function Breadcrumbs({ items, className }: { items: Crumb[]; className?: string }) {18  const all: Crumb[] = [{ name: "Home", href: routes.home() }, ...items];19  return (20    <>21      <nav aria-label="Breadcrumb" className={cn("-mx-3 overflow-x-auto px-3 no-scrollbar sm:mx-0 sm:px-0", className)}>22        <ol className="flex min-w-max items-center gap-1 text-[12px] text-ink-3">23          {all.map((c, i) => {24            const last = i === all.length - 1;25            return (26              <li key={c.href} className="inline-flex items-center gap-1">27                {i > 0 && <ChevronRight className="size-3 text-ink-4" aria-hidden />}28                {last ? (29                  <span aria-current="page" className="max-w-[60vw] truncate text-ink-2 sm:max-w-[360px] lg:max-w-[560px]">30                    {c.name}31                  </span>32                ) : (33                  <Link href={c.href} className="hover:text-ink hover:underline">34                    {c.name}35                  </Link>36                )}37              </li>38            );39          })}40        </ol>41      </nav>42      <JsonLd data={breadcrumbJsonLd(all)} />43    </>44  );45}46