Initialize tooltips dynamically

This commit is contained in:
Konrad Szwarc 2023-01-31 21:55:15 +01:00
parent 544ad70d87
commit f51c4044b9

View file

@ -1,5 +1,4 @@
import { autoUpdate, computePosition, flip, offset, Placement, shift } from '@floating-ui/dom';
import { nanoid } from 'nanoid';
import type { Placement } from '@floating-ui/dom';
interface UpdateTooltipOptions {
element: HTMLElement;
@ -7,7 +6,13 @@ interface UpdateTooltipOptions {
placement: Placement;
}
const updateTooltip =
const elementsWithTooltipData = [...document.querySelectorAll('[data-tooltip]')] as HTMLElement[];
if (elementsWithTooltipData.length > 0) {
Promise.all([import('@floating-ui/dom'), import('nanoid')]).then(([floatingUi, { nanoid }]) => {
const { autoUpdate, computePosition, flip, offset, shift } = floatingUi;
const updateTooltip =
({ element, tooltip, placement }: UpdateTooltipOptions) =>
() => {
computePosition(element, tooltip, { placement, middleware: [offset(8), flip(), shift({ padding: 8 })] }).then(
@ -20,10 +25,10 @@ const updateTooltip =
);
};
const tooltipClass =
const tooltipClass =
/* tw */ 'absolute top-0 left-0 hidden max-w-sm animate-show rounded-lg bg-gray-700 px-3 py-1 text-white dark:bg-gray-100 dark:text-gray-800 sm:max-w-xs';
const createTooltip = (content: string) => {
const createTooltip = (content: string) => {
const tooltip = document.createElement('div');
tooltip.innerText = content;
@ -32,9 +37,9 @@ const createTooltip = (content: string) => {
tooltip.setAttribute('role', 'tooltip');
return tooltip;
};
};
const addListeners = (element: HTMLElement, tooltip: HTMLElement, updateFn: () => void) => {
const addListeners = (element: HTMLElement, tooltip: HTMLElement, updateFn: () => void) => {
element.addEventListener('mouseenter', () => {
tooltip.style.display = 'block';
updateFn();
@ -43,9 +48,9 @@ const addListeners = (element: HTMLElement, tooltip: HTMLElement, updateFn: () =
element.addEventListener('mouseleave', () => {
tooltip.style.display = '';
});
};
};
const creteTooltipsForElements = (elements: HTMLElement[]) => {
const creteTooltipsForElements = (elements: HTMLElement[]) => {
const tooltipsContainer = document.createElement('div');
const tooltips = elements.map((element) => {
@ -57,12 +62,9 @@ const creteTooltipsForElements = (elements: HTMLElement[]) => {
document.body.appendChild(tooltipsContainer);
return tooltips;
};
};
const elements = [...document.querySelectorAll('[data-tooltip]')] as HTMLElement[];
const elementsWithTooltips = creteTooltipsForElements(elements);
elementsWithTooltips.forEach(({ element, tooltip }) => {
creteTooltipsForElements(elementsWithTooltipData).forEach(({ element, tooltip }) => {
const placement = (element.dataset.tooltipPlacement ?? 'top') as Placement;
const updateFn = updateTooltip({ element, tooltip, placement });
@ -70,4 +72,6 @@ elementsWithTooltips.forEach(({ element, tooltip }) => {
autoUpdate(element, tooltip, updateFn);
addListeners(element, tooltip, updateFn);
});
});
});
}