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
259 lines (258 loc) • 13.7 kB
JavaScript
var g = Object.defineProperty;
var k = (d, a, n) => a in d ? g(d, a, { enumerable: !0, configurable: !0, writable: !0, value: n }) : d[a] = n;
var i = (d, a, n) => k(d, typeof a != "symbol" ? a + "" : a, n);
import { PopupHeader as $ } from "./PopupHeader.mjs";
import { PopupFooter as x } from "./PopupFooter.mjs";
class S {
constructor(a, n = {}) {
i(this, "popup");
i(this, "header", null);
i(this, "content");
i(this, "overlay");
i(this, "footer", null);
i(this, "isVisible", !1);
const { className: e = "", closeOnClickOutside: o = !0, items: t = [] } = n;
this.popup = this.createPopup(e), this.content = this.createContent(), this.overlay = this.createOverlay(), n.title && (this.header = new $(n.title, () => this.hide()).getElement(), this.popup.appendChild(this.header)), this.popup.appendChild(this.content), n.buttons && (this.footer = new x(n.buttons), this.popup.appendChild(this.footer.getElement())), t.length > 0 && this.setContent(this.createContentFromItems(t)), a.getInnerContainer().appendChild(this.overlay), a.getInnerContainer().appendChild(this.popup), o && this.overlay.addEventListener("mousedown", (c) => {
this.isVisible && !this.popup.contains(c.target) && this.hide();
}), document.addEventListener("keydown", (c) => {
this.isVisible && c.key === "Escape" && this.hide();
});
}
createPopup(a) {
const n = document.createElement("div");
return n.className = `popup ${a}`, n.style.display = "none", n;
}
createContent() {
const a = document.createElement("div");
return a.className = "popup-content", a;
}
createContentFromItems(a) {
const n = document.createElement("div");
return n.className = "popup-items-container", a.forEach((e) => {
var c, v, E, N, C;
const o = document.createElement("div");
if (o.className = `popup-item ${e.className || ""}`, e.label) {
const s = document.createElement("label");
s.className = "popup-item-label", s.textContent = e.label, o.appendChild(s);
}
let t;
switch (e.type) {
case "progress":
t = document.createElement("div"), t.className = `popup-progress ${e.className || ""}`;
const s = document.createElement("div");
s.className = "popup-progress-bar", s.style.width = `${e.value || 0}%`, t.appendChild(s);
break;
case "loader":
t = document.createElement("div"), t.className = `popup-loader ${e.className || ""}`;
const p = document.createElement("div");
p.className = "popup-loader-spinner", t.appendChild(p);
break;
case "input":
t = document.createElement("input"), t.setAttribute("type", "text"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("placeholder", e.placeholder || ""), t.setAttribute("value", e.value || "");
break;
case "text":
t = document.createElement("div"), t.className = `popup-item-input ${e.className || ""}`, t.innerText = e.value || "", t.setAttribute("placeholder", e.placeholder || "");
break;
case "checkbox":
t = document.createElement("input"), t.setAttribute("type", "checkbox"), t.className = `popup-item-input ${e.className || ""}`, e.value && (t.checked = !0);
break;
case "list":
t = document.createElement("select"), t.className = `popup-item-input ${e.className || ""}`, (c = e.options) == null || c.forEach((l) => {
const r = document.createElement("option");
r.value = l, r.textContent = l, e.value && l === e.value && (r.selected = !0), t.appendChild(r);
});
break;
case "textarea":
t = document.createElement("textarea"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("placeholder", e.placeholder || ""), t.textContent = e.value || "";
break;
case "radio":
t = document.createElement("div"), t.className = `popup-item-input ${e.className || ""}`, (v = e.options) == null || v.forEach((l) => {
const r = document.createElement("div");
r.className = "popup-radio-container";
const h = document.createElement("input");
h.setAttribute("type", "radio"), h.setAttribute("name", e.id), h.setAttribute("value", l), h.className = "popup-radio-input", e.value === l && (h.checked = !0);
const f = document.createElement("label");
f.className = "popup-radio-label", f.textContent = l, r.appendChild(h), r.appendChild(f), t.appendChild(r);
});
break;
case "date":
t = document.createElement("input"), t.setAttribute("type", "date"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("value", e.value || "");
break;
case "range":
t = document.createElement("input"), t.setAttribute("type", "range"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("min", ((E = e.min) == null ? void 0 : E.toString()) || "0"), t.setAttribute("max", ((N = e.max) == null ? void 0 : N.toString()) || "100"), t.setAttribute("step", ((C = e.step) == null ? void 0 : C.toString()) || "1"), t.setAttribute("value", e.value || "50");
break;
case "file":
t = document.createElement("input"), t.setAttribute("type", "file"), t.className = `popup-item-input ${e.className || ""}`, e.accept && t.setAttribute("accept", e.accept);
break;
case "number":
t = document.createElement("input"), t.setAttribute("type", "number"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("value", e.value || ""), e.min !== void 0 && t.setAttribute("min", e.min.toString()), e.max !== void 0 && t.setAttribute("max", e.max.toString()), e.step !== void 0 && t.setAttribute("step", e.step.toString());
break;
case "password":
t = document.createElement("input"), t.setAttribute("type", "password"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("placeholder", e.placeholder || "");
break;
case "email":
t = document.createElement("input"), t.setAttribute("type", "email"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("placeholder", e.placeholder || "");
break;
case "url":
t = document.createElement("input"), t.setAttribute("type", "url"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("placeholder", e.placeholder || "");
break;
case "color":
t = document.createElement("div"), t.className = `color-picker-container ${e.className || ""}`;
const y = document.createElement("h3");
y.className = "text-sm font-medium text-gray-700 mb-2", y.textContent = "Custom Color", t.appendChild(y);
const b = document.createElement("div");
b.className = "flex items-center gap-2", t.appendChild(b);
const m = document.createElement("input");
m.type = "color", m.className = "custom-color", m.value = (e.value || "#000000").toString(), b.appendChild(m);
const u = document.createElement("input");
u.type = "text", u.className = "color-input", u.placeholder = "#000000", u.pattern = "^#[0-9A-Fa-f]{6}$", u.value = (e.value || "#000000").toString(), b.appendChild(u), m.addEventListener("input", (l) => {
u.value = l.target.value.toUpperCase();
}), u.addEventListener("input", (l) => {
const r = l.target.value.toUpperCase();
/^#[0-9A-Fa-f]{6}$/.test(r) && (m.value = r);
});
break;
case "time":
t = document.createElement("input"), t.setAttribute("type", "time"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("value", e.value || "");
break;
case "datetime-local":
t = document.createElement("input"), t.setAttribute("type", "datetime-local"), t.className = `popup-item-input ${e.className || ""}`, t.setAttribute("value", e.value || "");
break;
case "button":
t = document.createElement("button"), t.className = `popup-button ${e.buttonVariant || "primary"} ${e.className || ""}`, e.icon && (t.innerHTML = e.icon), t.insertAdjacentHTML("beforeend", e.text || "Button"), e.onChange && t.addEventListener("click", () => e.onChange(e.value));
break;
case "custom":
if (e.content)
t = typeof e.content == "function" ? e.content() : e.content;
else
throw new Error("Custom type requires a content property.");
break;
case "divider":
t = document.createElement("div"), t.className = `popup-divider ${e.className || ""}`, t.style.borderTop = "1px solid #e5e7eb", t.style.margin = "8px 0";
break;
default:
throw new Error(`Unsupported item type: ${e.type}`);
}
e.onChange && e.type !== "button" && e.type !== "progress" && e.type !== "loader" && (t.addEventListener("change", (s) => {
let p;
e.type === "checkbox" ? p = s.target.checked : e.type === "range" || e.type === "number" ? p = parseFloat(s.target.value) : p = s.target.value, e.onChange(p, s);
}), t.addEventListener("input", (s) => {
let p;
e.type === "checkbox" ? p = s.target.checked : e.type === "range" || e.type === "number" ? p = parseFloat(s.target.value) : p = s.target.value, e.onChange(p, s);
})), t.id = e.id, o.appendChild(t), n.appendChild(o);
}), n;
}
visibleShow(a) {
const n = this.popup.querySelector(`#${a}`);
n && (n.style.display = "block");
}
visibleHide(a) {
const n = this.popup.querySelector(`#${a}`);
n && (n.style.display = "none");
}
/**
* Получает значение элемента попапа по его ID.
* @param id - Уникальный идентификатор элемента.
* @returns Значение элемента или null, если элемент не найден.
*/
getValue(a) {
const n = this.popup.querySelector(`#${a}`);
if (!n)
return console.warn(`Element with id "${a}" not found.`), null;
if (n.classList.contains("color-picker-container")) {
const e = n.querySelector(".custom-color");
return e ? e.value : null;
}
switch (n.tagName.toLowerCase()) {
case "input":
const e = n;
return e.type === "checkbox" ? e.checked : e.type === "range" || e.type === "number" ? parseFloat(e.value) : e.value;
case "textarea":
return n.value;
case "select":
return n.value;
default:
return console.warn(`Unsupported element type for id "${a}".`), null;
}
}
setValue(a, n) {
const e = this.popup.querySelector(`#${a}`);
if (!e) {
console.warn(`Element with id "${a}" not found.`);
return;
}
if (e.classList.contains("color-picker-container")) {
const o = e.querySelector(".custom-color"), t = e.querySelector(".color-input");
if (o && t) {
const c = n.toString().toUpperCase();
/^#[0-9A-Fa-f]{6}$/.test(c) ? (o.value = c, t.value = c) : console.warn(
`Invalid color value for id "${a}". Expected a hex color (e.g., "#FF0000").`
);
}
return;
}
switch (e.tagName.toLowerCase()) {
case "input":
const o = e;
o.type === "checkbox" ? o.checked = !!n : o.type === "range" || o.type === "number" ? o.value = String(n) : o.value = n;
break;
case "textarea":
e.value = n;
break;
case "select":
e.value = n;
break;
default:
console.warn(`Unsupported element type for id "${a}".`);
}
}
setFocus(a) {
const n = this.popup.querySelector(`#${a}`);
if (!n) {
console.warn(`Element with id "${a}" not found.`);
return;
}
n.focus ? n.focus() : console.warn(`Element with id "${a}" does not support focus.`);
}
createOverlay() {
const a = document.createElement("div");
return a.className = "popup-overlay", a;
}
rerender(a) {
this.content.innerHTML = "";
const n = this.createContentFromItems(a);
this.content.appendChild(n);
}
updateFooterButtonCallback(a, n) {
this.footer ? this.footer.updateButtonCallback(a, n) : console.warn("Footer is not initialized. Cannot update button callback.");
}
setItems(a) {
this.setContent(this.createContentFromItems(a));
}
setContent(a) {
typeof a == "string" ? this.content.innerHTML = a : (this.content.innerHTML = "", this.content.appendChild(a));
}
show(a, n) {
if (this.popup.style.display = "flex", this.overlay.style.display = "block", this.isVisible = !0, document.body.classList.add("popup-open"), typeof a == "number" && typeof n == "number") {
this.popup.style.position = "fixed", this.popup.style.left = `${a}px`, this.popup.style.top = `${n}px`;
const e = this.popup.getBoundingClientRect();
e.right > window.innerWidth && (this.popup.style.left = `${a - e.width}px`), e.bottom > window.innerHeight && (this.popup.style.top = `${n - e.height}px`);
} else
this.popup.style.position = "fixed", this.popup.style.left = "50%", this.popup.style.top = "50%", this.popup.style.transform = "translate(-50%, -50%)";
}
hide() {
this.popup.style.display = "none", this.overlay.style.display = "none", this.isVisible = !1, document.body.classList.remove("popup-open");
}
isOpen() {
return this.isVisible;
}
getElement() {
return this.popup;
}
destroy() {
this.popup.remove();
}
}
export {
S as PopupManager
};