{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tooltip-radix",
  "dependencies": [
    "motion",
    "radix-ui"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/watermelon-ui/tooltip-radix.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Tooltip as TooltipPrime } from \"radix-ui\";\nimport {\n  AnimatePresence,\n  motion,\n  useMotionValue,\n  useSpring,\n  type SpringOptions,\n  type HTMLMotionProps,\n  type MotionValue,\n} from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\ntype TooltipProviderProps = TooltipProviderPrimitiveProps;\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: TooltipProviderProps) {\n  return <TooltipProviderPrimitive delayDuration={delayDuration} {...props} />;\n}\n\ntype TooltipProps = TooltipPrimitiveProps & {\n  delayDuration?: TooltipPrimitiveProps[\"delayDuration\"];\n};\n\nfunction Tooltip({ delayDuration = 0, ...props }: TooltipProps) {\n  return (\n    <TooltipProvider delayDuration={delayDuration}>\n      <TooltipPrimitive {...props} />\n    </TooltipProvider>\n  );\n}\n\ntype TooltipTriggerProps = TooltipTriggerPrimitiveProps;\n\nfunction TooltipTrigger({ ...props }: TooltipTriggerProps) {\n  return <TooltipTriggerPrimitive {...props} />;\n}\n\ntype TooltipContentProps = TooltipContentPrimitiveProps;\n\nfunction TooltipContent({\n  className,\n  sideOffset,\n  children,\n  ...props\n}: TooltipContentProps) {\n  return (\n    <TooltipPortalPrimitive>\n      <TooltipContentPrimitive\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-primary text-primary-foreground z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className,\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipArrowPrimitive className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipContentPrimitive>\n    </TooltipPortalPrimitive>\n  );\n}\n\nexport {\n  Tooltip,\n  TooltipTrigger,\n  TooltipContent,\n  type TooltipProps,\n  type TooltipTriggerProps,\n  type TooltipContentProps,\n};\n\ntype TooltipContextType = {\n  isOpen: boolean;\n  setIsOpen: (isOpen: boolean) => void;\n  x: MotionValue<number>;\n  y: MotionValue<number>;\n  followCursor?: boolean | \"x\" | \"y\";\n  followCursorSpringOptions?: SpringOptions;\n};\n\nconst [LocalTooltipProvider, useTooltip] =\n  getStrictContext<TooltipContextType>(\"TooltipContext\");\n\ntype TooltipProviderPrimitiveProps = React.ComponentProps<\n  typeof TooltipPrime.Provider\n>;\n\nfunction TooltipProviderPrimitive(props: TooltipProviderPrimitiveProps) {\n  return <TooltipPrime.Provider data-slot=\"tooltip-provider\" {...props} />;\n}\n\ntype TooltipPrimitiveProps = React.ComponentProps<typeof TooltipPrime.Root> & {\n  followCursor?: boolean | \"x\" | \"y\";\n  followCursorSpringOptions?: SpringOptions;\n};\n\nfunction TooltipPrimitive({\n  followCursor = false,\n  followCursorSpringOptions = { stiffness: 200, damping: 17 },\n  ...props\n}: TooltipPrimitiveProps) {\n  const [isOpen, setIsOpen] = useControlledState({\n    value: props?.open,\n    defaultValue: props?.defaultOpen,\n    onChange: props?.onOpenChange,\n  });\n  const x = useMotionValue(0);\n  const y = useMotionValue(0);\n\n  return (\n    <LocalTooltipProvider\n      value={{\n        isOpen,\n        setIsOpen,\n        x,\n        y,\n        followCursor,\n        followCursorSpringOptions,\n      }}\n    >\n      <TooltipPrime.Root\n        data-slot=\"tooltip\"\n        {...props}\n        onOpenChange={setIsOpen}\n      />\n    </LocalTooltipProvider>\n  );\n}\n\ntype TooltipTriggerPrimitiveProps = React.ComponentProps<\n  typeof TooltipPrime.Trigger\n>;\n\nfunction TooltipTriggerPrimitive({\n  onMouseMove,\n  ...props\n}: TooltipTriggerPrimitiveProps) {\n  const { x, y, followCursor } = useTooltip();\n\n  const handleMouseMove = (event: React.MouseEvent<HTMLButtonElement>) => {\n    onMouseMove?.(event);\n\n    const target = event.currentTarget.getBoundingClientRect();\n\n    if (followCursor === \"x\" || followCursor === true) {\n      const eventOffsetX = event.clientX - target.left;\n      const offsetXFromCenter = (eventOffsetX - target.width / 2) / 2;\n      x.set(offsetXFromCenter);\n    }\n\n    if (followCursor === \"y\" || followCursor === true) {\n      const eventOffsetY = event.clientY - target.top;\n      const offsetYFromCenter = (eventOffsetY - target.height / 2) / 2;\n      y.set(offsetYFromCenter);\n    }\n  };\n\n  return (\n    <TooltipPrime.Trigger\n      data-slot=\"tooltip-trigger\"\n      onMouseMove={handleMouseMove}\n      {...props}\n    />\n  );\n}\n\ntype TooltipPortalPrimitiveProps = Omit<\n  React.ComponentProps<typeof TooltipPrime.Portal>,\n  \"forceMount\"\n>;\n\nfunction TooltipPortalPrimitive(props: TooltipPortalPrimitiveProps) {\n  const { isOpen } = useTooltip();\n\n  return (\n    <AnimatePresence>\n      {isOpen && (\n        <TooltipPrime.Portal forceMount data-slot=\"tooltip-portal\" {...props} />\n      )}\n    </AnimatePresence>\n  );\n}\n\ntype TooltipContentPrimitiveProps = Omit<\n  React.ComponentProps<typeof TooltipPrime.Content>,\n  \"forceMount\" | \"asChild\"\n> &\n  HTMLMotionProps<\"div\">;\n\nfunction TooltipContentPrimitive({\n  onEscapeKeyDown,\n  onPointerDownOutside,\n  side,\n  sideOffset,\n  align,\n  alignOffset,\n  avoidCollisions,\n  collisionBoundary,\n  collisionPadding,\n  arrowPadding,\n  sticky,\n  hideWhenDetached,\n  style,\n  transition = { type: \"spring\", stiffness: 300, damping: 25 },\n  className,\n  children,\n  ...props\n}: TooltipContentPrimitiveProps) {\n  const { x, y, followCursor, followCursorSpringOptions } = useTooltip();\n  const translateX = useSpring(x, followCursorSpringOptions);\n  const translateY = useSpring(y, followCursorSpringOptions);\n\n  return (\n    <TooltipPrime.Content\n      forceMount\n      align={align}\n      alignOffset={alignOffset}\n      side={side}\n      sideOffset={sideOffset}\n      avoidCollisions={avoidCollisions}\n      collisionBoundary={collisionBoundary}\n      collisionPadding={collisionPadding}\n      arrowPadding={arrowPadding}\n      sticky={sticky}\n      hideWhenDetached={hideWhenDetached}\n      onEscapeKeyDown={onEscapeKeyDown}\n      onPointerDownOutside={onPointerDownOutside}\n    >\n      <motion.div\n        key=\"tooltip-content\"\n        data-slot=\"tooltip-content\"\n        className={className}\n        initial={{ opacity: 0, scale: 0.5 }}\n        animate={{ opacity: 1, scale: 1 }}\n        exit={{ opacity: 0, scale: 0.5 }}\n        transition={transition}\n        style={{\n          x:\n            followCursor === \"x\" || followCursor === true\n              ? translateX\n              : undefined,\n          y:\n            followCursor === \"y\" || followCursor === true\n              ? translateY\n              : undefined,\n          ...style,\n        }}\n        {...props}\n      >\n        {children}\n      </motion.div>\n    </TooltipPrime.Content>\n  );\n}\n\ntype TooltipArrowPrimitiveProps = React.ComponentProps<\n  typeof TooltipPrime.Arrow\n>;\n\nfunction TooltipArrowPrimitive(props: TooltipArrowPrimitiveProps) {\n  return <TooltipPrime.Arrow data-slot=\"tooltip-arrow\" {...props} />;\n}\n\nfunction getStrictContext<T>(\n  name?: string,\n): readonly [\n  ({\n    value,\n    children,\n  }: {\n    value: T;\n    children?: React.ReactNode;\n  }) => React.JSX.Element,\n  () => T,\n] {\n  const Context = React.createContext<T | undefined>(undefined);\n\n  const Provider = ({\n    value,\n    children,\n  }: {\n    value: T;\n    children?: React.ReactNode;\n  }) => <Context.Provider value={value}>{children}</Context.Provider>;\n\n  const useSafeContext = () => {\n    const ctx = React.useContext(Context);\n    if (ctx === undefined) {\n      throw new Error(`useContext must be used within ${name ?? \"a Provider\"}`);\n    }\n    return ctx;\n  };\n\n  return [Provider, useSafeContext] as const;\n}\n\nexport { getStrictContext };\n\ninterface CommonControlledStateProps<T> {\n  value?: T;\n  defaultValue?: T;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useControlledState<T, Rest extends any[] = []>(\n  props: CommonControlledStateProps<T> & {\n    onChange?: (value: T, ...args: Rest) => void;\n  },\n): readonly [T, (next: T, ...args: Rest) => void] {\n  const { value, defaultValue, onChange } = props;\n\n  const [state, setInternalState] = React.useState<T>(\n    value !== undefined ? value : (defaultValue as T),\n  );\n\n  React.useEffect(() => {\n    if (value !== undefined) setInternalState(value);\n  }, [value]);\n\n  const setState = React.useCallback(\n    (next: T, ...args: Rest) => {\n      setInternalState(next);\n      onChange?.(next, ...args);\n    },\n    [onChange],\n  );\n\n  return [state, setState] as const;\n}\n",
      "type": "registry:ui",
      "target": "components/ui/tooltip-radix.tsx"
    }
  ],
  "type": "registry:ui"
}
