UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

86 lines (85 loc) 3.13 kB
/*! * All material copyright ESRI, All Rights Reserved, unless otherwise specified. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details. * v1.5.0-next.4 */ 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.open = !togglePopover.open; } Array.from(this.registeredElements.values()) .filter((popover) => popover !== togglePopover && popover.autoClose && popover.open && !composedPath.includes(popover)) .forEach((popover) => (popover.open = false)); }; this.keyHandler = (event) => { if (event.defaultPrevented) { return; } if (event.key === "Escape") { this.closeAllPopovers(); } else if (isActivationKey(event.key)) { 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(); } } closeAllPopovers() { Array.from(this.registeredElements.values()).forEach((popover) => (popover.open = false)); } 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 }); } }