{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tooltip",
  "title": "Tooltip",
  "description": "Tooltip from the Get IT Done design system.",
  "dependencies": [
    "@radix-ui/react-tooltip@^1.4.1"
  ],
  "registryDependencies": [
    "https://zero-design.itdone.de/r/labels-context.json",
    "https://zero-design.itdone.de/r/utils.json",
    "https://zero-design.itdone.de/r/theme.json"
  ],
  "files": [
    {
      "path": "registry/ui/tooltip.tsx",
      "content": "'use client';\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\nimport { usePreset } from '@/components/ui/labels-context';\n\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\n/**\n * A disabled native element (e.g. `<Button disabled>`) never fires the pointer/focus\n * events Radix listens for, so a tooltip on a disabled trigger would silently never\n * open — the exact case this design system needs a tooltip for (explaining *why*\n * something is disabled). When the single child is `disabled`, wrap it in a focusable,\n * hoverable span and neutralize pointer-events on the child so the wrapper receives the\n * hover/focus interaction while the inner element keeps its real `disabled` semantics\n * for assistive tech.\n *\n * The wrapper is itself the focus target (not the inner disabled control), so it carries\n * the system's standard `focus-visible:ring-2 ring-ring-default` treatment — matching\n * every other interactive primitive (see `button.tsx`) — plus `role=\"button\"\n * aria-disabled=\"true\"` so assistive tech announces it as a disabled control rather than\n * a bare, roleless generic element.\n */\nconst TooltipTrigger = React.forwardRef<\n  React.ElementRef<typeof TooltipPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>\n>(({ children, className, ...props }, ref) => {\n  const child = children as React.ReactElement<{ disabled?: boolean; style?: React.CSSProperties }>;\n  const isDisabled = React.isValidElement(child) && Boolean(child.props?.disabled);\n\n  if (isDisabled) {\n    return (\n      <TooltipPrimitive.Trigger {...props} ref={ref} asChild>\n        <span\n          tabIndex={0}\n          role=\"button\"\n          aria-disabled=\"true\"\n          className={cn(\n            'inline-flex cursor-not-allowed rounded-control focus-visible:outline-none focus-visible:ring-focus focus-visible:ring-offset-focus focus-visible:ring-offset-background focus-visible:ring-ring-default',\n            className,\n          )}\n        >\n          {React.cloneElement(child, {\n            style: { pointerEvents: 'none', ...child.props.style },\n          })}\n        </span>\n      </TooltipPrimitive.Trigger>\n    );\n  }\n\n  return (\n    <TooltipPrimitive.Trigger ref={ref} className={className} {...props}>\n      {children}\n    </TooltipPrimitive.Trigger>\n  );\n});\nTooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;\n\n/**\n * `motion-reduce:animate-none` (plus killing the transition and the closed-state\n * animate-out variant) gives `prefers-reduced-motion: reduce` users an instant\n * show/hide instead of the slide/zoom/fade — Radix still drives open/close via the\n * `data-state` attribute, so visibility itself is unaffected, only the motion is.\n */\nconst TooltipContent = React.forwardRef<\n  React.ElementRef<typeof TooltipPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> & {\n    // `light` uses the popover surface with a hairline border (Figma Theme=Light); default stays the inverse surface.\n    tone?: 'dark' | 'light';\n    // Second, muted line under the content (Figma Supporting text=True).\n    supportingText?: React.ReactNode;\n  }\n>(({ className, sideOffset = 4, tone = 'dark', supportingText, children, ...props }, ref) => {\n  const zero = usePreset() === 'zero';\n  return (\n    <TooltipPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      data-tone={tone}\n      className={cn(\n        // Inverse surface (foreground on background), no border or heavy shadow.\n        'z-tooltip overflow-hidden bg-foreground text-background animate-in fade-in-0 zoom-in-[0.98] duration-150 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-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 motion-reduce:animate-none motion-reduce:transition-none motion-reduce:data-[state=closed]:animate-none',\n        zero ? 'rounded-control px-3 py-2 typography-ui-sm shadow-elevation-raised' : 'rounded-item px-2 py-1 text-xs font-medium',\n        tone === 'light' && 'border border-solid bg-popover text-popover-foreground',\n        tone === 'light' && (zero ? 'border-border-default shadow-elevation-raised' : 'border-hairline shadow-popover'),\n        className,\n      )}\n      {...props}\n    >\n      {supportingText ? (\n        <div className=\"flex flex-col gap-1\">\n          <span>{children}</span>\n          <span className={cn('font-normal', tone === 'light' ? 'text-text-subtle' : 'text-text-inverse-subtle')}>{supportingText}</span>\n        </div>\n      ) : (\n        children\n      )}\n    </TooltipPrimitive.Content>\n  );\n});\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nconst TooltipArrow = React.forwardRef<\n  React.ElementRef<typeof TooltipPrimitive.Arrow>,\n  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>\n>(({ className, ...props }, ref) => (\n  <TooltipPrimitive.Arrow ref={ref} className={cn('fill-foreground', className)} {...props} />\n));\nTooltipArrow.displayName = TooltipPrimitive.Arrow.displayName;\n\nexport { Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipTrigger };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}