livebook/assets/js/menu/index.js

45 lines
1.2 KiB
JavaScript
Raw Normal View History

/**
* A hook controlling a toggleable menu.
*
* The element should have two children:
*
* * one annotated with `data-toggle` being a clickable element
*
* * one annotated with `data-content` with menu content
*/
const Menu = {
mounted() {
const toggleElement = this.el.querySelector("[data-toggle]");
if (!toggleElement) {
throw new Error("Menu must have a child with data-toggle attribute");
}
const contentElement = this.el.querySelector("[data-content]");
if (!contentElement) {
throw new Error("Menu must have a child with data-content attribute");
}
toggleElement.addEventListener("click", (event) => {
if (this.el.hasAttribute("data-js-open")) {
this.el.removeAttribute("data-js-open");
} else {
this.el.setAttribute("data-js-open", "true");
// Postpone callback registration until the current click finishes bubbling.
setTimeout(() => {
document.addEventListener(
"click",
(event) => {
this.el.removeAttribute("data-js-open");
},
{ once: true }
);
}, 0);
}
});
},
};
export default Menu;