Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 64x 207x 207x 14x 14x 207x 8x 8x 207x 207x 207x 207x | import { useState } from "react"
export type TooltipProps = {
/** Tooltip content for example a text. */
content: React.ReactNode
/** Content when you hover, tooltip is shown. */
children: React.ReactNode
/** Position where tooltip is displayed. */
position?: "top" | "right" | "bottom" | "left"
/** Time when the tooltip is displayed. */
delay?: number
/** Adjust margin for top and left position when tooltip gets bigger. */
customMargin?: string
/** Add custom classname to tooltip wrapper. */
wrapperClassname?: string
}
/**
* Wrap around Component and show tooltip when hover over it.
* @example <Tooltip content="Tooltip">Hover over me</Tooltip>
*/
export const Tooltip: React.FC<TooltipProps> = ({ children, content, delay, wrapperClassname = "", position = "top", customMargin = "-40px" }) => {
let timeout: NodeJS.Timeout
const [isShown, setIsShown] = useState(false)
/**
* Shows Tooltip
*/
const showTooltip = () => {
timeout = setTimeout(() => {
setIsShown(true)
}, delay || 0)
}
/**
* Hide Tooltip
*/
const hideTooltip = () => {
clearInterval(timeout)
setIsShown(false)
}
// CSS Classes
const baseClass = "absolute bg-black text-white text-sm rounded-md left-1/2 -translate-x-1/2 whitespace-nowrap z-50 px-4 py-2"
const triangleBaseClass =
"before:content-[' '] before:left-1/2 before:h-0 before:w-0 before:absolute before:border-transparent before:border-solid before:border-[8px] before:ml-[-8px]"
const tooltipClassesPosition = {
["top"]: "text-center before:top-full before:border-t-black",
["right"]:
"left-[calc(100%_+_20px)] top-1/2 translate-x-0 -translate-y-1/2 before:left-[-8px] before:top-1/2 before:translate-x-0 before:-translate-y-1/2 before:border-r-black",
["bottom"]: "text-center before:bottom-full before:border-b-black",
["left"]:
"left-auto right-[calc(100%_+_20px)] top-1/2 translate-x-0 -translate-y-1/2 before:left-auto before:right-[-16px] before:top-1/2 before:translate-x-0 before:-translate-y-1/2 before:border-l-black",
}
return (
<div datacy="tooltip-wrapper" className={`relative inline-block ${wrapperClassname}`} onMouseEnter={showTooltip} onMouseLeave={hideTooltip}>
{children}
{isShown && (
<div
datacy="tooltip"
style={position == "top" ? { top: customMargin } : position == "bottom" ? { bottom: customMargin } : {}}
className={`${baseClass} ${triangleBaseClass} ${tooltipClassesPosition[position]}`}
>
{content}
</div>
)}
</div>
)
}
|