{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "breadcrumbs",
  "title": "Breadcrumbs",
  "description": "A breadcrumb trail for the org, project and environment you are in, collapsing on narrow screens.",
  "dependencies": [
    "@base-ui/react@^1.9.0"
  ],
  "registryDependencies": [
    "https://sproutboat.com/ikada/r/theme.json",
    "https://sproutboat.com/ikada/r/cn.json",
    "https://sproutboat.com/ikada/r/dropdown-menu.json",
    "https://sproutboat.com/ikada/r/icons.json"
  ],
  "files": [
    {
      "path": "registry/ikada/ui/breadcrumbs.tsx",
      "content": "\"use client\";\n\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { Fragment } from \"react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { cn, coarseTarget, focusRing, pressMotion } from \"@/components/ikada/lib/cn\";\nimport { ChevronRightIcon, MoreIcon } from \"@/components/ikada/lib/icons\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from \"@/components/ikada/dropdown-menu\";\n\nexport interface BreadcrumbItem {\n  label: ReactNode;\n  /** Plain text label for the overflow menu when `label` is not a string. */\n  text?: string;\n  /** Stable key. Defaults to `href`, then `text`; give one to every item but the current page when it has neither. */\n  id?: string;\n  href?: string;\n  /** Hand the link to a router: `<RouterLink to=\"/projects\" />`. Used instead of `href`. */\n  render?: useRender.ComponentProps<\"a\">[\"render\"];\n  onClick?: () => void;\n}\n\nexport interface BreadcrumbsProps extends Omit<ComponentProps<\"nav\">, \"children\"> {\n  /** Root first (Org, Project, Environment). The last item is the current page. */\n  items: readonly BreadcrumbItem[];\n  /** Past this many, the middle items collapse into a menu. The first and last always show. */\n  maxItems?: number;\n}\n\nconst linkStyles = cn(\n  \"rounded-xs px-0.5 text-fg-muted transition-colors duration-(--sb-duration-hover) ease-hover hover:text-fg hover:underline hover:underline-offset-4\",\n  coarseTarget,\n  focusRing,\n);\n\nfunction Crumb({ item, current }: { item: BreadcrumbItem; current: boolean }) {\n  // An undefined href would override the one on a router link, so only set it when there is one.\n  const title = typeof item.label === \"string\" ? item.label : item.text;\n  const shared = { onClick: item.onClick, title, className: cn(linkStyles, \"block truncate\"), children: item.label };\n  const linkProps = item.href === undefined ? shared : { ...shared, href: item.href };\n  const link = useRender({\n    defaultTagName: \"a\",\n    render: item.render,\n    enabled: !current && Boolean(item.href ?? item.render),\n    props: linkProps,\n  });\n  if (current) {\n    return (\n      <span aria-current=\"page\" title={title} className=\"block truncate font-medium text-fg\">\n        {item.label}\n      </span>\n    );\n  }\n  return (\n    link ?? (\n      <button type=\"button\" onClick={item.onClick} title={title} className={cn(linkStyles, \"block truncate\")}>\n        {item.label}\n      </button>\n    )\n  );\n}\n\n/** Org > Project > Environment. A long trail collapses its middle into a \"more\" menu. */\nexport function Breadcrumbs({ items, maxItems = 4, className, ref, ...props }: BreadcrumbsProps) {\n  const collapse = items.length > maxItems && maxItems >= 2;\n  const tail = collapse ? items.slice(items.length - (maxItems - 1)) : [];\n  const hidden = collapse ? items.slice(1, items.length - (maxItems - 1)) : [];\n  const shown: (BreadcrumbItem | \"more\")[] = collapse ? [...items.slice(0, 1), \"more\", ...tail] : [...items];\n\n  return (\n    <nav\n      data-slot=\"breadcrumbs\"\n      ref={ref}\n      aria-label=\"Breadcrumb\"\n      className={cn(\"min-w-0 text-sb-base\", className)}\n      {...props}\n    >\n      <ol className=\"flex min-w-0 items-center gap-1\">\n        {shown.map((entry, i) => {\n          const last = i === shown.length - 1;\n          return (\n            <Fragment key={entry === \"more\" ? \"more\" : (entry.id ?? entry.href ?? entry.text ?? \"current\")}>\n              <li className={cn(\"flex min-w-0 items-center\", last ? \"shrink\" : \"shrink-[3]\")}>\n                {entry === \"more\" ? (\n                  <DropdownMenu>\n                    <DropdownMenuTrigger\n                      aria-label={`${hidden.length} more levels`}\n                      className={cn(\n                        \"inline-grid size-7 place-items-center rounded-md text-fg-muted hover:bg-hover hover:text-fg pointer-coarse:size-11\",\n                        pressMotion,\n                        focusRing,\n                      )}\n                    >\n                      <MoreIcon />\n                    </DropdownMenuTrigger>\n                    <DropdownMenuContent align=\"start\">\n                      {hidden.map((h) => (\n                        <DropdownMenuItem\n                          key={h.id ?? h.href ?? h.text}\n                          onClick={h.onClick}\n                          render={\n                            h.render ??\n                            (h.href\n                              ? (props) => (\n                                  <a {...props} href={h.href}>\n                                    {props.children}\n                                  </a>\n                                )\n                              : undefined)\n                          }\n                        >\n                          {h.text ?? h.label}\n                        </DropdownMenuItem>\n                      ))}\n                    </DropdownMenuContent>\n                  </DropdownMenu>\n                ) : (\n                  <Crumb item={entry} current={last} />\n                )}\n              </li>\n              {last ? null : (\n                <li aria-hidden=\"true\" className=\"flex shrink-0 text-fg-muted\">\n                  <ChevronRightIcon className=\"size-3.5 rtl:-scale-x-100\" />\n                </li>\n              )}\n            </Fragment>\n          );\n        })}\n      </ol>\n    </nav>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/ikada/breadcrumbs.tsx"
    }
  ],
  "categories": [
    "navigation"
  ],
  "type": "registry:ui"
}