seti-ramesesv1
Version:
Reusable components and context for Next.js apps
82 lines (79 loc) • 2.88 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { clsx } from '../../node_modules/clsx/dist/clsx.js';
import { forwardRef, useState, useRef, useEffect } from 'react';
import { createPortal } from 'react-dom';
import styles from '../../styles/Tooltip.module.css.js';
const Tooltip = forwardRef(({ content, children, position = "top", delay = 0, color = "dark" }, ref) => {
const [visible, setVisible] = useState(false);
const [coords, setCoords] = useState({
top: 0,
left: 0,
});
const [hoverTimer, setHoverTimer] = useState(null);
const wrapperRef = useRef(null);
const showTooltip = () => {
if (!wrapperRef.current)
return;
const rect = wrapperRef.current.getBoundingClientRect();
let top = 0;
let left = 0;
switch (position) {
case "top":
top = rect.top;
left = rect.left + rect.width / 2;
break;
case "bottom":
top = rect.bottom;
left = rect.left + rect.width / 2;
break;
case "left":
top = rect.top + rect.height / 2;
left = rect.left;
break;
case "right":
top = rect.top + rect.height / 2;
left = rect.right;
break;
}
const timer = setTimeout(() => {
setCoords({ top, left });
setVisible(true);
}, delay);
setHoverTimer(timer);
};
const hideTooltip = () => {
if (hoverTimer)
clearTimeout(hoverTimer);
setVisible(false);
};
useEffect(() => {
return () => {
if (hoverTimer)
clearTimeout(hoverTimer);
};
}, [hoverTimer]);
// position-specific transforms
const getTransform = () => {
switch (position) {
case "top":
return "translate(-50%, -100%)";
case "bottom":
return "translate(-50%, 0%)";
case "left":
return "translate(-100%, -50%)";
case "right":
return "translate(0%, -50%)";
default:
return "translate(-50%, -100%)";
}
};
return (jsxs("div", { ref: wrapperRef, className: styles.wrapper, onMouseEnter: showTooltip, onMouseLeave: hideTooltip, children: [children, visible &&
createPortal(jsx("div", { className: clsx(styles.tooltip, styles[color], "fixed pointer-events-none"), style: {
top: coords.top,
left: coords.left,
transform: getTransform(),
}, children: content }), document.body)] }));
});
Tooltip.displayName = "Tooltip";
export { Tooltip as default };
//# sourceMappingURL=Tooltip.js.map