Breadcrumbs
Breadcrumbs are used to display the current page's location within a hierarchy and enable easy navigation.
Installation
Add the following Soul components
The breadcrumbs component uses the streamable, skeleton and animated-link components. Make sure you have added them to your project.
Install the following dependencies
npm install clsx lucide-react
Copy and paste the following code into your project
sections/breadcrumbs/index.tsx
import { clsx } from 'clsx';import { ChevronRight } from 'lucide-react';import { Stream, Streamable } from '@/vibes/soul/lib/streamable';import { AnimatedLink } from '@/vibes/soul/primitives/animated-link';import * as Skeleton from '@/vibes/soul/primitives/skeleton';export interface Breadcrumb { label: string; href: string;}export interface BreadcrumbsProps { breadcrumbs: Streamable<Breadcrumb[]>; className?: string;}/** * This component supports various CSS variables for theming. Here's a comprehensive list, along * with their default values: * * ```css * :root { * --breadcrumbs-font-family: var(--font-family-body); * --breadcrumbs-primary-text: hsl(var(--foreground)); * --breadcrumbs-secondary-text: hsl(var(--contrast-500)); * --breadcrumbs-icon: hsl(var(--contrast-500)); * --breadcrumbs-hover: hsl(var(--primary)); * } * ``` */export function Breadcrumbs({ breadcrumbs: streamableBreadcrumbs, className }: BreadcrumbsProps) { return ( <Stream fallback={<BreadcrumbsSkeleton className={className} />} value={streamableBreadcrumbs}> {(breadcrumbs) => { if (breadcrumbs.length === 0) { return <BreadCrumbEmptyState className={className} />; } return ( <nav aria-label="breadcrumb" className={clsx(className)}> <ol className="flex flex-wrap items-center gap-x-1.5 text-sm @xl:text-base"> {breadcrumbs.map(({ label, href }, index) => { if (index < breadcrumbs.length - 1) { return ( <li className="inline-flex items-center gap-x-1.5" key={href}> <AnimatedLink className="font-[family-name:var(--breadcrumbs-font-family,var(--font-family-body))] text-[var(--breadcrumbs-primary-text,hsl(var(--foreground)))] [background:linear-gradient(0deg,var(--breadcrumbs-hover,hsl(var(--primary))),var(--breadcrumbs-hover,hsl(var(--primary))))_no-repeat_left_bottom_/_0_2px]" href={href} > {label} </AnimatedLink> <ChevronRight aria-hidden="true" className="text-[var(--breadcrumbs-icon,hsl(var(--contrast-500)))]" size={20} strokeWidth={1} /> </li> ); } return ( <li className="inline-flex items-center font-[family-name:var(--breadcrumbs-font-family,var(--font-family-body))] text-[var(--breadcrumbs-secondary-text,hsl(var(--contrast-500)))]" key={href} > <span aria-current="page" aria-disabled="true" role="link"> {label} </span> </li> ); })} </ol> </nav> ); }} </Stream> );}export function BreadcrumbsSkeleton({ className }: Pick<BreadcrumbsProps, 'className'>) { return ( <Skeleton.Root className={clsx('group-has-[[data-pending]]/breadcrumbs:animate-pulse', className)} pending > <div className="flex flex-wrap items-center gap-x-1.5 text-sm @xl:text-base"> <Skeleton.Text characterCount={4} className="rounded text-lg" /> <Skeleton.Icon icon={<ChevronRight aria-hidden className="h-5 w-5" strokeWidth={1} />} /> <Skeleton.Text characterCount={6} className="rounded text-lg" /> <Skeleton.Icon icon={<ChevronRight aria-hidden className="h-5 w-5" strokeWidth={1} />} /> <Skeleton.Text characterCount={6} className="rounded text-lg" /> </div> </Skeleton.Root> );}export function BreadCrumbEmptyState({ className }: Pick<BreadcrumbsProps, 'className'>) { return ( <Skeleton.Root className={className}> <div className={clsx('min-h-[1lh]', className)} /> </Skeleton.Root> );}
Usage
import { Breadcrumbs, type Breadcrumb } from '@/vibes/soul/sections/breadcrumbs';function Usage() { const breadcrumbs: Breadcrumb[] = [ { label: 'Home', href: '#1', }, { label: 'Bags', href: '#2', }, { label: 'Handle Bags', href: '#3', }, ]; return ( <Breadcrumbs breadcrumbs={breadcrumbs} /> );}
API Reference
BreadcrumbsProps
Prop | Type | Default |
---|---|---|
breadcrumbs* | ||
className | string |
Breadcrumb
Prop | Type | Default |
---|---|---|
label | string | |
href | string |
CSS Variables
This component supports various CSS variables for theming. Here's a comprehensive list.
:root { --breadcrumbs-font-family: var(--font-family-body); --breadcrumbs-primary-text: hsl(var(--foreground)); --breadcrumbs-secondary-text: hsl(var(--contrast-500)); --breadcrumbs-icon: hsl(var(--contrast-500)); --breadcrumbs-hover: hsl(var(--primary));}