81 lines
2.0 KiB
TypeScript
81 lines
2.0 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import { cn } from "cn"
|
|
import {
|
|
Focusable,
|
|
OverlayArrow,
|
|
Tooltip as TooltipPrimitive,
|
|
TooltipTrigger as TooltipTriggerPrimitive,
|
|
} from "react-aria-components"
|
|
|
|
function TooltipTrigger({
|
|
delay = 0,
|
|
children,
|
|
...props
|
|
}: React.ComponentProps<typeof TooltipTriggerPrimitive>) {
|
|
const [trigger, tooltip] = React.Children.toArray(children)
|
|
|
|
return (
|
|
<TooltipTriggerPrimitive
|
|
data-slot="tooltip-trigger"
|
|
delay={delay}
|
|
{...props}
|
|
>
|
|
<Focusable>
|
|
{trigger as React.ComponentProps<typeof Focusable>["children"]}
|
|
</Focusable>
|
|
{tooltip}
|
|
</TooltipTriggerPrimitive>
|
|
)
|
|
}
|
|
|
|
function Tooltip({
|
|
className,
|
|
placement = "top",
|
|
offset = 4,
|
|
crossOffset = 0,
|
|
children,
|
|
...props
|
|
}: Omit<
|
|
React.ComponentProps<typeof TooltipPrimitive>,
|
|
"children" | "className"
|
|
> & {
|
|
className?: string
|
|
children?: React.ReactNode
|
|
}) {
|
|
return (
|
|
<TooltipPrimitive
|
|
data-slot="tooltip-content"
|
|
placement={placement}
|
|
offset={offset}
|
|
crossOffset={crossOffset}
|
|
className={cn(
|
|
"cn-tooltip-content-aria z-50 w-fit max-w-xs origin-(--trigger-anchor-point) bg-foreground text-background",
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
{children}
|
|
<OverlayArrow
|
|
className="cn-tooltip-arrow z-50 bg-foreground fill-foreground"
|
|
style={({ placement, defaultStyle }) => ({
|
|
...defaultStyle,
|
|
rotate: "0deg",
|
|
translate: "0 0",
|
|
transform:
|
|
placement === "bottom"
|
|
? "translate(-50%, calc(50% + 2px)) rotate(45deg)"
|
|
: placement === "top"
|
|
? "translate(-50%, calc(-50% - 2px)) rotate(45deg)"
|
|
: placement === "left"
|
|
? "translate(calc(-50% - 2px), -50%) rotate(45deg)"
|
|
: "translate(calc(50% + 2px), -50%) rotate(45deg)",
|
|
})}
|
|
/>
|
|
</TooltipPrimitive>
|
|
)
|
|
}
|
|
|
|
export { Tooltip, TooltipTrigger }
|