{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "tooltip", "type": "registry:ui", "title": "Tooltip", "files": [ { "path": "ui/tooltip.tsrx", "type": "registry:ui", "target": "components/ui/tooltip.tsrx", "content": "// Base UI base tooltip — runs on @octanejs/base-ui's Tooltip.\n//\n// SAME TWO POSITIONING DIFFERENCES AS POPOVER: the transform-origin var is plain\n// `--transform-origin` rather than radix's `--radix-tooltip-content-transform-origin`, and the\n// tree gains a Positioner layer (Portal > Positioner > Popup) which owns the offset.\n//\n// ONE RADIX-ONLY STATE IS DROPPED. The radix base styles `data-[state=delayed-open]:` alongside\n// `data-open:`, because radix distinguishes an immediate open from one that waited out the\n// delay. Base UI publishes only `data-open`/`data-closed` — there is no delayed-open state to\n// match, so those three utilities would be dead weight referencing an attribute that never\n// appears. The `data-open:` variants they duplicate are kept and cover both cases.\n//\n// UNVERIFIED PROVENANCE: class strings come from this package's radix base rather than\n// transcribed from upstream's Base UI source.\nimport { createElement, Fragment, type OctaneNode } from 'octane';\nimport { Tooltip as TooltipPrimitive } from '@octanejs/base-ui/tooltip';\n\nimport { cn } from '@/lib/utils';\n\nexport interface TooltipProviderProps extends Record {\n\tdelay?: number;\n}\n\nexport function TooltipProvider({ delay = 0, ...props }: TooltipProviderProps) @{\n\t\n}\n\nexport function Tooltip(props: Record) @{\n\t\n}\n\nexport function TooltipTrigger(props: Record) @{\n\t\n}\n\nexport interface TooltipContentProps extends Record {\n\tclassName?: string;\n\tsideOffset?: number;\n\tchildren?: OctaneNode;\n}\n\nexport interface BaseUiPositioningProps {\n\t/** Forwarded to the Positioner; see the note at the top of this file. */\n\tside?: 'top' | 'right' | 'bottom' | 'left';\n\tsideOffset?: number;\n\talign?: 'start' | 'center' | 'end';\n\talignOffset?: number;\n\tanchor?: unknown;\n\tpositionMethod?: 'absolute' | 'fixed';\n\tcollisionBoundary?: unknown;\n\tcollisionPadding?: unknown;\n\tcollisionAvoidance?: unknown;\n\tarrowPadding?: number;\n\tsticky?: boolean;\n\tdisableAnchorTracking?: boolean;\n}\n\nexport function TooltipContent({\n\tclassName,\n\tsideOffset = 0,\n\talign,\n\tside,\n\talignOffset,\n\tanchor,\n\tpositionMethod,\n\tcollisionBoundary,\n\tcollisionPadding,\n\tcollisionAvoidance,\n\tarrowPadding,\n\tsticky,\n\tdisableAnchorTracking,\n\tchildren,\n\t...props\n}: TooltipContentProps & BaseUiPositioningProps) {\n\treturn createElement(TooltipPrimitive.Portal, {\n\t\tchildren: createElement(TooltipPrimitive.Positioner, {\n\t\t\tside,\n\t\t\tsideOffset,\n\t\t\talign,\n\t\t\talignOffset,\n\t\t\tanchor,\n\t\t\tpositionMethod,\n\t\t\tcollisionBoundary,\n\t\t\tcollisionPadding,\n\t\t\tcollisionAvoidance,\n\t\t\tarrowPadding,\n\t\t\tsticky,\n\t\t\tdisableAnchorTracking,\n\t\t\tchildren: createElement(TooltipPrimitive.Popup, {\n\t\t\t\t'data-slot': 'tooltip-content',\n\t\t\t\tclassName: cn(\n\t\t\t\t\t'z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 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 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n\t\t\t\t\tclassName,\n\t\t\t\t),\n\t\t\t\t...props,\n\t\t\t\t// Octane reconciles ARRAY children as a keyed list, so every entry needs a key —\n\t\t\t\t// including the consumer's. Leaving `children` bare emits the missing-key warning\n\t\t\t\t// and lets the consumer node be mismatched against the arrow when its identity\n\t\t\t\t// changes. The consumer may pass anything (a string, an element, an array), so it\n\t\t\t\t// is wrapped in a keyed Fragment rather than keyed in place.\n\t\t\t\tchildren: [\n\t\t\t\t\tcreateElement(Fragment, { key: 'content', children }),\n\t\t\t\t\tcreateElement(TooltipPrimitive.Arrow, {\n\t\t\t\t\t\tkey: 'arrow',\n\t\t\t\t\t\tclassName: 'z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground',\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t}),\n\t\t}),\n\t});\n}\n" } ], "dependencies": [ "@octanejs/base-ui@0.1.33" ], "registryDependencies": [ "@octane/utils" ] }