Kosorikōsori alpha

Breadcrumb

Displays the path to the current resource using a hierarchy of links.

Installation

Copy-paste the component

Copy and paste the component code in a .tsx file.

import { forwardRef } from 'react';
import { ChevronRightIcon, DotsHorizontalIcon } from '@radix-ui/react-icons';
import { Slot } from '@radix-ui/react-slot';
import { clsx } from 'clsx/lite';
import { tv } from 'tailwind-variants';
 
const breadcrumbStyles = tv({
  slots: {
    list: clsx(
      'flex flex-wrap items-center gap-1.5 break-words text-sm text-grey-text',
      'sm:gap-2.5',
    ),
    item: 'inline-flex items-center gap-1.5',
    link: clsx('transition-colors', 'hover:text-grey-text-contrast'),
    separator: '[&>svg]:size-3.5',
    page: 'font-normal text-grey-text-contrast',
    ellipsis: 'flex size-9 items-center justify-center',
    ellipsisIcon: 'size-4',
  },
});
 
const { list, item, link, separator, page, ellipsis, ellipsisIcon } =
  breadcrumbStyles();
 
type BreadcrumbRef = HTMLElement;
type BreadcrumbProps = React.ComponentPropsWithoutRef<'nav'>;
 
/**
 * Breadcrumb component that serves as a navigation aid, indicating the current page's location within a hierarchy.
 *
 * @param {BreadcrumbProps} props - The props for the Breadcrumb component.
 *
 * @example
 * <Breadcrumb>
 *   <BreadcrumbList>
 *     <BreadcrumbItem>
 *       <BreadcrumbLink href='/'>Home</BreadcrumbLink>
 *     </BreadcrumbItem>
 *     <BreadcrumbSeparator />
 *     <BreadcrumbEllipsis className='size-4' />
 *     <BreadcrumbItem>
 *       <BreadcrumbLink href='/docs/ui'>UI</BreadcrumbLink>
 *     </BreadcrumbItem>
 *     <BreadcrumbSeparator />
 *     <BreadcrumbItem>
 *       <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
 *     </BreadcrumbItem>
 *   </BreadcrumbList>
 * </Breadcrumb>
 *
 * @see {@link https://dub.sh/ui-breadcrumb Breadcrumb Docs} for further information.
 */
export const Breadcrumb = forwardRef<BreadcrumbRef, BreadcrumbProps>(
  ({ ...props }, ref) => <nav ref={ref} aria-label='breadcrumb' {...props} />,
);
 
Breadcrumb.displayName = 'Breadcrumb';
 
type BreadcrumbListRef = HTMLOListElement;
type BreadcrumbListProps = React.ComponentPropsWithoutRef<'ol'>;
 
/**
 * BreadcrumbList component that wraps the list of breadcrumb items.
 *
 * @param {BreadcrumbListProps} props - Additional props to pass to the BreadcrumbList component.
 */
export const BreadcrumbList = forwardRef<
  BreadcrumbListRef,
  BreadcrumbListProps
>(({ className, ...props }, ref) => (
  <ol ref={ref} className={list({ className })} {...props} />
));
 
BreadcrumbList.displayName = 'BreadcrumbList';
 
type BreadcrumbItemRef = HTMLLIElement;
type BreadcrumbItemProps = React.ComponentPropsWithoutRef<'li'>;
 
/**
 * BreadcrumbItem component that represents a single item in the breadcrumb trail.
 *
 * @param {BreadcrumbItemProps} props - Additional props to pass to the BreadcrumbItem component.
 */
export const BreadcrumbItem = forwardRef<
  BreadcrumbItemRef,
  BreadcrumbItemProps
>(({ className, ...props }, ref) => (
  <li ref={ref} className={item({ className })} {...props} />
));
 
BreadcrumbItem.displayName = 'BreadcrumbItem';
 
type BreadcrumbLinkRef = HTMLAnchorElement;
type BreadcrumbLinkProps = React.ComponentPropsWithoutRef<'a'> & {
  asChild?: boolean;
};
 
/**
 * BreadcrumbLink component that serves as a clickable link within the breadcrumb.
 *
 * @param {BreadcrumbLinkProps} props - Additional props to pass to the BreadcrumbLink component.
 *
 * @example
 * <BreadcrumbLink href='/'>Home</BreadcrumbLink>
 */
export const BreadcrumbLink = forwardRef<
  BreadcrumbLinkRef,
  BreadcrumbLinkProps
>(({ asChild, className, ...props }, ref) => {
  const Comp = asChild ? Slot : 'a';
 
  return <Comp ref={ref} className={link({ className })} {...props} />;
});
 
BreadcrumbLink.displayName = 'BreadcrumbLink';
 
type BreadcrumbSeparatorProps = React.ComponentPropsWithoutRef<'li'>;
 
/**
 * BreadcrumbSeparator component that visually separates breadcrumb items.
 *
 * @param {BreadcrumbSeparatorProps} props - Additional props to pass to the BreadcrumbSeparator component.
 *
 * @example
 * <BreadcrumbSeparator />
 */
export const BreadcrumbSeparator = ({
  children,
  className,
  ...props
}: BreadcrumbSeparatorProps) => (
  <li
    aria-hidden='true'
    className={separator({ className })}
    role='presentation'
    {...props}
  >
    {children ?? <ChevronRightIcon />}
  </li>
);
 
BreadcrumbSeparator.displayName = 'BreadcrumbSeparator';
 
type BreadcrumbPageRef = HTMLSpanElement;
type BreadcrumbPageProps = React.ComponentPropsWithoutRef<'span'>;
 
/**
 * BreadcrumbPage component that indicates the current page in the breadcrumb trail.
 *
 * @param {BreadcrumbPageProps} props - Additional props to pass to the BreadcrumbPage component.
 *
 * @example
 * <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
 */
export const BreadcrumbPage = forwardRef<
  BreadcrumbPageRef,
  BreadcrumbPageProps
>(({ className, ...props }, ref) => (
  <span
    ref={ref}
    aria-current='page'
    aria-disabled='true'
    className={page({ className })}
    role='link'
    {...props}
  />
));
 
BreadcrumbPage.displayName = 'BreadcrumbPage';
 
type BreadcrumbEllipsisProps = React.ComponentProps<'span'>;
 
/**
 * BreadcrumbEllipsis component that indicates more items in the breadcrumb trail.
 *
 * @param {BreadcrumbEllipsisProps} props - Additional props to pass to the BreadcrumbEllipsis component.
 *
 * @example
 * <BreadcrumbEllipsis />
 */
export const BreadcrumbEllipsis = ({
  className,
  ...props
}: BreadcrumbEllipsisProps) => (
  <span
    aria-hidden='true'
    className={ellipsis({ className })}
    role='presentation'
    {...props}
  >
    <DotsHorizontalIcon className={ellipsisIcon()} />
    <span className='sr-only'>More</span>
  </span>
);
 
BreadcrumbEllipsis.displayName = 'BreadcrumbElipssis';

Update import paths

Update the @kosori/ui import paths to fit your project structure, for example, using ~/components/ui.

Usage

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '~/components/ui/breadcrumb';
<Breadcrumb>
  <BreadcrumbList>
    <BreadcrumbItem>
      <BreadcrumbLink href='/'>Home</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbEllipsis className='h-4 w-4' />
    <BreadcrumbItem>
      <BreadcrumbLink href='/docs/ui'>UI</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
    </BreadcrumbItem>
  </BreadcrumbList>
</Breadcrumb>

On this page