Create basic tooltip library

This commit is contained in:
2025-04-25 15:35:39 +02:00
parent 5e953d04fe
commit 35e96fb875
5 changed files with 99 additions and 40 deletions

View File

@ -0,0 +1,62 @@
import { type Placement, computePosition } from "@floating-ui/dom";
/**
* Library usage:
* Add a `tooltip` attribute to any html element with it's tooltip text
* You can control the position of the tooltp with the `position` attribute
* Allowed placements are `top`, `right`, `bottom`, `left`
* You can add `-start` and `-end` to all allowed placement values
**/
function getPlacement(element: HTMLElement): Placement {
const position = element.getAttribute("position");
if (position) {
return position as Placement;
}
return "bottom";
}
function getTooltip(element: HTMLElement) {
for (const tooltip of document.body.getElementsByClassName("tooltip")) {
if (tooltip.textContent === element.getAttribute("tooltip")) {
return tooltip as HTMLElement;
}
}
const tooltip = document.createElement("div");
document.body.append(tooltip);
tooltip.classList.add("tooltip");
tooltip.innerText = element.getAttribute("tooltip");
return tooltip;
}
addEventListener("mouseover", (event: MouseEvent) => {
const target = event.target as HTMLElement;
if (!target.hasAttribute("tooltip")) {
return;
}
const tooltip = getTooltip(target);
tooltip.setAttribute("tooltip-status", "open");
computePosition(target, tooltip, {
placement: getPlacement(target),
}).then(({ x, y }) => {
Object.assign(tooltip.style, {
left: `${x}px`,
top: `${y}px`,
});
});
document.body.append(tooltip);
});
addEventListener("mouseout", (event: MouseEvent) => {
const target = event.target as HTMLElement;
if (!target.hasAttribute("tooltip")) {
return;
}
getTooltip(target).setAttribute("tooltip-status", "close");
});

View File

@ -45,17 +45,10 @@ body {
}
}
[tooltip] {
position: relative;
}
[tooltip]::before {
.tooltip {
@include shadow;
z-index: 1;
pointer-events: none;
content: attr(tooltip);
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: #fff;
border: 0.5px solid hsl(0, 0%, 50%);
@ -64,44 +57,20 @@ body {
position: absolute;
white-space: nowrap;
opacity: 0;
transition: opacity 500ms ease-out;
top: 120%; // Put the tooltip under the element
transition: opacity 500ms ease-in;
position: absolute;
width: max-content;
left: 0;
top: 0;
}
[tooltip]:hover::before {
.tooltip[tooltip-status=open] {
opacity: 1;
transition: opacity 500ms ease-in;
}
[no-hover][tooltip]::before {
opacity: 1;
transition: opacity 500ms ease-in;
}
[position="top"][tooltip]::before {
top: initial;
bottom: 120%;
}
[position="bottom"][tooltip]::before {
top: 120%;
bottom: initial;
}
[position="left"][tooltip]::before {
top: initial;
bottom: 0%;
left: initial;
right: 65%;
}
[position="right"][tooltip]::before {
top: initial;
bottom: 0%;
left: 150%;
right: initial;
}
.ib {
display: inline-block;
padding: 1px;