Allow popup customization

This commit is contained in:
Antoine Bartuccio 2025-04-28 14:19:04 +02:00
parent 9d7b760aa9
commit 997259242e
3 changed files with 34 additions and 8 deletions

View File

@ -314,8 +314,9 @@ export class IcsCalendar extends inheritHtmlElement("div") {
click: async (event: Event) => { click: async (event: Event) => {
const button = event.target as HTMLButtonElement; const button = event.target as HTMLButtonElement;
button.classList.add("text-copy"); button.classList.add("text-copy");
if (!button.hasAttribute("position")) { button.setAttribute("tooltip-class", "text-copy");
button.setAttribute("position", "top"); if (!button.hasAttribute("tooltip-position")) {
button.setAttribute("tooltip-position", "top");
} }
if (button.classList.contains("text-copied")) { if (button.classList.contains("text-copied")) {
button.classList.remove("text-copied"); button.classList.remove("text-copied");
@ -329,6 +330,7 @@ export class IcsCalendar extends inheritHtmlElement("div") {
).toString(), ).toString(),
); );
setTimeout(() => { setTimeout(() => {
button.setAttribute("tooltip-class", "text-copied");
button.classList.remove("text-copied"); button.classList.remove("text-copied");
button.classList.add("text-copied"); button.classList.add("text-copied");
button.classList.remove("text-copy"); button.classList.remove("text-copy");

View File

@ -116,5 +116,8 @@ ics-calendar {
button.text-copied:hover { button.text-copied:hover {
transition: 500ms ease-out; transition: 500ms ease-out;
} }
}
.tooltip.text-copy {
opacity: 1;
} }

View File

@ -3,15 +3,21 @@ import { type Placement, computePosition } from "@floating-ui/dom";
/** /**
* Library usage: * Library usage:
* Add a `tooltip` attribute to any html element with it's tooltip text * 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 * You can control the position of the tooltp with the `tooltip-position` attribute
* Allowed placements are `top`, `right`, `bottom`, `left` * Allowed placements are `top`, `right`, `bottom`, `left`
* You can add `-start` and `-end` to all allowed placement values * You can add `-start` and `-end` to all allowed placement values
*
* You can customize your tooltip by passing additionnal classes or ids to it
* You can use `tooltip-class` and `tooltip-id` to add additional elements to the
* `class` and `id` attribute of the generated tooltip
**/ **/
type Status = "open" | "close";
const tooltips = new Map(); const tooltips = new Map();
function getPlacement(element: HTMLElement): Placement { function getPlacement(element: HTMLElement): Placement {
const position = element.getAttribute("position"); const position = element.getAttribute("tooltip-position");
if (position) { if (position) {
return position as Placement; return position as Placement;
} }
@ -21,12 +27,27 @@ function getPlacement(element: HTMLElement): Placement {
function createTooltip(element: HTMLElement) { function createTooltip(element: HTMLElement) {
const tooltip = document.createElement("div"); const tooltip = document.createElement("div");
document.body.append(tooltip); document.body.append(tooltip);
tooltip.classList.add("tooltip");
tooltip.innerText = element.getAttribute("tooltip");
tooltips.set(element, tooltip); tooltips.set(element, tooltip);
return tooltip; return tooltip;
} }
function updateTooltip(element: HTMLElement, tooltip: HTMLElement, status: Status) {
// Update tooltip status and set it's attributes and content
tooltip.setAttribute("tooltip-status", status);
tooltip.innerText = element.getAttribute("tooltip");
for (const attributes of [
{ src: "tooltip-class", dst: "class", default: ["tooltip"] },
{ src: "tooltip-id", dst: "id", default: [] },
]) {
let populated = attributes.default;
if (element.hasAttribute(attributes.src)) {
populated = populated.concat(element.getAttribute(attributes.src).split(" "));
}
tooltip.setAttribute(attributes.dst, populated.join(" "));
}
}
function getTooltip(element: HTMLElement) { function getTooltip(element: HTMLElement) {
const tooltip = tooltips.get(element); const tooltip = tooltips.get(element);
if (tooltip === undefined) { if (tooltip === undefined) {
@ -43,7 +64,7 @@ addEventListener("mouseover", (event: MouseEvent) => {
} }
const tooltip = getTooltip(target); const tooltip = getTooltip(target);
tooltip.setAttribute("tooltip-status", "open"); updateTooltip(target, tooltip, "open");
computePosition(target, tooltip, { computePosition(target, tooltip, {
placement: getPlacement(target), placement: getPlacement(target),
@ -63,5 +84,5 @@ addEventListener("mouseout", (event: MouseEvent) => {
return; return;
} }
getTooltip(target).setAttribute("tooltip-status", "close"); updateTooltip(target, getTooltip(target), "close");
}); });