2021-12-31 09:42:52 +00:00
|
|
|
import {
|
|
|
|
arrow,
|
|
|
|
computePosition,
|
2023-08-21 16:13:03 +00:00
|
|
|
Coords,
|
2021-12-31 09:42:52 +00:00
|
|
|
flip,
|
|
|
|
offset,
|
|
|
|
Placement,
|
|
|
|
shift,
|
|
|
|
} from "@floating-ui/dom";
|
2020-07-27 09:35:34 +00:00
|
|
|
|
2020-07-28 15:57:48 +00:00
|
|
|
const Tooltip = (): void => {
|
2021-11-05 14:36:34 +00:00
|
|
|
const tooltipContainers: NodeListOf<HTMLElement> =
|
|
|
|
document.querySelectorAll("[data-tooltip]");
|
2020-07-27 09:35:34 +00:00
|
|
|
|
|
|
|
for (let i = 0; i < tooltipContainers.length; i++) {
|
|
|
|
const tooltipReference = tooltipContainers[i];
|
|
|
|
const tooltipContent = tooltipReference.title;
|
|
|
|
|
|
|
|
const tooltip = document.createElement("div");
|
2020-10-02 15:38:16 +00:00
|
|
|
tooltip.setAttribute("id", "tooltip" + i);
|
2020-07-27 09:35:34 +00:00
|
|
|
tooltip.setAttribute(
|
|
|
|
"class",
|
2021-12-31 09:42:52 +00:00
|
|
|
"absolute px-2 py-1 text-sm bg-gray-900 text-white rounded max-w-xs z-50"
|
2020-07-27 09:35:34 +00:00
|
|
|
);
|
|
|
|
tooltip.innerHTML = tooltipContent;
|
2021-12-31 09:42:52 +00:00
|
|
|
const arrowElement = document.createElement("div");
|
|
|
|
arrowElement.setAttribute(
|
|
|
|
"class",
|
|
|
|
"absolute bg-gray-900 w-2 h-2 rotate-45"
|
|
|
|
);
|
|
|
|
arrowElement.setAttribute("id", "arrow" + i);
|
|
|
|
tooltip.appendChild(arrowElement);
|
2020-07-27 09:35:34 +00:00
|
|
|
|
2021-12-31 09:42:52 +00:00
|
|
|
const update = () => {
|
|
|
|
computePosition(tooltipReference, tooltip, {
|
|
|
|
placement: tooltipReference.dataset.tooltip as Placement,
|
|
|
|
middleware: [
|
|
|
|
flip(),
|
|
|
|
shift(),
|
|
|
|
offset(8),
|
|
|
|
arrow({ element: arrowElement }),
|
|
|
|
],
|
|
|
|
}).then(({ x, y, placement, middlewareData }) => {
|
|
|
|
Object.assign(tooltip.style, {
|
|
|
|
left: `${x}px`,
|
|
|
|
top: `${y}px`,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Accessing the data
|
2023-08-21 16:13:03 +00:00
|
|
|
const { x: arrowX, y: arrowY } = middlewareData.arrow as Coords;
|
2021-12-31 09:42:52 +00:00
|
|
|
|
|
|
|
const staticSide = {
|
|
|
|
top: "bottom",
|
|
|
|
right: "left",
|
|
|
|
bottom: "top",
|
|
|
|
left: "right",
|
|
|
|
}[placement.split("-")[0]];
|
|
|
|
|
|
|
|
Object.assign(arrowElement.style, {
|
|
|
|
left: arrowX != null ? `${arrowX}px` : "",
|
|
|
|
top: arrowY != null ? `${arrowY}px` : "",
|
|
|
|
right: "",
|
|
|
|
bottom: "",
|
|
|
|
[staticSide as string]: "-4px",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
2020-07-27 09:35:34 +00:00
|
|
|
|
2021-12-31 09:42:52 +00:00
|
|
|
const showTooltip = () => {
|
2020-07-27 09:35:34 +00:00
|
|
|
tooltipReference.removeAttribute("title");
|
2020-10-02 15:38:16 +00:00
|
|
|
tooltipReference.setAttribute("aria-describedby", "tooltip" + i);
|
2020-07-27 09:35:34 +00:00
|
|
|
document.body.appendChild(tooltip);
|
2021-12-31 09:42:52 +00:00
|
|
|
update();
|
2020-07-27 09:35:34 +00:00
|
|
|
};
|
|
|
|
|
2021-12-31 09:42:52 +00:00
|
|
|
const hideTooltip = () => {
|
2020-10-02 15:38:16 +00:00
|
|
|
const element = document.getElementById("tooltip" + i);
|
2020-07-27 09:35:34 +00:00
|
|
|
tooltipReference.removeAttribute("aria-describedby");
|
|
|
|
tooltipReference.setAttribute("title", tooltipContent);
|
|
|
|
if (element) {
|
|
|
|
document.body.removeChild(element);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const showEvents = ["mouseenter", "focus"];
|
|
|
|
const hideEvents = ["mouseleave", "blur"];
|
|
|
|
|
|
|
|
showEvents.forEach((event) => {
|
2021-12-31 09:42:52 +00:00
|
|
|
tooltipReference.addEventListener(event, showTooltip);
|
2020-07-27 09:35:34 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
hideEvents.forEach((event) => {
|
2021-12-31 09:42:52 +00:00
|
|
|
tooltipReference.addEventListener(event, hideTooltip);
|
2020-07-27 09:35:34 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Tooltip;
|