PopoverManager.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. import { queryElementsRoots } from "../../utils/dom";
  7. export default class PopoverManager {
  8. constructor() {
  9. // --------------------------------------------------------------------------
  10. //
  11. // Private Properties
  12. //
  13. // --------------------------------------------------------------------------
  14. this.registeredElements = new WeakMap();
  15. this.registeredElementCount = 0;
  16. // --------------------------------------------------------------------------
  17. //
  18. // Private Methods
  19. //
  20. // --------------------------------------------------------------------------
  21. this.queryPopover = (composedPath) => {
  22. const { registeredElements } = this;
  23. const registeredElement = composedPath.find((pathEl) => registeredElements.has(pathEl));
  24. return registeredElements.get(registeredElement);
  25. };
  26. this.clickHandler = (event) => {
  27. const composedPath = event.composedPath();
  28. const popover = this.queryPopover(composedPath);
  29. if (popover) {
  30. popover.toggle();
  31. return;
  32. }
  33. queryElementsRoots(event.target, "calcite-popover")
  34. .filter((popover) => popover.autoClose && popover.open && !composedPath.includes(popover))
  35. .forEach((popover) => popover.toggle(false));
  36. };
  37. }
  38. // --------------------------------------------------------------------------
  39. //
  40. // Public Methods
  41. //
  42. // --------------------------------------------------------------------------
  43. registerElement(referenceEl, popover) {
  44. this.registeredElementCount++;
  45. this.registeredElements.set(referenceEl, popover);
  46. if (this.registeredElementCount === 1) {
  47. this.addListeners();
  48. }
  49. }
  50. unregisterElement(referenceEl) {
  51. if (this.registeredElements.delete(referenceEl)) {
  52. this.registeredElementCount--;
  53. }
  54. if (this.registeredElementCount === 0) {
  55. this.removeListeners();
  56. }
  57. }
  58. addListeners() {
  59. document.addEventListener("pointerdown", this.clickHandler, { capture: true });
  60. }
  61. removeListeners() {
  62. document.removeEventListener("pointerdown", this.clickHandler, { capture: true });
  63. }
  64. }