2022-03-13 03:00:38 +01:00

83 lines
2.4 KiB
TypeScript

import { useEffect, useState } from "react";
type ToolTipProps = {
hovered: boolean;
children: React.ReactNode;
direction: "right" | "bottom" | "top" | "left";
offset: string;
delayShow?: number;
maxWidth?: "max-w-[10rem]" | "max-w-xs" | "max-w-sm" | "max-w-md";
};
export default function ToolTip(props: ToolTipProps): JSX.Element {
const { children, hovered, direction, offset } = props;
let { delayShow, maxWidth } = props;
if (delayShow === undefined) delayShow = 300;
if (maxWidth === undefined) maxWidth = "max-w-sm";
const [show, setShow] = useState(false);
useEffect(() => {
let timeout = setTimeout(() => {});
if (hovered) {
timeout = setTimeout(() => hovered && setShow(true), delayShow);
} else {
setShow(false);
}
return () => clearTimeout(timeout);
}, [delayShow, hovered]);
let tooltipCSS = "";
let transformCSS = "";
let arrowParentCSS = "";
let arrowCSS = "";
switch (direction) {
case "left":
tooltipCSS = "[justify-self:end] [align-self:center]";
transformCSS = `translateX(-${offset})`;
arrowParentCSS = "w-4 -right-4 top-0 bottom-0";
arrowCSS = "border-l-light";
break;
case "right":
tooltipCSS = "[justify-self:start] [align-self:center]";
transformCSS = `translateX(${offset})`;
arrowParentCSS = "w-4 -left-4 top-0 bottom-0";
arrowCSS = "border-r-light";
break;
case "top":
tooltipCSS = "[align-self:end]";
transformCSS = `translateY(-${offset})`;
arrowParentCSS = "h-4 -bottom-4 left-0 right-0";
arrowCSS = "border-t-light";
break;
case "bottom":
tooltipCSS = "[align-self:start]";
transformCSS = `translateY(${offset})`;
arrowParentCSS = "h-4 -top-4 left-0 right-0";
arrowCSS = "border-b-light";
break;
}
return (
<div
className={`fixed z-[100] drop-shadow-shade-xl transition-opacity ${maxWidth} ${
show
? "opacity-100 pointer-events-auto"
: "opacity-0 pointer-events-none"
} ${tooltipCSS}`}
style={{ transform: transformCSS }}
>
<div className={`absolute grid ${arrowParentCSS}`}>
<div
className={`w-0 h-0 border-8 border-[transparent] place-self-center ${arrowCSS}`}
/>
</div>
<div className="p-4 px-6 bg-light rounded-md">{children}</div>
</div>
);
}