Breadcrumbs
nexvyn/breadcrumbsFreeComponent
A horizontal trail of links that auto-collapses into an ellipsis button when the trail exceeds maxItems.
Live preview
live · rendered by the registry
Rendered by nexvyn on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.nexvyn.dev/r/breadcrumbs.jsonSource
1'use client'23import { forwardRef, useMemo, type HTMLAttributes, type ReactNode } from 'react'4import { cva, type VariantProps } from 'class-variance-authority'5import { cn } from '@/lib/utils'6import { playHoverSound } from '@/lib/sound'78export interface BreadcrumbItem {9 label: ReactNode10 href?: string11 icon?: ReactNode12 title?: string13}1415const breadcrumbVariants = cva('flex items-center', {16 variants: {17 variant: {18 default: '',19 muted: '',20 },21 size: {22 sm: 'text-[11px] gap-1',23 md: 'text-sm gap-1.5',24 lg: 'text-base gap-2',25 },26 },27 defaultVariants: {28 variant: 'default',29 size: 'md',30 },31})3233export interface BreadcrumbsProps34 extends Omit<HTMLAttributes<HTMLElement>, 'color'>, VariantProps<typeof breadcrumbVariants> {35 items: BreadcrumbItem[]36 maxItems?: number37 separator?: ReactNode38 siteUrl?: string39 'aria-label'?: string40 listClassName?: string41}4243const DefaultSeparator = () => (44 <span45 className="inline-flex translate-y-px shrink-0 items-center justify-center text-(--color-subtle)"46 aria-hidden="true"47 >48 <svg49 width="12"50 height="12"51 viewBox="0 0 12 12"52 fill="none"53 stroke="currentColor"54 strokeWidth="1.5"55 strokeLinecap="round"56 strokeLinejoin="round"57 >58 <path d="M4.5 2.5l3 3.5-3 3.5" />59 </svg>60 </span>61)6263export const Breadcrumbs = forwardRef<HTMLElement, BreadcrumbsProps>(64 (65 {66 items,67 maxItems = 4,68 separator,69 siteUrl,70 'aria-label': ariaLabel = 'Breadcrumb',71 variant,72 size,73 className,74 listClassName,75 ...props76 },77 ref,78 ) => {79 const sep = separator ?? <DefaultSeparator />8081 const { visibleItems, collapsedItems } = useMemo(() => {82 if (!maxItems || items.length <= maxItems) {83 return { visibleItems: items, collapsedItems: [] }84 }85 const keep = maxItems - 286 return {87 visibleItems: [items[0], ...items.slice(-keep)],88 collapsedItems: items.slice(1, items.length - keep),89 }90 }, [items, maxItems])9192 const hasEllipsis = collapsedItems.length > 09394 const jsonLd = useMemo(() => {95 if (!siteUrl) return null96 return {97 '@context': 'https://schema.org',98 '@type': 'BreadcrumbList',99 itemListElement: items.map((item, i) => ({100 '@type': 'ListItem',101 position: i + 1,102 name: typeof item.label === 'string' ? item.label : '',103// … truncated
What it pulls in
npm packages
Files it writes
More from nexvyn
All 33 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Badgebadge | nexvyn | Components | Free | 2 deps · 2 files | |
| Bars Themebars-theme | nexvyn | Components | Free | 1 dep · 3 files | |
| Bounce Sidebarbounce-sidebar | nexvyn | Components | Free | 1 dep · 2 files | |
| Checkboxcheckbox | nexvyn | Components | Free | 1 dep · 3 files | |
| Clipboard Fieldclipboard-field | nexvyn | Components | Free | no deps · 2 files | |
| Color Pickercolor-picker | nexvyn | Components | Free | no deps · 16 files | |
| Comboboxcombobox | nexvyn | Components | Free | 1 dep · 2 files | |
| Context Menucontext-menu | nexvyn | Components | Free | 1 dep · 2 files |
