mirror of
https://github.com/ae-utbm/sith.git
synced 2025-05-16 22:44:05 +00:00
Improve tooltips by using mutation observers
This commit is contained in:
parent
19aac8f302
commit
d1e5c93a08
@ -18,7 +18,7 @@ import {
|
|||||||
* Note: placement are suggestions and the position could change if the popup gets
|
* Note: placement are suggestions and the position could change if the popup gets
|
||||||
* outside of the screen.
|
* outside of the screen.
|
||||||
*
|
*
|
||||||
* You can customize your tooltip by passing additionnal classes or ids to it
|
* You can customize your tooltip by passing additional classes or ids to it
|
||||||
* You can use `tooltip-class` and `tooltip-id` to add additional elements to the
|
* You can use `tooltip-class` and `tooltip-id` to add additional elements to the
|
||||||
* `class` and `id` attribute of the generated tooltip
|
* `class` and `id` attribute of the generated tooltip
|
||||||
*
|
*
|
||||||
@ -32,7 +32,7 @@ import {
|
|||||||
|
|
||||||
type Status = "open" | "close";
|
type Status = "open" | "close";
|
||||||
|
|
||||||
const tooltips = new Map();
|
const tooltips: Map<HTMLElement, HTMLElement> = new Map();
|
||||||
|
|
||||||
function getPosition(element: HTMLElement): Placement | "auto" {
|
function getPosition(element: HTMLElement): Placement | "auto" {
|
||||||
const position = element.getAttribute("tooltip-position");
|
const position = element.getAttribute("tooltip-position");
|
||||||
@ -93,12 +93,10 @@ function getTooltip(element: HTMLElement) {
|
|||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener("mouseover", (event: MouseEvent) => {
|
function tooltipMouseover(event: MouseEvent) {
|
||||||
const target = event.target as HTMLElement;
|
// We get the closest tooltip to have a consistent behavior
|
||||||
if (!target.hasAttribute("tooltip")) {
|
// when hovering over a child element of a tooltip marked element
|
||||||
return;
|
const target = (event.target as HTMLElement).closest("[tooltip]") as HTMLElement;
|
||||||
}
|
|
||||||
|
|
||||||
const tooltip = getTooltip(target);
|
const tooltip = getTooltip(target);
|
||||||
updateTooltip(target, tooltip, "open");
|
updateTooltip(target, tooltip, "open");
|
||||||
|
|
||||||
@ -113,13 +111,57 @@ addEventListener("mouseover", (event: MouseEvent) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.body.append(tooltip);
|
document.body.append(tooltip);
|
||||||
});
|
}
|
||||||
|
|
||||||
addEventListener("mouseout", (event: MouseEvent) => {
|
|
||||||
const target = event.target as HTMLElement;
|
|
||||||
if (!target.hasAttribute("tooltip")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function tooltipMouseout(event: MouseEvent) {
|
||||||
|
// We get the closest tooltip to have a consistent behavior
|
||||||
|
// when hovering over a child element of a tooltip marked element
|
||||||
|
const target = (event.target as HTMLElement).closest("[tooltip]") as HTMLElement;
|
||||||
updateTooltip(target, getTooltip(target), "close");
|
updateTooltip(target, getTooltip(target), "close");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
for (const el of document.querySelectorAll("[tooltip]")) {
|
||||||
|
el.addEventListener("mouseover", tooltipMouseover);
|
||||||
|
el.addEventListener("mouseout", tooltipMouseout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add / remove callback when tooltip attribute is added / removed
|
||||||
|
new MutationObserver((mutations: MutationRecord[]) => {
|
||||||
|
for (const mutation of mutations) {
|
||||||
|
const target = mutation.target as HTMLElement;
|
||||||
|
target.removeEventListener("mouseover", tooltipMouseover);
|
||||||
|
target.removeEventListener("mouseout", tooltipMouseout);
|
||||||
|
if (target.hasAttribute("tooltip")) {
|
||||||
|
target.addEventListener("mouseover", tooltipMouseover);
|
||||||
|
target.addEventListener("mouseout", tooltipMouseout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).observe(document.body, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ["tooltip"],
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove orphan tooltips
|
||||||
|
new MutationObserver((mutations: MutationRecord[]) => {
|
||||||
|
for (const mutation of mutations) {
|
||||||
|
for (const node of mutation.removedNodes) {
|
||||||
|
if (node.nodeType !== node.ELEMENT_NODE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const target = node as HTMLElement;
|
||||||
|
if (!target.hasAttribute("tooltip")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tooltips.has(target)) {
|
||||||
|
tooltips.get(target).remove();
|
||||||
|
tooltips.delete(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).observe(document.body, {
|
||||||
|
subtree: true,
|
||||||
|
childList: true,
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user