Breadcrumb
A typed file path.
Install
$ npx shadcn@latest add https://ephemera.kerrshift.com/r/breadcrumb.jsonOr copy the source below into components/ui/breadcrumb.tsx. Core components need the Paper Theme and Radix where noted.
Usage
example.tsx
import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem><BreadcrumbLink href="/">Drawer</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbLink href="/letters">Letters</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>Dear Sam</BreadcrumbPage></BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| BreadcrumbLink asChild | boolean | — | Use your router's Link. |
| BreadcrumbSeparator children | ReactNode | "›" | Custom separator. |
Any other props are passed to the root element.
Fonts
Components read optional CSS variables and fall back to system fonts: --font-display, --font-receipt, --font-type, --font-hand and --font-stamp. This site uses Fraunces, IBM Plex Mono, Courier Prime, Caveat and Anton.
Source
components/ui/breadcrumb.tsx
import * as React from "react";
import { Slot } from "radix-ui";
const type = { fontFamily: "var(--font-type, 'Courier New', ui-monospace, monospace)" };
/** A typed file path: Drawer › Folder › Letter */
export function Breadcrumb(props: React.HTMLAttributes<HTMLElement>) {
return <nav aria-label="breadcrumb" {...props} />;
}
export function BreadcrumbList({ className = "", style, ...props }: React.OlHTMLAttributes<HTMLOListElement>) {
return (
<ol
className={`flex flex-wrap items-center gap-2 text-[12.5px] uppercase tracking-[0.12em] text-(--ink-muted) ${className}`}
style={{ ...type, ...style }}
{...props}
/>
);
}
export function BreadcrumbItem({ className = "", ...props }: React.LiHTMLAttributes<HTMLLIElement>) {
return <li className={`inline-flex items-center gap-2 ${className}`} {...props} />;
}
export function BreadcrumbLink({
asChild,
className = "",
...props
}: React.AnchorHTMLAttributes<HTMLAnchorElement> & { asChild?: boolean }) {
const Comp = asChild ? Slot.Root : "a";
return (
<Comp
className={`underline decoration-(--ink-faint) decoration-dashed underline-offset-4 transition-colors hover:text-(--ink) hover:decoration-(--pen) hover:decoration-solid ${className}`}
{...props}
/>
);
}
export function BreadcrumbPage({ className = "", ...props }: React.HTMLAttributes<HTMLSpanElement>) {
return <span role="link" aria-disabled="true" aria-current="page" className={`font-bold text-(--ink) ${className}`} {...props} />;
}
export function BreadcrumbSeparator({ children, className = "", ...props }: React.LiHTMLAttributes<HTMLLIElement>) {
return (
<li role="presentation" aria-hidden className={`text-(--ink-faint) ${className}`} {...props}>
{children ?? "›"}
</li>
);
}