Newer
Older
vmk-ui-kit / src / js / components / dropdowns.js
/**
 * VMK UI Kit browser dropdown helper.
 *
 * Mirrors gnexus-ui-kit dropdown helpers:
 *   init(root), toggle(trigger), open(trigger), close(trigger)
 */

const initializedRoots = new WeakSet();

function findMenu(trigger) {
  const dropdown = trigger.closest(".dropdown");
  return dropdown?.querySelector(".dropdown-menu");
}

function toggle(trigger) {
  const menu = findMenu(trigger);
  if (!menu) return;
  menu.classList.toggle("is-open");
}

function open(trigger) {
  findMenu(trigger)?.classList.add("is-open");
}

function close(trigger) {
  findMenu(trigger)?.classList.remove("is-open");
}

function closeAll(root = document) {
  root.querySelectorAll(".dropdown-menu.is-open").forEach(menu => menu.classList.remove("is-open"));
}

function handleClick(event) {
  const trigger = event.target.closest("[data-dropdown-trigger]");
  if (trigger) {
    event.stopPropagation();
    toggle(trigger);
    return;
  }

  if (!event.target.closest(".dropdown-menu")) {
    closeAll(document);
  }
}

function handleKeydown(event) {
  if (event.key === "Escape") {
    closeAll(document);
  }
}

function init(root = document) {
  if (initializedRoots.has(root)) return;

  root.addEventListener("click", handleClick);
  root.addEventListener("keydown", handleKeydown);
  initializedRoots.add(root);
}

export default {
  init,
  toggle,
  open,
  close
};