{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "breadcrumb",
  "type": "registry:ui",
  "title": "Breadcrumb",
  "description": "Location hierarchy navigation with labelled nav semantics, ordered list anatomy, current-page state, tokenized separators and sizes, router composition, responsive truncation, and optional Popover-backed overflow for hidden ancestors.",
  "dependencies": [
    "react-aria-components@^1.21.1"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://components.dethink.co.uk/r/dethink-base.json",
    "https://components.dethink.co.uk/r/popover.json"
  ],
  "files": [
    {
      "path": "packages/components/src/components/breadcrumb/breadcrumb.tsx",
      "type": "registry:file",
      "target": "~/components/dethink/components/breadcrumb/breadcrumb.tsx",
      "content": "import {\n  Children,\n  cloneElement,\n  createContext,\n  forwardRef,\n  isValidElement,\n  useContext,\n  type AnchorHTMLAttributes,\n  type ButtonHTMLAttributes,\n  type HTMLAttributes,\n  type LiHTMLAttributes,\n  type MouseEventHandler,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTitle,\n  PopoverTrigger,\n} from \"../popover\";\nimport { cn } from \"../../utils/cn\";\n\nexport type BreadcrumbSize = \"sm\" | \"md\" | \"lg\";\nexport type BreadcrumbSeparatorVariant = \"chevron\" | \"slash\" | \"dot\" | \"none\";\nexport type BreadcrumbCollapseFrom = \"start\" | \"middle\" | \"end\";\n\nexport interface BreadcrumbItemData {\n  key: string;\n  label: ReactNode;\n  textValue?: string;\n  href?: string;\n  current?: boolean;\n  disabled?: boolean;\n  icon?: ReactNode;\n  onAction?: () => void;\n}\n\nexport interface BreadcrumbProps extends Omit<\n  HTMLAttributes<HTMLElement>,\n  \"children\"\n> {\n  children?: ReactNode;\n  collapseFrom?: BreadcrumbCollapseFrom;\n  items?: BreadcrumbItemData[];\n  maxItems?: number;\n  overflowLabel?: string;\n  preserveCurrent?: boolean;\n  preserveRoot?: boolean;\n  separator?: BreadcrumbSeparatorVariant | ReactNode;\n  size?: BreadcrumbSize;\n}\n\nexport interface BreadcrumbListProps extends HTMLAttributes<HTMLOListElement> {}\n\nexport interface BreadcrumbItemProps extends LiHTMLAttributes<HTMLLIElement> {\n  current?: boolean;\n  disabled?: boolean;\n}\n\ntype BreadcrumbLinkBaseProps = {\n  asChild?: boolean;\n  current?: boolean;\n  disabled?: boolean;\n  icon?: ReactNode;\n  rel?: string;\n  target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n};\n\ntype NativeBreadcrumbLinkProps = Omit<\n  AnchorHTMLAttributes<HTMLAnchorElement>,\n  \"children\" | \"href\"\n> &\n  BreadcrumbLinkBaseProps & {\n    asChild?: false;\n    children: ReactNode;\n    href: string;\n    onAction?: never;\n  };\n\ntype ActionBreadcrumbLinkProps = Omit<\n  ButtonHTMLAttributes<HTMLButtonElement>,\n  \"children\" | \"disabled\" | \"type\"\n> &\n  BreadcrumbLinkBaseProps & {\n    asChild?: false;\n    children: ReactNode;\n    href?: undefined;\n    onAction: () => void;\n  };\n\ntype ChildBreadcrumbLinkProps = Omit<\n  AnchorHTMLAttributes<HTMLAnchorElement>,\n  \"children\" | \"href\"\n> &\n  BreadcrumbLinkBaseProps & {\n    asChild: true;\n    children: ReactElement<BreadcrumbLinkSlotProps>;\n    href?: string;\n    onAction?: () => void;\n  };\n\nexport type BreadcrumbLinkProps =\n  | NativeBreadcrumbLinkProps\n  | ActionBreadcrumbLinkProps\n  | ChildBreadcrumbLinkProps;\n\nexport interface BreadcrumbPageProps extends HTMLAttributes<HTMLSpanElement> {\n  current?: boolean;\n  icon?: ReactNode;\n}\n\nexport interface BreadcrumbSeparatorProps extends HTMLAttributes<HTMLSpanElement> {\n  separator?: BreadcrumbSeparatorVariant | ReactNode;\n}\n\nexport interface BreadcrumbEllipsisProps extends HTMLAttributes<HTMLSpanElement> {}\n\nexport interface BreadcrumbOverflowProps extends Omit<\n  HTMLAttributes<HTMLDivElement>,\n  \"children\"\n> {\n  items: BreadcrumbItemData[];\n  label?: string;\n  size?: BreadcrumbSize;\n}\n\ntype BreadcrumbLinkSlotProps = Record<string, unknown> & {\n  children?: ReactNode;\n  className?: string;\n  href?: string;\n  onClick?: MouseEventHandler<HTMLElement>;\n  ref?: Ref<HTMLElement>;\n  rel?: string;\n  target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n  \"aria-current\"?: AnchorHTMLAttributes<HTMLAnchorElement>[\"aria-current\"];\n  \"aria-disabled\"?: AnchorHTMLAttributes<HTMLAnchorElement>[\"aria-disabled\"];\n};\n\ntype BreadcrumbContextValue = {\n  separator: BreadcrumbSeparatorVariant | ReactNode;\n  size: BreadcrumbSize;\n};\n\ntype NormalizedBreadcrumbItem = BreadcrumbItemData & {\n  current: boolean;\n  index: number;\n};\n\nexport type BreadcrumbRenderItem =\n  | {\n      type: \"item\";\n      item: NormalizedBreadcrumbItem;\n    }\n  | {\n      type: \"overflow\";\n      items: NormalizedBreadcrumbItem[];\n    };\n\ninterface BreadcrumbWindowOptions {\n  collapseFrom?: BreadcrumbCollapseFrom;\n  maxItems?: number;\n  preserveCurrent?: boolean;\n  preserveRoot?: boolean;\n}\n\nconst BreadcrumbContext = createContext<BreadcrumbContextValue>({\n  separator: \"chevron\",\n  size: \"md\",\n});\n\nconst breadcrumbRootClasses = \"max-w-full text-muted-foreground\";\n\nconst breadcrumbListClasses =\n  \"m-0 flex min-w-0 list-none flex-wrap items-center gap-y-[var(--dt-space-1)] p-0\";\n\nconst breadcrumbItemClasses =\n  \"flex min-w-0 max-w-full items-center data-[current=true]:text-foreground data-[disabled=true]:opacity-60\";\n\nconst breadcrumbLinkBaseClasses =\n  \"group/breadcrumb-link inline-flex max-w-full min-w-0 items-center rounded-sm font-medium text-muted-foreground no-underline outline-none transition-[color,background-color,box-shadow] duration-150 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background active:text-foreground data-[current=true]:text-foreground data-[current=true]:font-semibold data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-60\";\n\nconst breadcrumbPageBaseClasses =\n  \"inline-flex max-w-full min-w-0 items-center rounded-sm font-medium text-foreground\";\n\nconst breadcrumbTextClasses = \"min-w-0 truncate\";\n\nconst breadcrumbIconClasses =\n  \"me-[var(--dt-space-1)] flex size-4 shrink-0 items-center justify-center text-muted-foreground group-data-[current=true]/breadcrumb-link:text-foreground [&>svg]:size-4\";\n\nconst breadcrumbSeparatorClasses =\n  \"mx-[var(--dt-space-1-5)] inline-flex shrink-0 items-center justify-center text-muted-foreground/70\";\n\nconst breadcrumbEllipsisClasses =\n  \"inline-flex min-w-4 items-center justify-center font-semibold tracking-normal text-muted-foreground\";\n\nconst breadcrumbOverflowTriggerClasses =\n  \"size-8 rounded-sm px-0 text-muted-foreground hover:text-foreground\";\n\nconst breadcrumbOverflowContentClasses =\n  \"w-[var(--dt-breadcrumb-overflow-width,14rem)] p-[var(--dt-space-1)]\";\n\nconst breadcrumbOverflowListClasses =\n  \"m-0 grid max-h-[min(18rem,calc(100dvh_-_var(--dt-space-4)))] list-none gap-0 overflow-auto p-0\";\n\nconst breadcrumbOverflowItemClasses = \"min-w-0\";\n\nconst breadcrumbOverflowLinkClasses =\n  \"flex w-full min-w-0 items-center gap-[var(--dt-space-2)] rounded-sm px-[var(--dt-space-2)] py-[var(--dt-space-1-5)] text-start text-sm leading-5 text-foreground no-underline outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-60\";\n\nconst breadcrumbSizeClasses: Record<BreadcrumbSize, string> = {\n  sm: \"text-xs leading-5\",\n  md: \"text-sm leading-6\",\n  lg: \"text-base leading-7\",\n};\n\nconst breadcrumbLinkSizeClasses: Record<BreadcrumbSize, string> = {\n  sm: \"min-h-7 gap-[var(--dt-space-1)]\",\n  md: \"min-h-8 gap-[var(--dt-space-1)]\",\n  lg: \"min-h-9 gap-[var(--dt-space-1-5)]\",\n};\n\nexport function breadcrumbClassNames({\n  className,\n  size = \"md\",\n}: Pick<BreadcrumbProps, \"className\" | \"size\"> = {}) {\n  return cn(breadcrumbRootClasses, breadcrumbSizeClasses[size], className);\n}\n\nexport function breadcrumbListClassNames({\n  className,\n}: Pick<BreadcrumbListProps, \"className\"> = {}) {\n  return cn(breadcrumbListClasses, className);\n}\n\nexport function breadcrumbItemClassNames({\n  className,\n}: Pick<BreadcrumbItemProps, \"className\"> = {}) {\n  return cn(breadcrumbItemClasses, className);\n}\n\nexport function breadcrumbLinkClassNames({\n  className,\n  size = \"md\",\n}: Pick<BreadcrumbLinkProps, \"className\"> & { size?: BreadcrumbSize } = {}) {\n  return cn(\n    breadcrumbLinkBaseClasses,\n    breadcrumbLinkSizeClasses[size],\n    className,\n  );\n}\n\nexport function breadcrumbPageClassNames({\n  className,\n  size = \"md\",\n}: Pick<BreadcrumbPageProps, \"className\"> & { size?: BreadcrumbSize } = {}) {\n  return cn(\n    breadcrumbPageBaseClasses,\n    breadcrumbLinkSizeClasses[size],\n    className,\n  );\n}\n\nexport function breadcrumbSeparatorClassNames({\n  className,\n}: Pick<BreadcrumbSeparatorProps, \"className\"> = {}) {\n  return cn(breadcrumbSeparatorClasses, className);\n}\n\nexport function breadcrumbEllipsisClassNames({\n  className,\n}: Pick<BreadcrumbEllipsisProps, \"className\"> = {}) {\n  return cn(breadcrumbEllipsisClasses, className);\n}\n\nexport function breadcrumbOverflowClassNames({\n  className,\n}: Pick<BreadcrumbOverflowProps, \"className\"> = {}) {\n  return cn(\"contents\", className);\n}\n\nfunction setRef<T>(ref: Ref<T> | undefined, node: T | null) {\n  if (typeof ref === \"function\") {\n    ref(node);\n    return;\n  }\n\n  if (ref) {\n    ref.current = node;\n  }\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      setRef(ref, node);\n    }\n  };\n}\n\nfunction composeClickHandlers(\n  componentHandler: MouseEventHandler<HTMLElement>,\n  childHandler: MouseEventHandler<HTMLElement> | undefined,\n) {\n  return (event: React.MouseEvent<HTMLElement>) => {\n    componentHandler(event);\n\n    if (!event.defaultPrevented) {\n      childHandler?.(event);\n    }\n  };\n}\n\nfunction getChildRef(child: ReactElement<BreadcrumbLinkSlotProps>) {\n  return child.props.ref;\n}\n\nfunction mergeRelForTarget(\n  rel: string | undefined,\n  target: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"] | undefined,\n) {\n  if (target !== \"_blank\") {\n    return rel;\n  }\n\n  const tokens = new Set((rel ?? \"\").split(/\\s+/).filter(Boolean));\n  tokens.add(\"noopener\");\n\n  return Array.from(tokens).join(\" \");\n}\n\nfunction resolveAriaCurrent(\n  ariaCurrent: AnchorHTMLAttributes<HTMLAnchorElement>[\"aria-current\"],\n  current: boolean | undefined,\n) {\n  if (ariaCurrent !== undefined) {\n    return ariaCurrent;\n  }\n\n  return current ? (\"page\" as const) : undefined;\n}\n\nfunction hasCurrentState(\n  ariaCurrent: AnchorHTMLAttributes<HTMLAnchorElement>[\"aria-current\"],\n) {\n  return (\n    ariaCurrent !== undefined &&\n    ariaCurrent !== false &&\n    ariaCurrent !== \"false\"\n  );\n}\n\nfunction normalizeItems(\n  items: BreadcrumbItemData[],\n): NormalizedBreadcrumbItem[] {\n  if (items.length === 0) {\n    return [];\n  }\n\n  const explicitCurrentIndex = items.findIndex((item) => item.current);\n  const fallbackCurrentIndex = items.length - 1;\n  const currentIndex =\n    explicitCurrentIndex === -1 ? fallbackCurrentIndex : explicitCurrentIndex;\n\n  return items.map((item, index) => ({\n    ...item,\n    current: index === currentIndex,\n    index,\n  }));\n}\n\nfunction isNormalizedBreadcrumbItem(\n  item: BreadcrumbItemData,\n): item is NormalizedBreadcrumbItem {\n  return \"index\" in item && typeof item.current === \"boolean\";\n}\n\nfunction normalizeOverflowItems(\n  items: BreadcrumbItemData[],\n): NormalizedBreadcrumbItem[] {\n  return items.map((item, index) =>\n    isNormalizedBreadcrumbItem(item)\n      ? item\n      : {\n          ...item,\n          current: item.current === true,\n          index,\n        },\n  );\n}\n\nfunction addTrailingIndexes({\n  count,\n  indexes,\n  startIndex,\n}: {\n  count: number;\n  indexes: Set<number>;\n  items: NormalizedBreadcrumbItem[];\n  startIndex: number;\n}) {\n  for (let index = startIndex; index >= 0 && indexes.size < count; index -= 1) {\n    indexes.add(index);\n  }\n}\n\nfunction addLeadingIndexes({\n  count,\n  indexes,\n  items,\n  startIndex,\n}: {\n  count: number;\n  indexes: Set<number>;\n  items: NormalizedBreadcrumbItem[];\n  startIndex: number;\n}) {\n  for (\n    let index = startIndex;\n    index < items.length && indexes.size < count;\n    index += 1\n  ) {\n    indexes.add(index);\n  }\n}\n\nfunction entriesFromVisibleIndexes(\n  items: NormalizedBreadcrumbItem[],\n  visibleIndexes: Set<number>,\n): BreadcrumbRenderItem[] {\n  const entries: BreadcrumbRenderItem[] = [];\n  let hidden: NormalizedBreadcrumbItem[] = [];\n\n  const flushHidden = () => {\n    if (hidden.length > 0) {\n      entries.push({ type: \"overflow\", items: hidden });\n      hidden = [];\n    }\n  };\n\n  for (const item of items) {\n    if (visibleIndexes.has(item.index)) {\n      flushHidden();\n      entries.push({ type: \"item\", item });\n    } else {\n      hidden.push(item);\n    }\n  }\n\n  flushHidden();\n\n  return entries;\n}\n\nexport function getBreadcrumbRenderItems(\n  sourceItems: BreadcrumbItemData[],\n  {\n    collapseFrom = \"middle\",\n    maxItems,\n    preserveCurrent = true,\n    preserveRoot = true,\n  }: BreadcrumbWindowOptions = {},\n): BreadcrumbRenderItem[] {\n  const items = normalizeItems(sourceItems);\n\n  if (items.length === 0) {\n    return [];\n  }\n\n  if (!maxItems || items.length <= maxItems) {\n    return items.map((item) => ({ type: \"item\", item }));\n  }\n\n  const safeMaxItems = Math.max(3, maxItems);\n  const visibleSlots = safeMaxItems - 1;\n  const visibleIndexes = new Set<number>();\n  const currentIndex = items.findIndex((item) => item.current);\n  const anchorIndex =\n    preserveCurrent && currentIndex !== -1 ? currentIndex : items.length - 1;\n\n  if (collapseFrom === \"start\") {\n    if (preserveRoot) {\n      visibleIndexes.add(0);\n    }\n\n    addTrailingIndexes({\n      count: visibleSlots,\n      indexes: visibleIndexes,\n      items,\n      startIndex: items.length - 1,\n    });\n  } else if (collapseFrom === \"end\") {\n    if (preserveCurrent) {\n      visibleIndexes.add(anchorIndex);\n    }\n\n    addLeadingIndexes({\n      count: visibleSlots,\n      indexes: visibleIndexes,\n      items,\n      startIndex: 0,\n    });\n  } else {\n    if (preserveRoot) {\n      visibleIndexes.add(0);\n    }\n\n    if (preserveCurrent) {\n      visibleIndexes.add(anchorIndex);\n    }\n\n    addTrailingIndexes({\n      count: visibleSlots,\n      indexes: visibleIndexes,\n      items,\n      startIndex: anchorIndex - 1,\n    });\n  }\n\n  return entriesFromVisibleIndexes(items, visibleIndexes);\n}\n\nfunction renderSeparatorContent(\n  separator: BreadcrumbSeparatorProps[\"separator\"],\n) {\n  if (separator === \"none\") {\n    return null;\n  }\n\n  if (separator === \"slash\") {\n    return \"/\";\n  }\n\n  if (separator === \"dot\") {\n    return \"•\";\n  }\n\n  if (separator === \"chevron\" || separator === undefined) {\n    return (\n      <svg\n        aria-hidden=\"true\"\n        className=\"size-3.5 rtl:rotate-180\"\n        fill=\"none\"\n        viewBox=\"0 0 12 12\"\n      >\n        <path\n          d=\"m4.5 3 3 3-3 3\"\n          stroke=\"currentColor\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"1.5\"\n        />\n      </svg>\n    );\n  }\n\n  return separator;\n}\n\nfunction renderLinkChildren({\n  children,\n  icon,\n}: {\n  children: ReactNode;\n  icon?: ReactNode;\n}) {\n  return (\n    <>\n      {icon ? (\n        <span\n          aria-hidden=\"true\"\n          data-slot=\"breadcrumb-link-icon\"\n          className={breadcrumbIconClasses}\n        >\n          {icon}\n        </span>\n      ) : null}\n      <span data-slot=\"breadcrumb-link-text\" className={breadcrumbTextClasses}>\n        {children}\n      </span>\n    </>\n  );\n}\n\nfunction renderBreadcrumbDataItem(\n  item: NormalizedBreadcrumbItem,\n  {\n    className,\n    overflow = false,\n  }: {\n    className?: string;\n    overflow?: boolean;\n  } = {},\n) {\n  const content = item.textValue ?? item.label;\n\n  if (item.href) {\n    return (\n      <BreadcrumbLink\n        className={className}\n        current={item.current}\n        disabled={item.disabled}\n        href={item.href}\n        icon={item.icon}\n      >\n        {item.label}\n      </BreadcrumbLink>\n    );\n  }\n\n  if (item.onAction) {\n    return (\n      <BreadcrumbLink\n        className={className}\n        current={item.current}\n        disabled={item.disabled}\n        icon={item.icon}\n        onAction={item.onAction}\n      >\n        {item.label}\n      </BreadcrumbLink>\n    );\n  }\n\n  return (\n    <BreadcrumbPage\n      aria-label={overflow && typeof content === \"string\" ? content : undefined}\n      className={className}\n      current={item.current}\n      icon={item.icon}\n    >\n      {item.label}\n    </BreadcrumbPage>\n  );\n}\n\nexport const Breadcrumb = forwardRef<HTMLElement, BreadcrumbProps>(\n  (\n    {\n      \"aria-label\": ariaLabel,\n      \"aria-labelledby\": ariaLabelledBy,\n      children,\n      className,\n      collapseFrom = \"middle\",\n      items,\n      maxItems,\n      overflowLabel = \"Show breadcrumb path\",\n      preserveCurrent = true,\n      preserveRoot = true,\n      separator = \"chevron\",\n      size = \"md\",\n      ...props\n    },\n    ref,\n  ) => {\n    const contextValue: BreadcrumbContextValue = { separator, size };\n    const entries = items\n      ? getBreadcrumbRenderItems(items, {\n          collapseFrom,\n          maxItems,\n          preserveCurrent,\n          preserveRoot,\n        })\n      : [];\n    const resolvedAriaLabel =\n      ariaLabel ?? (ariaLabelledBy === undefined ? \"Breadcrumb\" : undefined);\n\n    return (\n      <nav\n        {...props}\n        ref={ref}\n        aria-label={resolvedAriaLabel}\n        aria-labelledby={ariaLabelledBy}\n        data-slot=\"breadcrumb\"\n        data-size={size}\n        className={breadcrumbClassNames({ className, size })}\n      >\n        <BreadcrumbContext.Provider value={contextValue}>\n          {items ? (\n            <BreadcrumbList>\n              {entries.map((entry, index) => (\n                <BreadcrumbItem\n                  key={\n                    entry.type === \"item\"\n                      ? entry.item.key\n                      : `overflow-${entry.items.map((item) => item.key).join(\"-\")}`\n                  }\n                  current={entry.type === \"item\" ? entry.item.current : false}\n                >\n                  {entry.type === \"item\" ? (\n                    renderBreadcrumbDataItem(entry.item)\n                  ) : (\n                    <BreadcrumbOverflow\n                      items={entry.items}\n                      label={overflowLabel}\n                      size={size}\n                    />\n                  )}\n                  {index < entries.length - 1 ? <BreadcrumbSeparator /> : null}\n                </BreadcrumbItem>\n              ))}\n            </BreadcrumbList>\n          ) : (\n            children\n          )}\n        </BreadcrumbContext.Provider>\n      </nav>\n    );\n  },\n);\n\nBreadcrumb.displayName = \"Breadcrumb\";\n\nexport const BreadcrumbList = forwardRef<HTMLOListElement, BreadcrumbListProps>(\n  ({ className, ...props }, ref) => (\n    <ol\n      {...props}\n      ref={ref}\n      data-slot=\"breadcrumb-list\"\n      className={breadcrumbListClassNames({ className })}\n    />\n  ),\n);\n\nBreadcrumbList.displayName = \"BreadcrumbList\";\n\nexport const BreadcrumbItem = forwardRef<HTMLLIElement, BreadcrumbItemProps>(\n  ({ className, current = false, disabled = false, ...props }, ref) => (\n    <li\n      {...props}\n      ref={ref}\n      data-current={current ? \"true\" : undefined}\n      data-disabled={disabled ? \"true\" : undefined}\n      data-slot=\"breadcrumb-item\"\n      className={breadcrumbItemClassNames({ className })}\n    />\n  ),\n);\n\nBreadcrumbItem.displayName = \"BreadcrumbItem\";\n\nexport const BreadcrumbLink = forwardRef<HTMLElement, BreadcrumbLinkProps>(\n  (\n    {\n      asChild = false,\n      children,\n      className,\n      current = false,\n      disabled = false,\n      href,\n      icon,\n      onAction,\n      onClick,\n      rel,\n      target,\n      \"aria-current\": ariaCurrent,\n      ...props\n    },\n    ref,\n  ) => {\n    const { size } = useContext(BreadcrumbContext);\n    const resolvedAriaCurrent = resolveAriaCurrent(ariaCurrent, current);\n    const isCurrent = hasCurrentState(resolvedAriaCurrent);\n    const classes = breadcrumbLinkClassNames({ className, size });\n    const handleClick: MouseEventHandler<HTMLElement> = (event) => {\n      if (disabled) {\n        event.preventDefault();\n        event.stopPropagation();\n        return;\n      }\n\n      (onClick as MouseEventHandler<HTMLElement> | undefined)?.(event);\n\n      if (!event.defaultPrevented) {\n        onAction?.();\n      }\n    };\n\n    if (asChild) {\n      const child = Children.only(children);\n\n      if (!isValidElement<BreadcrumbLinkSlotProps>(child)) {\n        throw new Error(\n          \"BreadcrumbLink with asChild expects a single React element child.\",\n        );\n      }\n\n      const childRef = getChildRef(child);\n      const resolvedHref = child.props.href ?? href;\n      const resolvedTarget = child.props.target ?? target;\n      const resolvedRel = mergeRelForTarget(\n        child.props.rel ?? rel,\n        resolvedTarget,\n      );\n      const resolvedChildAriaCurrent =\n        child.props[\"aria-current\"] ?? resolvedAriaCurrent;\n      const isChildCurrent = hasCurrentState(resolvedChildAriaCurrent);\n      const clonedProps: BreadcrumbLinkSlotProps = {\n        ...props,\n        ...child.props,\n        ref: composeRefs(ref, childRef),\n        \"aria-current\": resolvedChildAriaCurrent,\n        \"aria-disabled\": disabled ? true : child.props[\"aria-disabled\"],\n        \"data-current\": isChildCurrent ? \"true\" : undefined,\n        \"data-disabled\": disabled ? \"true\" : undefined,\n        \"data-slot\": \"breadcrumb-link\",\n        className: cn(classes, child.props.className),\n        onClick: composeClickHandlers(handleClick, child.props.onClick),\n      };\n\n      if (resolvedHref !== undefined) {\n        clonedProps.href = resolvedHref;\n      }\n\n      if (resolvedTarget !== undefined) {\n        clonedProps.target = resolvedTarget;\n      }\n\n      if (resolvedRel !== undefined) {\n        clonedProps.rel = resolvedRel;\n      }\n\n      return cloneElement(child, clonedProps);\n    }\n\n    if (href) {\n      return (\n        <a\n          {...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}\n          ref={ref as Ref<HTMLAnchorElement>}\n          aria-current={resolvedAriaCurrent}\n          aria-disabled={disabled ? true : undefined}\n          data-current={isCurrent ? \"true\" : undefined}\n          data-disabled={disabled ? \"true\" : undefined}\n          data-slot=\"breadcrumb-link\"\n          href={href}\n          rel={mergeRelForTarget(rel, target)}\n          target={target}\n          className={classes}\n          onClick={handleClick as MouseEventHandler<HTMLAnchorElement>}\n        >\n          {renderLinkChildren({ children, icon })}\n        </a>\n      );\n    }\n\n    return (\n      <button\n        {...(props as ButtonHTMLAttributes<HTMLButtonElement>)}\n        ref={ref as Ref<HTMLButtonElement>}\n        aria-current={resolvedAriaCurrent}\n        data-current={isCurrent ? \"true\" : undefined}\n        data-disabled={disabled ? \"true\" : undefined}\n        data-slot=\"breadcrumb-link\"\n        disabled={disabled}\n        type=\"button\"\n        className={classes}\n        onClick={handleClick as MouseEventHandler<HTMLButtonElement>}\n      >\n        {renderLinkChildren({ children, icon })}\n      </button>\n    );\n  },\n);\n\nBreadcrumbLink.displayName = \"BreadcrumbLink\";\n\nexport const BreadcrumbPage = forwardRef<HTMLSpanElement, BreadcrumbPageProps>(\n  ({ children, className, current = true, icon, ...props }, ref) => {\n    const { size } = useContext(BreadcrumbContext);\n\n    return (\n      <span\n        {...props}\n        ref={ref}\n        aria-current={current ? \"page\" : undefined}\n        data-current={current ? \"true\" : undefined}\n        data-slot=\"breadcrumb-page\"\n        className={breadcrumbPageClassNames({ className, size })}\n      >\n        {renderLinkChildren({ children, icon })}\n      </span>\n    );\n  },\n);\n\nBreadcrumbPage.displayName = \"BreadcrumbPage\";\n\nexport const BreadcrumbSeparator = forwardRef<\n  HTMLSpanElement,\n  BreadcrumbSeparatorProps\n>(({ className, separator, ...props }, ref) => {\n  const context = useContext(BreadcrumbContext);\n  const resolvedSeparator = separator ?? context.separator;\n\n  if (resolvedSeparator === \"none\") {\n    return null;\n  }\n\n  return (\n    <span\n      {...props}\n      ref={ref}\n      aria-hidden=\"true\"\n      data-slot=\"breadcrumb-separator\"\n      className={breadcrumbSeparatorClassNames({ className })}\n    >\n      {renderSeparatorContent(resolvedSeparator)}\n    </span>\n  );\n});\n\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\";\n\nexport const BreadcrumbEllipsis = forwardRef<\n  HTMLSpanElement,\n  BreadcrumbEllipsisProps\n>(({ className, ...props }, ref) => (\n  <span\n    {...props}\n    ref={ref}\n    data-slot=\"breadcrumb-ellipsis\"\n    className={breadcrumbEllipsisClassNames({ className })}\n  >\n    ...\n  </span>\n));\n\nBreadcrumbEllipsis.displayName = \"BreadcrumbEllipsis\";\n\nexport const BreadcrumbOverflow = forwardRef<\n  HTMLDivElement,\n  BreadcrumbOverflowProps\n>(\n  (\n    {\n      className,\n      items,\n      label = \"Show breadcrumb path\",\n      size: _size = \"md\",\n      ...props\n    },\n    ref,\n  ) => {\n    const normalizedItems = normalizeOverflowItems(items);\n\n    return (\n      <div\n        {...props}\n        ref={ref}\n        data-slot=\"breadcrumb-overflow\"\n        className={breadcrumbOverflowClassNames({ className })}\n      >\n        <Popover>\n          <PopoverTrigger\n            aria-label={label}\n            className={breadcrumbOverflowTriggerClasses}\n            size=\"icon\"\n            variant=\"ghost\"\n          >\n            <BreadcrumbEllipsis aria-hidden=\"true\" />\n          </PopoverTrigger>\n          <PopoverContent\n            aria-label={label}\n            className={breadcrumbOverflowContentClasses}\n            panelClassName=\"gap-0\"\n            placement=\"bottom start\"\n          >\n            <PopoverTitle visuallyHidden>{label}</PopoverTitle>\n            <ol\n              data-slot=\"breadcrumb-overflow-list\"\n              className={breadcrumbOverflowListClasses}\n            >\n              {normalizedItems.map((item) => (\n                <li\n                  key={item.key}\n                  data-slot=\"breadcrumb-overflow-item\"\n                  className={breadcrumbOverflowItemClasses}\n                >\n                  {renderBreadcrumbDataItem(item, {\n                    className: cn(breadcrumbOverflowLinkClasses, \"min-h-8\"),\n                    overflow: true,\n                  })}\n                </li>\n              ))}\n            </ol>\n          </PopoverContent>\n        </Popover>\n      </div>\n    );\n  },\n);\n\nBreadcrumbOverflow.displayName = \"BreadcrumbOverflow\";\n"
    },
    {
      "path": "packages/components/src/components/breadcrumb/index.ts",
      "type": "registry:file",
      "target": "~/components/dethink/components/breadcrumb/index.ts",
      "content": "export {\n  Breadcrumb,\n  BreadcrumbEllipsis,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbOverflow,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n  breadcrumbClassNames,\n  breadcrumbEllipsisClassNames,\n  breadcrumbItemClassNames,\n  breadcrumbLinkClassNames,\n  breadcrumbListClassNames,\n  breadcrumbOverflowClassNames,\n  breadcrumbPageClassNames,\n  breadcrumbSeparatorClassNames,\n  type BreadcrumbCollapseFrom,\n  type BreadcrumbEllipsisProps,\n  type BreadcrumbItemData,\n  type BreadcrumbItemProps,\n  type BreadcrumbLinkProps,\n  type BreadcrumbListProps,\n  type BreadcrumbOverflowProps,\n  type BreadcrumbPageProps,\n  type BreadcrumbProps,\n  type BreadcrumbRenderItem,\n  type BreadcrumbSeparatorProps,\n  type BreadcrumbSeparatorVariant,\n  type BreadcrumbSize,\n} from \"./breadcrumb\";\n"
    },
    {
      "path": "packages/components/src/utils/cn.ts",
      "type": "registry:file",
      "target": "~/components/dethink/utils/cn.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
    }
  ]
}
