dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
97 lines (96 loc) • 4.65 kB
JavaScript
class o {
constructor(s) {
this.enableSubmenuTimer = -1, this.isConnected = !1, this.submenuOpenDelay = 100, this.handleMouseMove = (e) => {
this.host.style.setProperty(
"--safe-triangle-cursor-x",
`${e.clientX}px`
), this.host.style.setProperty(
"--safe-triangle-cursor-y",
`${e.clientY}px`
);
}, this.handleMouseOver = () => {
this.hasSubmenu() && this.enableSubmenu(!0);
}, this.handleKeyDown = (e) => {
const t = e.target, i = t.closest("dap-ds-navigation-menu-item");
if (!(i && i !== this.host))
switch (e.key) {
case "Escape":
e.preventDefault(), e.stopPropagation(), this.disableSubmenu(), this.host.focus();
break;
case "Tab":
this.disableSubmenu();
break;
case "ArrowLeft":
e.target !== this.host && (e.preventDefault(), e.stopPropagation(), this.host.focus(), this.disableSubmenu());
break;
case "ArrowRight":
this.host.level > 0 && this.handleSubmenuEntry(e);
break;
case "Enter":
case " ":
(t === this.host || this.host.contains(t) && !t.closest("dap-ds-navigation-menu-item")) && this.handleSubmenuEntry(e);
break;
}
}, this.handleClick = (e) => {
var t;
e.target === this.host ? (e.preventDefault(), e.stopPropagation()) : e.target instanceof Element && (e.target.tagName.toLowerCase() === "dap-ds-navigation-menu-item" || (t = e.target.getAttribute("role")) != null && t.startsWith("menuitem")) && this.disableSubmenu();
}, this.handleFocusOut = (e) => {
e.relatedTarget && e.relatedTarget instanceof Element && this.host.contains(e.relatedTarget) || this.disableSubmenu();
}, this.updateSafeTriangle = () => {
const e = this.host.popup;
if (!e || !this.host.opened)
return;
const { left: t, top: i, height: h } = e.getBoundingClientRect();
this.host.style.setProperty("--safe-triangle-submenu-start-x", `${t}px`), this.host.style.setProperty("--safe-triangle-submenu-start-y", `${i}px`), this.host.style.setProperty("--safe-triangle-submenu-end-x", `${t}px`), this.host.style.setProperty(
"--safe-triangle-submenu-end-y",
`${i + h}px`
);
}, (this.host = s).addController(this);
}
hostConnected() {
this.hasSubmenu() && !this.host.disabled && this.addListeners();
}
hostDisconnected() {
this.removeListeners();
}
hostUpdated() {
this.hasSubmenu() && !this.host.disabled ? this.addListeners() : this.removeListeners();
}
hasSubmenu() {
return this.host.hasNestedItems || this.host.hasContent;
}
addListeners() {
this.isConnected || (this.host.addEventListener("mousemove", this.handleMouseMove), this.host.addEventListener("mouseover", this.handleMouseOver), this.host.addEventListener("keydown", this.handleKeyDown), this.host.addEventListener("click", this.handleClick), this.host.addEventListener("focusout", this.handleFocusOut), this.isConnected = !0);
}
removeListeners() {
this.isConnected && (this.host.removeEventListener("mousemove", this.handleMouseMove), this.host.removeEventListener("mouseover", this.handleMouseOver), this.host.removeEventListener("keydown", this.handleKeyDown), this.host.removeEventListener("click", this.handleClick), this.host.removeEventListener("focusout", this.handleFocusOut), this.isConnected = !1);
}
handleSubmenuEntry(s) {
this.hasSubmenu() && (s.preventDefault(), s.stopPropagation(), this.host.opened ? this.host.focusFirstDropdownChild() : (this.enableSubmenu(!1), this.host.updateComplete.then(() => {
this.host.focusFirstDropdownChild();
})));
}
setSubmenuState(s, e = !1) {
s !== this.host.opened && (s ? (this.host.showDropDown(e), this.host.updateComplete.then(() => {
this.updateSafeTriangle();
})) : this.host.hideDropDown());
}
// Shows the submenu. Supports disabling the opening delay for keyboard events
enableSubmenu(s = !0) {
s ? (window.clearTimeout(this.enableSubmenuTimer), this.enableSubmenuTimer = window.setTimeout(() => {
this.setSubmenuState(!0, !0);
}, this.submenuOpenDelay)) : this.setSubmenuState(!0, !1);
}
disableSubmenu() {
window.clearTimeout(this.enableSubmenuTimer), this.setSubmenuState(!1);
}
// Public method to cancel pending submenu opening timer
// Used when closing siblings to prevent race conditions
cancelPendingOpen() {
window.clearTimeout(this.enableSubmenuTimer);
}
}
export {
o as SubmenuController
};
//# sourceMappingURL=submenu-controller.js.map