{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"tooltip","title":"Tooltip","description":"Short contextual label for hoverable or focusable controls.","dependencies":["@base-ui/react@1.7.0"],"registryDependencies":["@siteplane/base"],"files":[{"path":"packages/ui/src/components/tooltip/tooltip.tsx","content":"\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\nimport type React from \"react\";\n\nimport { SiteplaneUIPortalScope } from \"../../system/provider/siteplane-ui-provider\";\nimport { surfaceClassNames } from \"../../system/styles/surface\";\nimport { cn, type WithStringClassName } from \"../../system/utils/cn\";\nimport { slotClass } from \"../../system/utils/slot-class\";\n\nexport const TooltipCreateHandle: typeof TooltipPrimitive.createHandle =\n  TooltipPrimitive.createHandle;\n\nexport function TooltipProvider({\n  delay = 700,\n  timeout = 550,\n  ...props\n}: TooltipPrimitive.Provider.Props): React.ReactElement {\n  return (\n    <TooltipPrimitive.Provider delay={delay} timeout={timeout} {...props} />\n  );\n}\n\nexport const Tooltip: typeof TooltipPrimitive.Root = TooltipPrimitive.Root;\n\n/** How far the arrow reaches out of the popup: --sp-rw-space-1, in px. */\nconst TOOLTIP_ARROW_DEPTH = 4;\n\nexport function TooltipTrigger(\n  props: WithStringClassName<TooltipPrimitive.Trigger.Props>,\n): React.ReactElement {\n  return (\n    <TooltipPrimitive.Trigger\n      data-slot=\"tooltip-trigger\"\n      {...props}\n      className={cn(slotClass(\"tooltip-trigger\", props), props.className)}\n    />\n  );\n}\n\nexport type TooltipTone = \"neutral\" | \"error\";\n/**\n * @deprecated The earlier names of the two tones: `default` is `neutral` and\n * `destructive` is `error`.\n */\nexport type TooltipDeprecatedTone = \"default\" | \"destructive\";\n\nexport function TooltipPopup({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  side = \"top\",\n  anchor,\n  disableAnchorTracking,\n  arrow = false,\n  children,\n  interactive = true,\n  portalProps,\n  tone = \"neutral\",\n  variant = \"default\",\n  ...props\n}: WithStringClassName<TooltipPrimitive.Popup.Props> & {\n  align?: TooltipPrimitive.Positioner.Props[\"align\"];\n  side?: TooltipPrimitive.Positioner.Props[\"side\"];\n  sideOffset?: TooltipPrimitive.Positioner.Props[\"sideOffset\"];\n  anchor?: TooltipPrimitive.Positioner.Props[\"anchor\"];\n  /**\n   * Stops the popup from watching its anchor and itself for changes of size\n   * and place. For an anchor that its owner moves and hands over again at\n   * every frame, such as the card of a chart that trails its item, which\n   * would otherwise set the watching up anew at every frame.\n   */\n  disableAnchorTracking?: TooltipPrimitive.Positioner.Props[\"disableAnchorTracking\"];\n  /**\n   * Points an arrow at the anchor. The arrow reaches into the side offset,\n   * so the gap between the arrow's tip and the anchor stays `sideOffset`.\n   */\n  arrow?: boolean;\n  /**\n   * `false` lets the pointer pass through the popup, for a bubble that only\n   * reports, such as a field's error.\n   */\n  interactive?: boolean;\n  portalProps?: WithStringClassName<TooltipPrimitive.Portal.Props>;\n  /**\n   * `error` fills the popup with the solid destructive colour of the Badge's\n   * destructive variant, for an error; `neutral`, the default, keeps the\n   * secondary surface. `default` and `destructive` are the deprecated earlier\n   * names of `neutral` and `error`.\n   */\n  tone?: TooltipTone | TooltipDeprecatedTone;\n  /**\n   * `glass` lays the shared glass surface over whatever sits behind the\n   * tooltip. `tone` applies to the default surface only.\n   */\n  variant?: \"default\" | \"glass\";\n}): React.ReactElement {\n  return (\n    <TooltipPrimitive.Portal {...portalProps}>\n      <SiteplaneUIPortalScope>\n        <TooltipPrimitive.Positioner\n          align={align}\n          anchor={anchor}\n          disableAnchorTracking={disableAnchorTracking}\n          className={cn(\n            \"sp-tooltip-positioner\",\n            \"z-50 max-w-(--available-width)\",\n            // The positioner is as large as the popup was when it opened: Base\n            // UI measures it then and sets `--positioner-width` and\n            // `--positioner-height`, which fix its size, and it glides when its\n            // place changes. A popup with an anchor of its own is placed by\n            // whoever supplies it: the anchor moves frame by frame and the\n            // content may change in place (the card of a chart that trails its\n            // item, with rows and rolling digits). So its positioner neither\n            // transitions nor holds a measured size, which the content would\n            // outgrow and lose its padding to: it is as large as its content.\n            anchor === undefined\n              ? \"h-(--positioner-height) w-(--positioner-width) transition-[top,left,right,bottom,transform] duration-(--motion-duration-fast) ease-(--motion-ease-state) data-instant:transition-none\"\n              : \"h-max w-max\",\n            !interactive && \"pointer-events-none\",\n          )}\n          data-slot=\"tooltip-positioner\"\n          side={side}\n          sideOffset={\n            arrow && typeof sideOffset === \"number\"\n              ? sideOffset + TOOLTIP_ARROW_DEPTH\n              : sideOffset\n          }\n        >\n          <TooltipPrimitive.Popup\n            className={cn(\n              slotClass(\"tooltip-popup\", props),\n              \"sp-floating-panel relative flex h-(--popup-height,auto) w-(--popup-width,auto) origin-(--transform-origin) text-balance before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] data-instant:duration-0\",\n              // Glass takes the glass surface in place of the opaque one, whose\n              // fill, text colour and shadow the glass rule draws.\n              variant === \"glass\" && surfaceClassNames.glass,\n              !interactive && \"pointer-events-none\",\n              className,\n            )}\n            data-slot=\"tooltip-popup\"\n            // Only the error tone paints; glass keeps its own surface.\n            data-tone={\n              (tone === \"error\" || tone === \"destructive\") &&\n              variant !== \"glass\"\n                ? \"error\"\n                : undefined\n            }\n            data-variant={variant === \"glass\" ? variant : undefined}\n            {...props}\n          >\n            {arrow && (\n              <TooltipPrimitive.Arrow\n                className=\"sp-tooltip-arrow\"\n                data-slot=\"tooltip-arrow\"\n              />\n            )}\n            {/* The cross-fade of the current and the previous content, with\n                its width and its reduced-motion rules, is the viewport rule\n                it shares with Popover in design-rework.css. */}\n            <TooltipPrimitive.Viewport\n              className=\"sp-tooltip-viewport relative size-full overflow-clip data-instant:transition-none **:data-previous:truncate\"\n              data-slot=\"tooltip-viewport\"\n            >\n              {children}\n            </TooltipPrimitive.Viewport>\n          </TooltipPrimitive.Popup>\n        </TooltipPrimitive.Positioner>\n      </SiteplaneUIPortalScope>\n    </TooltipPrimitive.Portal>\n  );\n}\n\n// TooltipContent is the shadcn name of TooltipPopup.\nexport { TooltipPrimitive, TooltipPopup as TooltipContent };\n","type":"registry:ui","target":"~/src/siteplane/components/tooltip/tooltip.tsx"},{"path":"packages/ui/src/components/tooltip/index.ts","content":"export * from \"./tooltip\";\n","type":"registry:ui","target":"~/src/siteplane/components/tooltip/index.ts"}],"type":"registry:ui","docs":"https://ui.siteplane.io/docs-markdown/components/tooltip.md","categories":["Overlays & disclosure"],"meta":{"avoidWhen":["Avoid for interactive content; use Popover.","Avoid for essential instructions: do not make them hover-only."],"description":"Short contextual label for hoverable or focusable controls.","knownLimitations":[],"providerNotes":["Mount TooltipProvider once at the application root. It defaults to a 700ms opening delay and a 550ms warm re-hover window; both remain configurable."],"releaseStatus":"stable","searchTerms":["tooltip"],"useWhen":["Use for a short, non-essential label on a control that people hover or focus, such as the name of an icon button."]}}