"use client"
import * as React from "react"
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
useTooltipProvided,
} from "./tooltip"
import { useOverlayElevation } from "../../lib/overlay-elevation"
import { cn } from "../../lib/utils"
interface TipProps {
/** Plain string or text + `` — see `.cursor/rules/exxat-kbd-shortcuts.mdc` */
label: React.ReactNode
children: React.ReactNode
side?: "top" | "bottom" | "left" | "right"
/** Merged onto `TooltipContent` — e.g. `z-properties-sheet-tooltip` inside floating sheets. */
contentClassName?: string
/** Merged onto `TooltipTrigger` when `asChild` — use `inline-flex` for icon-only hosts. */
triggerClassName?: string
/**
* Force the tooltip above floating sheets (`z-[80]`). Rarely needed: a `Tip`
* inside a rail is elevated automatically by the rail's own context.
*/
contentZIndex?: number
/**
* Keep the tooltip mounted but never open it.
*
* For a host that is only sometimes worth explaining — a tab label that reads
* for itself until the row runs out of room and hides it. Rendering the `Tip`
* conditionally instead would remount the host, which resets anything it was
* in the middle of: focus, a text selection, a transition.
*/
disabled?: boolean
}
export function Tip({
label,
children,
side = "top",
contentClassName,
triggerClassName,
contentZIndex,
disabled = false,
}: TipProps) {
const provided = useTooltipProvided()
// A tooltip inside a rail must clear it, and the author of a one-off icon
// button in an actions slot should not have to know that.
const inheritedZIndex = useOverlayElevation()
const zIndex =
contentZIndex ??
(contentClassName?.includes("properties-sheet-tooltip") ? 100 : null) ??
inheritedZIndex
// Held here rather than left to Radix so that `disabled` has something to
// override. Handing `open` over only while disabled would move the tooltip
// between controlled and uncontrolled, which React warns about and which
// loses whatever state it was in at the swap.
const [open, setOpen] = React.useState(false)
React.useEffect(() => {
if (disabled) setOpen(false)
}, [disabled])
const tip = (
{
if (!disabled) setOpen(next)
}}
>
{children}
{label}
)
return provided ? tip : {tip}
}