Breadcrumb
13 号弱色的路径:链接指针下变粉,当前页是墨色 600,分隔是一个小箭头。
breadcrumb-demo.tsx
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
export default function BreadcrumbDemo() {
return (
<div className="flex flex-col gap-4">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#anime">番剧</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="#season">2026 秋</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>夜樱终电</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#groups">字幕组</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="#releases">资源</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>[喵萌奶茶屋] 夜樱终电 - 06 [1080p]</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</div>
)
}安装
npx shadcn@latest add @anibt/breadcrumb第一次用之前:在 components.json 里登记 @anibt,再单独运行一次 npx shadcn@latest add @anibt/theme(见快速开始)。只有单独安装主题时,CLI 才会把 shadcn 的标准颜色换成白樱 / 夜樱;随组件带进来的主题只补上 AniBT 自己的变量和配方。
手动安装
- 1. 先装主题组件只读
@anibt/theme的 token 和配方,没有主题就没有样子。npx shadcn@latest add @anibt/theme - 2. 安装依赖
npm install lucide-react radix-ui - 3. 把下面的文件放进项目components/ui/breadcrumb.tsx
import * as React from "react" import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react" import { Slot } from "radix-ui" import { cn } from "@/lib/utils" /** * Breadcrumb — the AniBT 「贴纸手账」 trail. * * 13px, muted; a link is `--anibt-ink2` and turns pink under the pointer; the * current page is ink at 600 and not a link. Separators are a small muted * chevron. The trail wraps rather than scrolls; keep it to three or four * steps and fold the middle into `BreadcrumbEllipsis`. * * No washi tape here: the tape is the single "you are here" mark of the main * navigation, and a second one on the same page would compete with it. * * The parts are shadcn's. `BreadcrumbLink` takes `asChild` (Radix) or * `render={<Link … />}` (Base UI) to hand the link to a router. */ function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { return <nav aria-label="面包屑" data-slot="breadcrumb" {...props} /> } function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) { return ( <ol data-slot="breadcrumb-list" className={cn( "flex flex-wrap items-center gap-1.5 text-[13px] leading-5 break-words text-muted-foreground", className )} {...props} /> ) } function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) { return ( <li data-slot="breadcrumb-item" className={cn("inline-flex min-w-0 items-center gap-1.5", className)} {...props} /> ) } function BreadcrumbLink({ asChild = false, render, className, children, ...props }: React.ComponentProps<"a"> & { asChild?: boolean /** Base UI's form of `asChild`: `render={<Link href="…" />}`. */ render?: React.ReactElement }) { const classes = cn( "inline-flex items-center gap-1 rounded-[6px] font-medium text-anibt-ink2 underline-offset-4 outline-hidden transition-colors duration-150 hover:text-accent-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:outline-solid [&>svg]:size-3.5 [&>svg]:shrink-0", className ) if (asChild || render) { const child = render ? (children !== undefined ? React.cloneElement(render, undefined, children) : render) : children return ( <Slot.Root data-slot="breadcrumb-link" className={classes} {...props}> {child} </Slot.Root> ) } return ( <a data-slot="breadcrumb-link" className={classes} {...props}> {children} </a> ) } function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) { return ( <span data-slot="breadcrumb-page" role="link" aria-disabled="true" aria-current="page" className={cn("anibt-ell font-semibold text-foreground", className)} {...props} /> ) } function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<"li">) { return ( <li data-slot="breadcrumb-separator" role="presentation" aria-hidden="true" className={cn("text-muted-foreground/80 [&>svg]:size-3.5", className)} {...props} > {children ?? <ChevronRightIcon />} </li> ) } function BreadcrumbEllipsis({ className, label = "更多", ...props }: React.ComponentProps<"span"> & { label?: string }) { return ( <span data-slot="breadcrumb-ellipsis" role="presentation" aria-hidden="true" className={cn("flex size-5 items-center justify-center [&>svg]:size-4", className)} {...props} > <MoreHorizontalIcon /> <span className="sr-only">{label}</span> </span> ) } export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis, }
用法
用法
import Link from "next/link"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/anime">番剧</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>夜樱终电</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>路径换行,不横滚;保持三四步,中间的折进 BreadcrumbEllipsis。当前页不是链接,太长时省略。
这里不贴和纸胶带:胶带是主导航里唯一的「你在这里」,同一页上再贴一条会和它抢。
路由链接用 asChild(Radix 写法)或 render={<Link href="…" />}(Base UI 写法)。
属性
BreadcrumbLink
asChildboolean默认 false把样式交给唯一的子元素
renderReactElement默认 —Base UI 的写法:渲染成这个元素
BreadcrumbEllipsis
labelstring默认 "更多"给屏幕阅读器的文字
Breadcrumb 的 aria-label 默认是「面包屑」。其余部分与 shadcn 同名,属性透传。
