import { Tooltip } from "bootstrap"; type ConstructorTypeParent = "parent"; type ConstructorTypeDom = "dom"; interface ParentSelectorTooltips { type: ConstructorTypeParent /** The parent element that contains Dom elements for which tooltips shall be created. */ parentSelector: string; } interface DomProvidedTooltips { type: ConstructorTypeDom; /** Dom elements for which tooltips shall be created. */ elements: HTMLElement | NodeListOf; } interface TooltipsOptions { /** Tooltip options. */ options?: Partial|null|undefined; } export type TooltipsConstructor = TooltipsOptions & (ParentSelectorTooltips|DomProvidedTooltips); export class Tooltips { /** BS tooltips instances */ private tooltips: Array = []; /** The parent element that contains Dom elements for which tooltips shall be created. */ private parentSelector: string | null = null; /** Dom elements for which tooltips shall be created. */ private elements: Array = []; /** Tooltip default options. */ private static defaultOptions: Partial = { delay: { show: 1250, hide: 0, }, }; /** Tooltip options. */ private options: Partial = {}; /** * @param parentSelector * @param options Tooltip options. */ constructor(params: TooltipsConstructor) { if (params.type === "parent") { this.parentSelectorConstructor(params); } if (params.type === "dom") { this.domPrividedTooltipsContructor(params); } } public static make(params: TooltipsConstructor = { type: "parent", parentSelector: "body"} ) { const fullParams = { ...{ type: "parent", options: {} }, ...params }; return new Tooltips(fullParams); } private parentSelectorConstructor({ parentSelector, options }: TooltipsOptions & ParentSelectorTooltips) { this.parentSelector = parentSelector; this.options = { ...Tooltips.defaultOptions, ...options }; this.initTooltips(); } private domPrividedTooltipsContructor({ elements, options }: TooltipsOptions & DomProvidedTooltips) { if (elements instanceof HTMLElement) { this.elements = [elements]; } else { this.elements = Array.from(elements); } this.options = { ...Tooltips.defaultOptions, ...options }; this.initTooltips(); } /** * Close all Bootstrap tooltips and reinstanciate them. */ public refreshTooltips(): void { this.closeBootstrapTooltip(); this.initTooltips(); } /** * Close all Bootstrap tooltips for ever. */ public closeBootstrapTooltip(): void { this.tooltips.forEach((tooltip) => { tooltip.hide(); // * Prevent pending tooltips beeing shown after we asked to hide them tooltip.disable(); }); } /** * Initialize tooltips */ private initTooltips() { this.closeBootstrapTooltip(); /** data-bs-toggle tooltips elements */ const elements = this.parentSelector ? [].slice .call(document.querySelectorAll(`${this.parentSelector} [data-bs-toggle="tooltip"]`)) : this.elements; this.tooltips = elements.map((tooltipTriggerEl) => { return new Tooltip(tooltipTriggerEl, this.options); }); } }