UNPKG

on-codemerge

Version:

A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product

92 lines (91 loc) 4.73 kB
var m = Object.defineProperty; var r = (c, t, e) => t in c ? m(c, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[t] = e; var s = (c, t, e) => r(c, typeof t != "symbol" ? t + "" : t, e); class h { constructor(t, e, i = {}) { s(this, "menu"); s(this, "editor"); s(this, "activeElement", null); s(this, "subMenus", []); // Для управления вложенными меню s(this, "orientation"); s(this, "buttons", []); s(this, "handleClickOutside", (t) => { this.menu.contains(t.target) || this.hide(); }); s(this, "handleEscapeKey", (t) => { t.key === "Escape" && this.hide(); }); this.orientation = i.orientation || "vertical", this.buttons = e, this.editor = t, this.menu = this.createMenu(), document.body.appendChild(this.menu), this.setupEventListeners(); } createMenu() { const t = document.createElement("div"); return t.className = `context-menu ${this.orientation === "horizontal" ? "horizontal" : ""}`, this.buttons.forEach((e) => { if (e.type === "divider") { const i = document.createElement("div"); i.className = "menu-divider", t.appendChild(i); } else if (e.type === "custom" && e.customHTML) { const i = document.createElement("div"); i.innerHTML = e.customHTML, t.appendChild(i); } else { const i = document.createElement("button"); i.className = `menu-item ${e.className || ""}`, i.dataset.action = e.action || "", e.title && (i.title = e.title || ""); const l = e.icon ? `<span class="menu-icon">${e.icon}</span>` : "", o = e.label ? `<span class="menu-label">${e.label || ""}</span> ` : ""; if (i.innerHTML = e.iconPosition === "right" ? `${o}${l}` : `${l}${o}`, typeof e.disabled == "function" ? i.disabled = e.disabled() : i.disabled = e.disabled || !1, e.onClick && i.addEventListener("click", () => { var n; (n = e.onClick) == null || n.call(e, this.activeElement), e.closeOnClick !== !1 && this.hide(); }), e.hotkey && document.addEventListener("keydown", (n) => { var d, a; n.ctrlKey && n.key === ((d = e.hotkey) == null ? void 0 : d.toLowerCase()) && ((a = e.onClick) == null || a.call(e, this.activeElement), this.hide()); }), e.subMenu) { const n = new h(this.editor, e.subMenu); this.subMenus.push(n), i.addEventListener("mouseenter", () => { n.show(i, i.offsetWidth, 0); }), i.addEventListener("mouseleave", () => { n.hide(); }); } t.appendChild(i); } }), t; } setupEventListeners() { document.addEventListener("click", this.handleClickOutside), document.addEventListener("keydown", this.handleEscapeKey); } show(t, e, i) { this.activeElement = t, this.menu.style.display = "flex", this.menu.style.opacity = "0", this.menu.style.transform = "translateY(-10px)", this.menu.style.left = `${e}px`, this.menu.style.top = `${i}px`, setTimeout(() => { this.menu.style.opacity = "1", this.menu.style.transform = "translateY(0)"; }, 10), setTimeout(() => { const l = this.menu.getBoundingClientRect(), o = window.innerWidth, n = window.innerHeight; if (l.right > o) { const d = l.right - o + 100; this.menu.style.left = `${e - d}px`; } if (l.bottom > n) { const d = l.bottom - n; this.menu.style.top = `${i - d}px`; } }, 100); } hide() { this.menu.style.opacity = "0", this.menu.style.transform = "translateY(-10px)", setTimeout(() => { this.menu.style.display = "none"; }, 200), this.subMenus.forEach((t) => t.hide()), this.activeElement = null; } updateButtons(t) { this.menu.innerHTML = "", this.buttons = t, this.menu.appendChild(this.createMenu()); } updateButtonState(t, e) { const i = this.menu.querySelector(`[data-action="${t}"]`); i && (e.label !== void 0 && (i.querySelector(".menu-label").textContent = e.label), e.icon !== void 0 && (i.querySelector(".menu-icon").innerHTML = e.icon), e.disabled !== void 0 && (typeof e.disabled == "function" ? i.disabled = e.disabled() : i.disabled = e.disabled), e.checked !== void 0 && i instanceof HTMLInputElement && (i.checked = e.checked)); } getElement() { return this.menu; } destroy() { document.removeEventListener("click", this.handleClickOutside), document.removeEventListener("keydown", this.handleEscapeKey), this.subMenus.forEach((t) => t.destroy()), this.subMenus = [], this.menu.parentElement && this.menu.parentElement.removeChild(this.menu), this.menu = null, this.editor = null, this.activeElement = null, this.buttons = []; } } export { h as ContextMenu };