/*! * All material copyright ESRI, All Rights Reserved, unless otherwise specified. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details. * v1.0.0-beta.97 */ import { isPrimaryPointerButton } from "../../utils/dom"; import { isActivationKey } from "../../utils/key"; export default class PopoverManager { constructor() { // -------------------------------------------------------------------------- // // Private Properties // // -------------------------------------------------------------------------- this.registeredElements = new Map(); this.registeredElementCount = 0; // -------------------------------------------------------------------------- // // Private Methods // // -------------------------------------------------------------------------- this.queryPopover = (composedPath) => { const { registeredElements } = this; const registeredElement = composedPath.find((pathEl) => registeredElements.has(pathEl)); return registeredElements.get(registeredElement); }; this.togglePopovers = (event) => { const composedPath = event.composedPath(); const togglePopover = this.queryPopover(composedPath); if (togglePopover && !togglePopover.triggerDisabled) { togglePopover.toggle(); } Array.from(this.registeredElements.values()) .filter((popover) => popover !== togglePopover && popover.autoClose && popover.open && !composedPath.includes(popover)) .forEach((popover) => popover.toggle(false)); }; this.keyHandler = (event) => { if (event.defaultPrevented || !isActivationKey(event.key)) { return; } this.togglePopovers(event); }; this.clickHandler = (event) => { if (isPrimaryPointerButton(event)) { this.togglePopovers(event); } }; } // -------------------------------------------------------------------------- // // Public Methods // // -------------------------------------------------------------------------- registerElement(referenceEl, popover) { this.registeredElementCount++; this.registeredElements.set(referenceEl, popover); if (this.registeredElementCount === 1) { this.addListeners(); } } unregisterElement(referenceEl) { if (this.registeredElements.delete(referenceEl)) { this.registeredElementCount--; } if (this.registeredElementCount === 0) { this.removeListeners(); } } addListeners() { document.addEventListener("pointerdown", this.clickHandler, { capture: true }); document.addEventListener("keydown", this.keyHandler, { capture: true }); } removeListeners() { document.removeEventListener("pointerdown", this.clickHandler, { capture: true }); document.removeEventListener("keydown", this.keyHandler, { capture: true }); } }