{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dock",
  "title": "Dock",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-react/components/dock/Dock.tsx",
      "content": "import * as React from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface DockItem {\n  /** Unique id for the item. */\n  id: string\n  /** Lucide icon component to render. */\n  icon: LucideIcon\n  /** Label shown in the tooltip on hover. */\n  label: string\n  /** Click handler. */\n  handler?: () => void\n  /** Whether this item is the active one. */\n  active?: boolean\n}\n\nexport interface DockProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** Dock items. */\n  items: DockItem[]\n  /** Base icon size in pixels. Default 48. */\n  baseSize?: number\n  /** Peak magnification scale as the cursor hovers directly over an item. Default 1.6. */\n  magnification?: number\n  /** Pixel radius within which items magnify. Default 120. */\n  distance?: number\n  /** Orientation. Only 'horizontal' (bottom dock) is supported. */\n  orientation?: 'horizontal'\n  /** Show the tooltip label on hover. Default true. */\n  showTooltips?: boolean\n}\n\nconst Dock = React.forwardRef<HTMLDivElement, DockProps>(\n  (\n    {\n      items,\n      baseSize = 48,\n      magnification = 1.6,\n      distance = 120,\n      orientation = 'horizontal',\n      showTooltips = true,\n      className,\n      ...props\n    },\n    ref,\n  ) => {\n    const mouseXRef = React.useRef<number | null>(null)\n    const [mouseX, setMouseX] = React.useState<number | null>(null)\n    const [hoveredId, setHoveredId] = React.useState<string | null>(null)\n    const itemRefs = React.useRef<(HTMLDivElement | null)[]>([])\n\n    function onMove(e: React.MouseEvent<HTMLDivElement>) {\n      mouseXRef.current = e.clientX\n      setMouseX(e.clientX)\n    }\n\n    function onLeave() {\n      mouseXRef.current = null\n      setMouseX(null)\n      setHoveredId(null)\n    }\n\n    function sizeFor(index: number): number {\n      if (mouseXRef.current === null) return baseSize\n      const el = itemRefs.current[index]\n      if (!el) return baseSize\n      const rect = el.getBoundingClientRect()\n      const center = rect.left + rect.width / 2\n      const dist = Math.abs(mouseXRef.current - center)\n      if (dist > distance) return baseSize\n      // Cosine bell curve so magnification falls off smoothly.\n      const t = 1 - dist / distance\n      const scale = 1 + (magnification - 1) * t\n      return baseSize * scale\n    }\n\n    const sizes = items.map((_, i) => sizeFor(i))\n\n    return (\n      <div\n        ref={ref}\n        data-uipkge=\"\"\n        data-slot=\"dock\"\n        data-orientation={orientation}\n        className={cn(\n          'border-border/60 bg-background/60 flex items-end justify-center gap-3 rounded-2xl border px-3 py-2 backdrop-blur-md',\n          className,\n        )}\n        onMouseMove={onMove}\n        onMouseLeave={onLeave}\n        {...props}\n      >\n        {items.map((item, index) => {\n          const Icon = item.icon\n          const size = sizes[index] ?? baseSize\n          return (\n            <div\n              key={item.id}\n              ref={(el) => {\n                itemRefs.current[index] = el\n              }}\n              data-slot=\"dock-item\"\n              data-active={item.active ? '' : undefined}\n              role=\"button\"\n              tabIndex={0}\n              aria-label={item.label}\n              aria-current={item.active ? 'true' : undefined}\n              className=\"group focus-visible:ring-ring/50 relative flex shrink-0 cursor-pointer items-end justify-center rounded-xl outline-none focus-visible:ring-[3px]\"\n              onMouseEnter={() => setHoveredId(item.id)}\n              onMouseLeave={() => setHoveredId(null)}\n              onClick={() => item.handler?.()}\n              onKeyDown={(e) => {\n                if (e.key === 'Enter') {\n                  item.handler?.()\n                } else if (e.key === ' ') {\n                  e.preventDefault()\n                  item.handler?.()\n                }\n              }}\n            >\n              {/* Tooltip */}\n              {showTooltips && hoveredId === item.id ? (\n                <span className=\"border-border bg-popover text-popover-foreground pointer-events-none absolute -top-9 left-1/2 -translate-x-1/2 rounded-md border px-2 py-1 text-xs whitespace-nowrap shadow-md\">\n                  {item.label}\n                </span>\n              ) : null}\n\n              {/* Icon tile */}\n              <span\n                className={cn(\n                  'flex items-center justify-center rounded-xl border transition-[width,height] duration-100 ease-out will-change-[width,height]',\n                  item.active\n                    ? 'border-primary/40 bg-primary/10 text-primary'\n                    : 'border-border/50 bg-muted/40 text-foreground hover:bg-muted',\n                )}\n                style={{ width: `${size}px`, height: `${size}px` }}\n              >\n                <Icon style={{ width: `${size * 0.5}px`, height: `${size * 0.5}px` }} />\n              </span>\n\n              {/* Active indicator dot */}\n              {item.active ? (\n                <span className=\"bg-primary absolute -bottom-1.5 size-1 rounded-full\" aria-hidden=\"true\" />\n              ) : null}\n            </div>\n          )\n        })}\n      </div>\n    )\n  },\n)\nDock.displayName = 'Dock'\n\nexport { Dock }\n",
      "type": "registry:ui",
      "target": "~/components/ui/dock/Dock.tsx"
    },
    {
      "path": "packages/registry-react/components/dock/index.ts",
      "content": "export { Dock, type DockProps, type DockItem } from './Dock'\n",
      "type": "registry:ui",
      "target": "~/components/ui/dock/index.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "macOS-style dock menu with magnification on hover. Items expand as the cursor approaches using a cosine bell curve. Supports an items array (icon + label + handler), magnification scale, base size, tooltips on hover, click handlers, and an active state indicator.",
  "categories": [
    "navigation"
  ]
}