{
  "name": "tooltip",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "tooltip.tsx",
      "content": "\"use client\";\r\n\r\nimport { computePosition, css, scaleIn, scaleOut, themeVars as theme, type Placement } from \"@yugnex/core\";\r\nimport { usePortal, usePresence } from \"@yugnex/core/client\";\r\nimport { cloneElement, useEffect, useId, useRef, useState, type ReactElement, type ReactNode, type Ref } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\n\r\nconst tooltipClass = css({\r\n  position: \"fixed\",\r\n  top: 0,\r\n  left: 0,\r\n  zIndex: theme.zIndex.tooltip,\r\n  padding: `${theme.space[1.5]} ${theme.space[2.5]}`,\r\n  borderRadius: theme.radius.sm,\r\n  backgroundColor: theme.color.foreground,\r\n  color: theme.color.background,\r\n  fontFamily: theme.fontFamily.sans,\r\n  fontSize: theme.fontSize.xs,\r\n  boxShadow: theme.shadow.md,\r\n  pointerEvents: \"none\",\r\n  '&[data-state=\"open\"]': {\r\n    animation: `${scaleIn} ${theme.duration.fast} ${theme.easing.decelerate}`,\r\n  },\r\n  '&[data-state=\"closed\"]': {\r\n    animation: `${scaleOut} ${theme.duration.fast} ${theme.easing.accelerate}`,\r\n  },\r\n});\r\n\r\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>): (node: T | null) => void {\r\n  return (node) => {\r\n    for (const ref of refs) {\r\n      if (typeof ref === \"function\") ref(node);\r\n      else if (ref) (ref as { current: T | null }).current = node;\r\n    }\r\n  };\r\n}\r\n\r\nexport interface TooltipProps {\r\n  /** A single element (must forward its ref, e.g. a native tag or a forwardRef component). */\r\n  children: ReactElement;\r\n  content: ReactNode;\r\n  placement?: Placement;\r\n  delay?: number;\r\n}\r\n\r\nexport function Tooltip({ children, content, placement = \"top\", delay = 200 }: TooltipProps) {\r\n  const [open, setOpen] = useState(false);\r\n  const anchorRef = useRef<HTMLElement | null>(null);\r\n  const floatingRef = useRef<HTMLDivElement | null>(null);\r\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n  const id = useId();\r\n  const portalNode = usePortal();\r\n  const { mounted, dataState } = usePresence(open, { exitDuration: 150 });\r\n  const [pos, setPos] = useState({ x: 0, y: 0 });\r\n\r\n  useEffect(() => {\r\n    if (!open || !anchorRef.current || !floatingRef.current) return;\r\n    const update = () => {\r\n      if (!anchorRef.current || !floatingRef.current) return;\r\n      const result = computePosition(anchorRef.current, floatingRef.current, { placement });\r\n      setPos({ x: result.x, y: result.y });\r\n    };\r\n    update();\r\n    window.addEventListener(\"scroll\", update, true);\r\n    window.addEventListener(\"resize\", update);\r\n    return () => {\r\n      window.removeEventListener(\"scroll\", update, true);\r\n      window.removeEventListener(\"resize\", update);\r\n    };\r\n  }, [open, placement, mounted]);\r\n\r\n  const show = () => {\r\n    if (timeoutRef.current) clearTimeout(timeoutRef.current);\r\n    timeoutRef.current = setTimeout(() => setOpen(true), delay);\r\n  };\r\n  const hide = () => {\r\n    if (timeoutRef.current) clearTimeout(timeoutRef.current);\r\n    setOpen(false);\r\n  };\r\n\r\n  // Cast to a generic props shape so we can inject a merged ref + handlers via\r\n  // cloneElement regardless of the child's own prop types (the same pattern\r\n  // Radix's Slot uses for polymorphic triggers).\r\n  const element = children as ReactElement<Record<string, unknown>>;\r\n  const childRef = (element as { ref?: Ref<HTMLElement> }).ref;\r\n\r\n  const trigger = cloneElement(element, {\r\n    ref: mergeRefs(anchorRef, childRef),\r\n    onMouseEnter: show,\r\n    onMouseLeave: hide,\r\n    onFocus: show,\r\n    onBlur: hide,\r\n    \"aria-describedby\": open ? id : undefined,\r\n  });\r\n\r\n  return (\r\n    <>\r\n      {trigger}\r\n      {mounted && portalNode\r\n        ? createPortal(\r\n            <div\r\n              ref={floatingRef}\r\n              role=\"tooltip\"\r\n              id={id}\r\n              data-state={dataState}\r\n              className={tooltipClass}\r\n              style={{ transform: `translate(${pos.x}px, ${pos.y}px)` }}\r\n            >\r\n              {content}\r\n            </div>,\r\n            portalNode,\r\n          )\r\n        : null}\r\n    </>\r\n  );\r\n}\r\n",
      "type": "registry:component"
    }
  ]
}