Skip to content
63 linesCodeBlameRaw
1import { MoreHorizontal } from "lucide-react";
2import { Slot } from "radix-ui";
3import type { ComponentProps } from "react";
4
5import { cn } from "../../lib/cn";
6
7// shadcn/ui's breadcrumb, styled with g1t's tokens: where you are as a
8// trail of links, the page you are on last and not a link of its own
9// (BreadcrumbPage), with a quiet `/` between. `asChild` on a link puts its
10// look on a router <Link>.
11
12export function Breadcrumb(props: ComponentProps<"nav">) {
13 return <nav aria-label="Breadcrumb" data-slot="breadcrumb" {...props} />;
14}
15
16export function BreadcrumbList({ className, ...props }: ComponentProps<"ol">) {
17 return <ol data-slot="breadcrumb-list" className={cn("flex min-w-0 items-center gap-1 text-sm text-muted", className)} {...props} />;
18}
19
20export function BreadcrumbItem({ className, ...props }: ComponentProps<"li">) {
21 return <li data-slot="breadcrumb-item" className={cn("inline-flex min-w-0 items-center gap-1", className)} {...props} />;
22}
23
24export function BreadcrumbLink({ asChild, className, ...props }: ComponentProps<"a"> & { asChild?: boolean }) {
25 const Comp = asChild ? Slot.Root : "a";
26 return (
27 <Comp
28 data-slot="breadcrumb-link"
29 className={cn("truncate rounded-md px-1.5 py-1 outline-none transition-colors hover:bg-raised hover:text-fg focus-visible:ring-2 focus-visible:ring-accent", className)}
30 {...props}
31 />
32 );
33}
34
35/** The page you are on: the trail's end, in the foreground. */
36export function BreadcrumbPage({ asChild, className, ...props }: ComponentProps<"span"> & { asChild?: boolean }) {
37 const Comp = asChild ? Slot.Root : "span";
38 return (
39 <Comp
40 data-slot="breadcrumb-page"
41 aria-current="page"
42 className={cn("truncate rounded-md px-1.5 py-1 font-medium text-fg outline-none focus-visible:ring-2 focus-visible:ring-accent", className)}
43 {...props}
44 />
45 );
46}
47
48export function BreadcrumbSeparator({ children, className, ...props }: ComponentProps<"li">) {
49 return (
50 <li data-slot="breadcrumb-separator" role="presentation" aria-hidden="true" className={cn("text-line-strong select-none", className)} {...props}>
51 {children ?? "/"}
52 </li>
53 );
54}
55
56export function BreadcrumbEllipsis({ className, ...props }: ComponentProps<"span">) {
57 return (
58 <span data-slot="breadcrumb-ellipsis" role="presentation" aria-hidden="true" className={cn("flex size-8 items-center justify-center", className)} {...props}>
59 <MoreHorizontal size={16} />
60 <span className="sr-only">More</span>
61 </span>
62 );
63}