Vela UI Docsvenizia.ai

Breadcrumb

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

npx shadcn@latest add @velaui/breadcrumb
npx shadcn@latest add @velaui/breadcrumb

Examples

  • Default
  • With icon
  • Icon outline
  • Slash separator
  • Dot separator
  • Collapsed ellipsis

View code

Breadcrumb · Default

Installation

pnpm dlx velaui add @velaui/breadcrumb
pnpm dlx velaui add @velaui/breadcrumb

Code

breadcrumb-default.tsx
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Products</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Sneakers</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

View code

Breadcrumb · With icon

Installation

pnpm dlx velaui add @velaui/breadcrumb
pnpm dlx velaui add @velaui/breadcrumb

Code

breadcrumb-with-icon.tsx
import { Folder } from "@/components/icons/folder";
import { Home01 } from "@/components/icons/home-01";
import {
  Breadcrumb,
  BreadcrumbIcon,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">
            <BreadcrumbIcon variant="fill">
              <Home01 />
            </BreadcrumbIcon>
            Home
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">
            <BreadcrumbIcon variant="fill">
              <Folder />
            </BreadcrumbIcon>
            Documents
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Report.pdf</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

View code

Breadcrumb · Icon outline

Installation

pnpm dlx velaui add @velaui/breadcrumb
pnpm dlx velaui add @velaui/breadcrumb

Code

breadcrumb-icon-outline.tsx
import { Settings } from "@/components/icons/settings";
import {
  Breadcrumb,
  BreadcrumbIcon,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">
            <BreadcrumbIcon variant="default">
              <Settings />
            </BreadcrumbIcon>
            Settings
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Account</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

View code

Breadcrumb · Slash separator

Installation

pnpm dlx velaui add @velaui/breadcrumb
pnpm dlx velaui add @velaui/breadcrumb

Code

breadcrumb-slash-separator.tsx
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Docs</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator variant="slash" />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Guides</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator variant="slash" />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

View code

Breadcrumb · Dot separator

Installation

pnpm dlx velaui add @velaui/breadcrumb
pnpm dlx velaui add @velaui/breadcrumb

Code

breadcrumb-dot-separator.tsx
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Workspace</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator variant="dot" />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Security</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator variant="dot" />
        <BreadcrumbItem>
          <BreadcrumbPage>API keys</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

View code

Breadcrumb · Collapsed ellipsis

Installation

pnpm dlx velaui add @velaui/breadcrumb
pnpm dlx velaui add @velaui/breadcrumb

Code

breadcrumb-collapsed-ellipsis.tsx
import {
  Breadcrumb,
  BreadcrumbEllipsis,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbEllipsis />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

Usage

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

export default function Example() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#">Products</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Sneakers</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

Props

Breadcrumb

Takes every prop of BreadcrumbProps.

BreadcrumbList

Takes every prop of BreadcrumbListProps.

BreadcrumbItem

Takes every prop of BreadcrumbItemProps.

BreadcrumbLink

PropTypeDefault
asChildboolean—

Takes these and every prop of BreadcrumbLinkProps.

BreadcrumbPage

Takes every prop of BreadcrumbPageProps.

BreadcrumbIcon

PropTypeDefault
variant"fill" | "default"—

Takes these and every prop of BreadcrumbIconProps.

BreadcrumbSeparator

PropTypeDefault
variant"slash" | "chevron" | "dot""chevron"

Takes these and every prop of BreadcrumbSeparatorProps.

BreadcrumbEllipsis

Takes every prop of BreadcrumbEllipsisProps.

Breadcrumb

Takes every prop of BreadcrumbProps.

BreadcrumbList

Takes every prop of BreadcrumbListProps.

BreadcrumbItem

Takes every prop of BreadcrumbItemProps.

BreadcrumbLink

Takes every prop of BreadcrumbLinkProps.

BreadcrumbPage

Takes every prop of BreadcrumbPageProps.

BreadcrumbIcon

PropTypeDefault
variant"fill" | "default"—

Takes these and every prop of BreadcrumbIconProps.

BreadcrumbSeparator

PropTypeDefault
variant"slash" | "chevron" | "dot""chevron"

Takes these and every prop of BreadcrumbSeparatorProps.

BreadcrumbEllipsis

Takes every prop of BreadcrumbEllipsisProps.

Dependencies

npm
class-variance-authority@0.7.1radix-ui@1.6.0
Installs with it
3 icons
npm
@base-ui/react@1.6.0class-variance-authority@0.7.1
Installs with it
3 icons

Source

components/ui/breadcrumb.tsx
/* eslint-disable react-refresh/only-export-components */
import * as React from "react";
import { Slot } from "radix-ui";
import { cva, type VariantProps } from "class-variance-authority";
import { ChevronRight } from "@/components/icons/chevron-right";
import { DotHorizontal } from "@/components/icons/dot-horizontal";
import { Slash01Forward } from "@/components/icons/slash-01-forward";

import { cn } from "@/lib/utils";

export type BreadcrumbProps = React.ComponentProps<"nav">;

function Breadcrumb({ className, ...props }: BreadcrumbProps) {
  return (
    <nav
      aria-label="breadcrumb"
      data-slot="breadcrumb"
      className={cn(className)}
      {...props}
    />
  );
}

export type BreadcrumbListProps = React.ComponentProps<"ol">;

function BreadcrumbList({ className, ...props }: BreadcrumbListProps) {
  return (
    <ol
      data-slot="breadcrumb-list"
      className={cn(
        "flex flex-wrap items-center gap-1.5 text-sm leading-[1.4] wrap-break-word text-text-strong",
        className,
      )}
      {...props}
    />
  );
}

export type BreadcrumbItemProps = React.ComponentProps<"li">;

function BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {
  return (
    <li
      data-slot="breadcrumb-item"
      className={cn("inline-flex items-center gap-0.5", className)}
      {...props}
    />
  );
}

export type BreadcrumbLinkProps = React.ComponentProps<"a"> & {
  asChild?: boolean;
};

function BreadcrumbLink({
  asChild,
  className,
  ...props
}: BreadcrumbLinkProps) {
  const Comp = asChild ? Slot.Root : "a";

  return (
    <Comp
      data-slot="breadcrumb-link"
      className={cn(
        // Hover darkens the crumb text only - the design draws no surface
        // behind the link (state cell: default note -> hover strong).
        "inline-flex items-center gap-0.5 text-text-strong transition-colors hover:text-neutral-950",
        className,
      )}
      {...props}
    />
  );
}

export type BreadcrumbPageProps = React.ComponentProps<"span">;

function BreadcrumbPage({ className, ...props }: BreadcrumbPageProps) {
  return (
    <span
      data-slot="breadcrumb-page"
      role="link"
      aria-disabled="true"
      aria-current="page"
      className={cn(
        "inline-flex items-center gap-0.5 font-normal text-text-note",
        className,
      )}
      {...props}
    />
  );
}

const breadcrumbIconVariants = cva(
  "flex size-5 shrink-0 items-center justify-center p-0.5 [&>svg]:size-4",
  {
    variants: {
      variant: {
        default: "rounded-md",
        fill: "rounded-full bg-bg-surface-1",
      },
    },
    defaultVariants: {
      variant: "fill",
    },
  },
);

export type BreadcrumbIconProps = React.ComponentProps<"span"> &
  VariantProps<typeof breadcrumbIconVariants>;

function BreadcrumbIcon({
  className,
  variant,
  ...props
}: BreadcrumbIconProps) {
  return (
    <span
      data-slot="breadcrumb-icon"
      aria-hidden="true"
      className={cn(breadcrumbIconVariants({ variant }), className)}
      {...props}
    />
  );
}

const breadcrumbSeparatorVariants = cva(
  "flex size-4 shrink-0 items-center justify-center text-icon-note",
  {
    variants: {
      variant: {
        slash: "[&>svg]:size-3",
        chevron: "[&>svg]:size-4",
        dot: "",
      },
    },
    defaultVariants: {
      variant: "chevron",
    },
  },
);

export type BreadcrumbSeparatorProps = React.ComponentProps<"li"> &
  VariantProps<typeof breadcrumbSeparatorVariants>;

function BreadcrumbSeparator({
  children,
  className,
  variant = "chevron",
  ...props
}: BreadcrumbSeparatorProps) {
  return (
    <li
      data-slot="breadcrumb-separator"
      role="presentation"
      aria-hidden="true"
      className={cn(breadcrumbSeparatorVariants({ variant }), className)}
      {...props}
    >
      {children ??
        (variant === "slash" ? (
          <Slash01Forward />
        ) : variant === "dot" ? (
          <span className="size-1 rounded-full bg-current" />
        ) : (
          <ChevronRight />
        ))}
    </li>
  );
}

export type BreadcrumbEllipsisProps = React.ComponentProps<"span">;

function BreadcrumbEllipsis({
  className,
  ...props
}: BreadcrumbEllipsisProps) {
  return (
    <span
      data-slot="breadcrumb-ellipsis"
      role="presentation"
      aria-hidden="true"
      className={cn(
        "flex size-5 items-center justify-center text-icon-note [&>svg]:size-4",
        className,
      )}
      {...props}
    >
      <DotHorizontal />
      <span className="sr-only">More</span>
    </span>
  );
}

export {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbPage,
  BreadcrumbIcon,
  BreadcrumbSeparator,
  BreadcrumbEllipsis,
  breadcrumbIconVariants,
  breadcrumbSeparatorVariants,
};
components/ui/breadcrumb.tsx
/* eslint-disable react-refresh/only-export-components */
import * as React from "react";
import { mergeProps } from "@base-ui/react/merge-props";
import { useRender } from "@base-ui/react/use-render";
import { cva, type VariantProps } from "class-variance-authority";
import { ChevronRight } from "@/components/icons/chevron-right";
import { DotHorizontal } from "@/components/icons/dot-horizontal";
import { Slash01Forward } from "@/components/icons/slash-01-forward";

import { cn } from "@/lib/utils";

export type BreadcrumbProps = React.ComponentProps<"nav">;

function Breadcrumb({ className, ...props }: BreadcrumbProps) {
  return (
    <nav
      aria-label="breadcrumb"
      data-slot="breadcrumb"
      className={cn(className)}
      {...props}
    />
  );
}

export type BreadcrumbListProps = React.ComponentProps<"ol">;

function BreadcrumbList({ className, ...props }: BreadcrumbListProps) {
  return (
    <ol
      data-slot="breadcrumb-list"
      className={cn(
        "flex flex-wrap items-center gap-1.5 text-sm leading-[1.4] wrap-break-word text-text-strong",
        className,
      )}
      {...props}
    />
  );
}

export type BreadcrumbItemProps = React.ComponentProps<"li">;

function BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {
  return (
    <li
      data-slot="breadcrumb-item"
      className={cn("inline-flex items-center gap-0.5", className)}
      {...props}
    />
  );
}

export type BreadcrumbLinkProps = useRender.ComponentProps<"a">;

function BreadcrumbLink({
  className,
  render,
  ...props
}: BreadcrumbLinkProps) {
  return useRender({
    defaultTagName: "a",
    props: mergeProps<"a">(
      {
        className: cn(
          // Hover darkens the crumb text only - the design draws no surface
          // behind the link (state cell: default note -> hover strong).
          "inline-flex items-center gap-0.5 text-text-strong transition-colors hover:text-neutral-950",
          className,
        ),
      },
      props,
    ),
    render,
    state: {
      slot: "breadcrumb-link",
    },
  });
}

export type BreadcrumbPageProps = React.ComponentProps<"span">;

function BreadcrumbPage({ className, ...props }: BreadcrumbPageProps) {
  return (
    <span
      data-slot="breadcrumb-page"
      role="link"
      aria-disabled="true"
      aria-current="page"
      className={cn(
        "inline-flex items-center gap-0.5 font-normal text-text-note",
        className,
      )}
      {...props}
    />
  );
}

const breadcrumbIconVariants = cva(
  "flex size-5 shrink-0 items-center justify-center p-0.5 [&>svg]:size-4",
  {
    variants: {
      variant: {
        default: "rounded-md",
        fill: "rounded-full bg-bg-surface-1",
      },
    },
    defaultVariants: {
      variant: "fill",
    },
  },
);

export type BreadcrumbIconProps = React.ComponentProps<"span"> &
  VariantProps<typeof breadcrumbIconVariants>;

function BreadcrumbIcon({
  className,
  variant,
  ...props
}: BreadcrumbIconProps) {
  return (
    <span
      data-slot="breadcrumb-icon"
      aria-hidden="true"
      className={cn(breadcrumbIconVariants({ variant }), className)}
      {...props}
    />
  );
}

const breadcrumbSeparatorVariants = cva(
  "flex size-4 shrink-0 items-center justify-center text-icon-note",
  {
    variants: {
      variant: {
        slash: "[&>svg]:size-3",
        chevron: "[&>svg]:size-4",
        dot: "",
      },
    },
    defaultVariants: {
      variant: "chevron",
    },
  },
);

export type BreadcrumbSeparatorProps = React.ComponentProps<"li"> &
  VariantProps<typeof breadcrumbSeparatorVariants>;

function BreadcrumbSeparator({
  children,
  className,
  variant = "chevron",
  ...props
}: BreadcrumbSeparatorProps) {
  return (
    <li
      data-slot="breadcrumb-separator"
      role="presentation"
      aria-hidden="true"
      className={cn(breadcrumbSeparatorVariants({ variant }), className)}
      {...props}
    >
      {children ??
        (variant === "slash" ? (
          <Slash01Forward />
        ) : variant === "dot" ? (
          <span className="size-1 rounded-full bg-current" />
        ) : (
          <ChevronRight />
        ))}
    </li>
  );
}

export type BreadcrumbEllipsisProps = React.ComponentProps<"span">;

function BreadcrumbEllipsis({
  className,
  ...props
}: BreadcrumbEllipsisProps) {
  return (
    <span
      data-slot="breadcrumb-ellipsis"
      role="presentation"
      aria-hidden="true"
      className={cn(
        "flex size-5 items-center justify-center text-icon-note [&>svg]:size-4",
        className,
      )}
      {...props}
    >
      <DotHorizontal />
      <span className="sr-only">More</span>
    </span>
  );
}

export {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbPage,
  BreadcrumbIcon,
  BreadcrumbSeparator,
  BreadcrumbEllipsis,
  breadcrumbIconVariants,
  breadcrumbSeparatorVariants,
};