{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tooltip",
  "title": "Tooltip",
  "description": "Displays contextual information when hovering or focusing an element, built on Base UI.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/base/ui/tooltip.tsx",
      "content": "\"use client\"\n\nimport { DirectionProvider } from \"@base-ui/react/direction-provider\"\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction TooltipProvider({\n  delay = 600,\n  ...props\n}: TooltipPrimitive.Provider.Props) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delay={delay}\n      {...props}\n    />\n  )\n}\n\n/**\n * TooltipContent renders through a Portal, so it doesn't inherit `dir` from a\n * nearby wrapper (only from document.documentElement). TooltipTrigger\n * measures the ambient direction where it's actually rendered and pushes it\n * here so TooltipContent can apply it explicitly to the portaled popup.\n *\n * The DOM `dir` attribute alone isn't enough: Base UI resolves logical\n * `side=\"inline-start\"/\"inline-end\"` values through its own internal\n * DirectionContext, not from CSS/DOM `dir`, so the tree is also wrapped in\n * Base UI's own DirectionProvider.\n */\nconst TooltipDirContext = React.createContext<{\n  dir: \"ltr\" | \"rtl\"\n  setDir: (dir: \"ltr\" | \"rtl\") => void\n}>({ dir: \"ltr\", setDir: () => {} })\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n  const [dir, setDir] = React.useState<\"ltr\" | \"rtl\">(\"ltr\")\n  const contextValue = React.useMemo(() => ({ dir, setDir }), [dir])\n\n  return (\n    <TooltipDirContext.Provider value={contextValue}>\n      <DirectionProvider direction={dir}>\n        <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n      </DirectionProvider>\n    </TooltipDirContext.Provider>\n  )\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n  const ref = React.useRef<HTMLButtonElement>(null)\n  const { setDir } = React.useContext(TooltipDirContext)\n\n  React.useEffect(() => {\n    function update() {\n      if (!ref.current) return\n      setDir(getComputedStyle(ref.current).direction === \"rtl\" ? \"rtl\" : \"ltr\")\n    }\n\n    update()\n\n    const observer = new MutationObserver(update)\n    observer.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: [\"dir\"],\n      subtree: true,\n    })\n\n    return () => observer.disconnect()\n  }, [setDir])\n\n  return (\n    <TooltipPrimitive.Trigger\n      ref={ref}\n      data-slot=\"tooltip-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction TooltipContent({\n  className,\n  side = \"top\",\n  sideOffset = 4,\n  align = \"center\",\n  alignOffset = 0,\n  children,\n  ...props\n}: TooltipPrimitive.Popup.Props &\n  Pick<\n    TooltipPrimitive.Positioner.Props,\n    \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n  >) {\n  const { dir } = React.useContext(TooltipDirContext)\n\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Positioner\n        dir={dir}\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n        className=\"isolate z-50\"\n      >\n        <TooltipPrimitive.Popup\n          data-slot=\"tooltip-content\"\n          className={cn(\n            \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 pt-1.5 pb-2 text-xs leading-5 text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n          <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n        </TooltipPrimitive.Popup>\n      </TooltipPrimitive.Positioner>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}