{
  "schemaVersion": 1,
  "target": "react",
  "name": "tooltip",
  "version": "0.1.0",
  "category": "core",
  "title": "Tooltip",
  "description": "A short label that appears on hover and keyboard focus, built on Base UI Tooltip.",
  "tags": [
    "overlay",
    "tooltip",
    "hint",
    "base-ui"
  ],
  "requires": {
    "projectTypes": [
      "next",
      "vite-react"
    ],
    "styling": "tailwind-v4"
  },
  "npmDependencies": {
    "@base-ui/react": "^1.9.0"
  },
  "registryDependencies": [],
  "docsPath": "/components/tooltip",
  "props": [
    {
      "name": "TooltipProvider delay / closeDelay / timeout",
      "type": "number",
      "description": "Shared hover delays in ms. Once one tooltip is open, neighbours open instantly within timeout (default 400)."
    },
    {
      "name": "Tooltip open / defaultOpen / onOpenChange",
      "type": "boolean / boolean / (open, details) => void",
      "description": "Root state. Leave open unset for an uncontrolled tooltip."
    },
    {
      "name": "Tooltip disabled",
      "type": "boolean",
      "default": "false",
      "description": "Turns the tooltip off without removing it."
    },
    {
      "name": "TooltipTrigger delay",
      "type": "number",
      "default": "600",
      "description": "Hover delay before opening, in ms. Keyboard focus opens it immediately."
    },
    {
      "name": "TooltipTrigger",
      "type": "Base UI Tooltip.Trigger props",
      "description": "The hovered or focused element, a <button> by default. Pass render={<Button />} to reuse your own."
    },
    {
      "name": "TooltipContent side",
      "type": "\"top\" | \"bottom\" | \"left\" | \"right\" | \"inline-start\" | \"inline-end\"",
      "default": "\"top\"",
      "description": "Preferred side of the trigger. Flips when there is not enough room."
    },
    {
      "name": "TooltipContent align",
      "type": "\"start\" | \"center\" | \"end\"",
      "default": "\"center\"",
      "description": "Alignment against the trigger."
    },
    {
      "name": "TooltipContent sideOffset",
      "type": "number",
      "default": "6",
      "description": "Gap from the trigger, in pixels."
    },
    {
      "name": "TooltipContent arrow",
      "type": "boolean",
      "default": "true",
      "description": "Shows an arrow pointing at the trigger."
    }
  ],
  "accessibility": [
    "The tooltip opens on hover and on keyboard focus, and Escape closes it.",
    "Pointer users can move onto the tooltip without it closing, so the text stays readable.",
    "Base UI does not link the tooltip text to the trigger, so give icon-only triggers an aria-label that says the same thing.",
    "Do not put links or buttons inside a tooltip; use a Popover for interactive content.",
    "With reduced motion the fade and scale transitions are removed."
  ],
  "states": [
    "closed",
    "open"
  ],
  "files": [
    {
      "path": "ui/tooltip.tsx",
      "content": "\"use client\";\n\nimport { Tooltip as BaseTooltip } from \"@base-ui/react/tooltip\";\n\ntype ClassName<State> = string | ((state: State) => string | undefined) | undefined;\n\nfunction cx(...classes: (string | false | null | undefined)[]) {\n  return classes.filter(Boolean).join(\" \");\n}\n\n/** Prepends base classes while keeping Base UI's state-function form of className working. */\nfunction withBase<State>(base: string, className: ClassName<State>) {\n  return typeof className === \"function\" ? (state: State) => cx(base, className(state)) : cx(base, className);\n}\n\n/**\n * Shares hover delays across tooltips, so moving between triggers opens the next tooltip\n * instantly. Optional; wrap your app or a toolbar in it.\n */\nexport const TooltipProvider = BaseTooltip.Provider;\n\n/** Groups the tooltip parts and holds its open state. */\nexport const Tooltip = BaseTooltip.Root;\n\n/**\n * The element that shows the tooltip on hover and keyboard focus. Renders a `<button>`;\n * pass `render={<Button />}` to reuse your button, and give icon-only triggers an `aria-label`.\n */\nexport const TooltipTrigger = BaseTooltip.Trigger;\n\ntype PositionerProps = BaseTooltip.Positioner.Props;\n\nexport interface TooltipContentProps extends BaseTooltip.Popup.Props {\n  /** Side of the trigger to place the tooltip on. Flips when there is not enough room. */\n  side?: PositionerProps[\"side\"];\n  /** Alignment against the trigger on the chosen side. */\n  align?: PositionerProps[\"align\"];\n  /** Gap between the trigger and the tooltip, in pixels. */\n  sideOffset?: PositionerProps[\"sideOffset\"];\n  /** Shows an arrow pointing at the trigger. */\n  arrow?: boolean;\n  /** Classes for the positioner wrapper, for example to change the z-index. */\n  positionerClassName?: string;\n  /** Element to portal into. Defaults to `document.body`. */\n  container?: BaseTooltip.Portal.Props[\"container\"];\n}\n\n/** The tooltip bubble, rendered in a portal and positioned against the trigger. */\nexport function TooltipContent({\n  side = \"top\",\n  align = \"center\",\n  sideOffset = 6,\n  arrow = true,\n  positionerClassName,\n  container,\n  className,\n  children,\n  ...props\n}: TooltipContentProps) {\n  return (\n    <BaseTooltip.Portal container={container}>\n      <BaseTooltip.Positioner side={side} align={align} sideOffset={sideOffset} className={cx(\"z-50\", positionerClassName)}>\n        <BaseTooltip.Popup\n          className={withBase(\n            cx(\n              \"relative max-w-xs origin-(--transform-origin) rounded-md bg-zinc-900 px-2 py-1 text-xs font-medium text-white shadow-md\",\n              \"dark:bg-zinc-100 dark:text-zinc-900\",\n              \"transition-[opacity,scale] duration-100 ease-out motion-reduce:transition-none\",\n              \"data-[starting-style]:opacity-0 data-[ending-style]:opacity-0\",\n              \"motion-safe:data-[starting-style]:scale-95 motion-safe:data-[ending-style]:scale-95\",\n              // Skip the fade when moving between triggers inside a TooltipProvider.\n              \"data-[instant]:transition-none\",\n            ),\n            className,\n          )}\n          {...props}\n        >\n          {arrow ? (\n            <BaseTooltip.Arrow\n              className={cx(\n                \"size-2 rotate-45 bg-zinc-900 dark:bg-zinc-100\",\n                \"data-[side=bottom]:-top-1 data-[side=top]:-bottom-1 data-[side=left]:-right-1 data-[side=right]:-left-1\",\n              )}\n            />\n          ) : null}\n          {children}\n        </BaseTooltip.Popup>\n      </BaseTooltip.Positioner>\n    </BaseTooltip.Portal>\n  );\n}\n"
    }
  ],
  "example": {
    "content": "import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@/components/seamless/ui/tooltip\";\n\nconst iconButton =\n  \"inline-flex size-9 items-center justify-center rounded-lg border border-zinc-200 bg-white text-zinc-700 \" +\n  \"transition-colors duration-150 hover:bg-zinc-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-500 \" +\n  \"motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800\";\n\nexport default function TooltipExample() {\n  return (\n    <TooltipProvider>\n      <div className=\"flex items-center gap-2\">\n        <Tooltip>\n          <TooltipTrigger aria-label=\"Copy link\" className={iconButton}>\n            <svg aria-hidden=\"true\" viewBox=\"0 0 16 16\" fill=\"none\" className=\"size-4\">\n              <rect x=\"5\" y=\"5\" width=\"8\" height=\"8\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n              <path d=\"M3 10.5V4a1 1 0 0 1 1-1h6.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n            </svg>\n          </TooltipTrigger>\n          <TooltipContent>Copy link</TooltipContent>\n        </Tooltip>\n        <Tooltip>\n          <TooltipTrigger aria-label=\"Download\" className={iconButton}>\n            <svg aria-hidden=\"true\" viewBox=\"0 0 16 16\" fill=\"none\" className=\"size-4\">\n              <path d=\"M8 2.5v8M4.5 7 8 10.5 11.5 7M3 13.5h10\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n            </svg>\n          </TooltipTrigger>\n          <TooltipContent side=\"bottom\">Download</TooltipContent>\n        </Tooltip>\n      </div>\n    </TooltipProvider>\n  );\n}\n"
  }
}
