{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "breadcrumb",
  "type": "registry:ui",
  "title": "Breadcrumb",
  "description": "Show where a page sits in a hierarchy.",
  "categories": [
    "disclosure"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://irisui.dev/r/foundation.json",
    "https://irisui.dev/r/provider.json",
    "https://irisui.dev/r/motion-tokens.json",
    "https://irisui.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "src/registry/components/breadcrumb/breadcrumb.tsx",
      "content": "\"use client\";\nimport type { MouseEvent } from \"react\";\nimport { ChevronRight as NavArrowRight } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { ProvidedLink } from \"../lib/provider\";\nimport { motionTokens } from \"../lib/motion-tokens\";\nimport { cn } from \"../lib/utils\";\nexport interface BreadcrumbItem {\n  label: string;\n  href?: string;\n  /** Runs when the crumb is chosen. Without an href the crumb renders as a button, for paths that live in local state. */\n  onClick?: (event: MouseEvent<HTMLElement>) => void;\n}\nexport interface BreadcrumbProps {\n  items: BreadcrumbItem[];\n  ariaLabel?: string;\n}\n/** Each crumb reserves the width of its medium weight label (a hidden copy in ::after), so becoming the current page never shifts the path. */\nconst crumb =\n  \"inline-flex flex-col rounded-button px-0.5 py-1 after:invisible after:h-0 after:overflow-hidden after:font-medium after:select-none after:pointer-events-none after:content-[attr(data-label)]\";\nconst fade = \"duration-fast ease-standard motion-reduce:transition-none\";\nconst link = cn(\n  crumb,\n  fade,\n  \"text-ink-2 underline decoration-transparent decoration-1 underline-offset-4 transition-[color,text-decoration-color] hover:text-accent-ink hover:decoration-[color-mix(in_oklab,currentColor_45%,transparent)]\",\n);\n/** Crumbs present on first render stay still; crumbs added later slide in from the path before them. */\nexport function Breadcrumb({ items, ariaLabel = \"Breadcrumb\" }: BreadcrumbProps) {\n  const reduced = useReducedMotion() ?? false;\n  const still = { duration: 0 };\n  const path = items.map((item) => item.label).join(\"/\");\n  return (\n    <nav aria-label={ariaLabel}>\n      {/* The gap between crumbs matches the gap inside one, so every chevron sits centered between its two labels. */}\n      <ol className=\"relative m-0 flex list-none flex-wrap items-center gap-x-1.5 gap-y-0.5 p-0\">\n        <AnimatePresence mode=\"popLayout\" initial={false}>\n          {items.map((item, index) => {\n            const current = index === items.length - 1;\n            return (\n              <motion.li\n                key={`${item.label}-${index}`}\n                className=\"inline-flex items-center gap-1.5 text-sm leading-body whitespace-nowrap text-ink-3\"\n                layout={reduced ? false : \"position\"}\n                layoutDependency={path}\n                initial={reduced ? false : { opacity: 0, x: -8, filter: `blur(${motionTokens.blur.subtle}px)` }}\n                animate={{ opacity: 1, x: 0, filter: \"blur(0px)\" }}\n                exit={\n                  reduced\n                    ? { opacity: 0, transition: still }\n                    : {\n                        opacity: 0,\n                        x: -4,\n                        filter: `blur(${motionTokens.blur.subtle}px)`,\n                        transition: { duration: motionTokens.duration.instant, ease: [...motionTokens.ease.standard] },\n                      }\n                }\n                transition={\n                  reduced\n                    ? still\n                    : {\n                        duration: motionTokens.duration.standard,\n                        ease: [...motionTokens.ease.enter],\n                        layout: motionTokens.spring.smooth,\n                      }\n                }\n              >\n                {index > 0 && (\n                  <NavArrowRight\n                    className=\"size-4 flex-none text-line-strong [stroke-width:1.75]\"\n                    width={14}\n                    height={14}\n                    aria-hidden=\"true\"\n                  />\n                )}\n                {!current && item.href ? (\n                  <ProvidedLink className={link} href={item.href} data-label={item.label} onClick={item.onClick}>\n                    {item.label}\n                  </ProvidedLink>\n                ) : !current && item.onClick ? (\n                  <button\n                    type=\"button\"\n                    className={cn(link, \"m-0 cursor-pointer border-0 bg-none text-start\")}\n                    data-label={item.label}\n                    onClick={item.onClick}\n                  >\n                    {item.label}\n                  </button>\n                ) : (\n                  <span\n                    className={cn(crumb, current && cn(fade, \"font-medium text-accent-ink transition-[color]\"))}\n                    aria-current={current ? \"page\" : undefined}\n                    data-label={item.label}\n                  >\n                    {item.label}\n                  </span>\n                )}\n              </motion.li>\n            );\n          })}\n        </AnimatePresence>\n      </ol>\n    </nav>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/iris/breadcrumb/breadcrumb.tsx"
    }
  ],
  "docs": "Docs and live preview: https://irisui.dev/components/breadcrumb",
  "meta": {
    "kind": "component",
    "group": "Overlays & disclosure",
    "export": "Breadcrumb",
    "tags": [
      "navigation",
      "wayfinding"
    ],
    "docs": "https://irisui.dev/components/breadcrumb"
  }
}
