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
728 lines (727 loc) • 30.4 kB
JavaScript
/*! on-codemerge v1.3.1 @author Pavel Kuzmin @license MIT @homepage https://s00d.github.io/on-codemerge/ @repository git+https://github.com/s00d/on-codemerge.git Copyright (c) 2026 Pavel Kuzmin - Built on 2026-07-02T13:39:17.947Z */
var A = Object.defineProperty;
var B = (N, t, e) => t in N ? A(N, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : N[t] = e;
var U = (N, t, e) => B(N, typeof t != "symbol" ? t + "" : t, e);
import { createContainer as n, createButton as I, createLabel as x, createSelectField as R, createInputField as y, createCheckbox as F } from "../../../utils/helpers.mjs";
class V {
constructor(t, e, o, s, d, a, p) {
U(this, "editor");
U(this, "formManager");
U(this, "onUpdate");
U(this, "onRemove");
U(this, "onClone");
U(this, "onTypeChange");
U(this, "onOptionsChange");
this.onUpdate = t, this.onRemove = e, this.onClone = o, this.editor = s, this.formManager = d, this.onTypeChange = a, this.onOptionsChange = p;
}
/**
* Create field editor
*/
createFieldEditor(t) {
const e = n(
"field-editor-container mb-4 p-4 border border-gray-200 rounded bg-gray-50"
), o = n("field-header flex justify-between items-center mb-3"), s = n("field-title text-lg font-semibold");
s.textContent = t.label || this.editor.t("Untitled Field");
const d = n("field-actions flex gap-2"), a = I(
this.editor.t("Copy"),
() => this.onClone(t.id),
"secondary"
), p = I(
this.editor.t("Remove"),
() => this.onRemove(t.id),
"danger"
);
d.appendChild(a), d.appendChild(p), o.appendChild(s), o.appendChild(d), e.appendChild(o);
const c = this.createMainSettings(t);
e.appendChild(c);
const r = this.createOptionsSettings(t);
e.appendChild(r);
const l = this.createValidationSettings(t);
return e.appendChild(l), e;
}
/**
* Create main field settings
*/
createMainSettings(t) {
var i;
const e = n("main-settings mb-4"), o = n("section-title text-md font-medium mb-2");
o.textContent = this.editor.t("Main Settings"), e.appendChild(o);
const s = n("setting-group mb-3"), d = x(this.editor.t("Field Type:")), a = R(this.getFieldTypeOptions(), t.type, (h) => {
const m = h;
this.onUpdate(t.id, { type: m }), this.onTypeChange && this.onTypeChange(t.id, m);
});
s.appendChild(d), s.appendChild(a), e.appendChild(s);
const p = n("setting-group mb-3"), c = x(this.editor.t("Field Label:")), r = y(
"text",
this.editor.t("Enter field label"),
t.label,
(h) => this.onUpdate(t.id, { label: h })
);
p.appendChild(c), p.appendChild(r), e.appendChild(p);
const l = n("setting-group mb-3"), u = x(this.editor.t("Placeholder:")), b = y(
"text",
this.editor.t("Enter placeholder text"),
((i = t.options) == null ? void 0 : i.placeholder) || "",
(h) => this.onUpdate(t.id, {
options: { ...t.options, placeholder: h }
})
);
return l.appendChild(u), l.appendChild(b), e.appendChild(l), e;
}
/**
* Create field options settings
*/
createOptionsSettings(t) {
var g, S, L, O, C, E;
const e = n("options-settings mb-4"), o = n("section-title text-md font-medium mb-2");
o.textContent = this.editor.t("Additional Options"), e.appendChild(o);
const s = n("setting-group mb-3"), d = x(this.editor.t("Field Name (name):")), a = y(
"text",
this.editor.t("Enter field name"),
((g = t.options) == null ? void 0 : g.name) || "",
(w) => this.onUpdate(t.id, {
options: { ...t.options, name: w }
})
);
s.appendChild(d), s.appendChild(a), e.appendChild(s);
const p = n("setting-group mb-3"), c = x(this.editor.t("Field ID:")), r = y(
"text",
this.editor.t("Enter field ID"),
((S = t.options) == null ? void 0 : S.id) || "",
(w) => this.onUpdate(t.id, {
options: { ...t.options, id: w }
})
);
p.appendChild(c), p.appendChild(r), e.appendChild(p);
const l = n("setting-group mb-3"), u = x(this.editor.t("CSS Class:")), b = y(
"text",
this.editor.t("Enter CSS class"),
((L = t.options) == null ? void 0 : L.className) || "",
(w) => this.onUpdate(t.id, {
options: { ...t.options, className: w }
})
);
l.appendChild(u), l.appendChild(b), e.appendChild(l);
const i = n("checkboxes-group flex flex-wrap gap-4 mb-3"), h = F(
this.editor.t("Read Only"),
((O = t.options) == null ? void 0 : O.readonly) || !1,
(w) => this.onUpdate(t.id, {
options: { ...t.options, readonly: w }
})
), m = F(
this.editor.t("Disabled"),
((C = t.options) == null ? void 0 : C.disabled) || !1,
(w) => this.onUpdate(t.id, {
options: { ...t.options, disabled: w }
})
), v = F(
this.editor.t("Multiple Selection"),
((E = t.options) == null ? void 0 : E.multiple) || !1,
(w) => this.onUpdate(t.id, {
options: { ...t.options, multiple: w }
})
);
i.appendChild(h), i.appendChild(m), i.appendChild(v), e.appendChild(i);
const k = this.createTypeSpecificOptions(t);
if (k && e.appendChild(k), t.type === "select" || t.type === "radio") {
const w = this.createOptionsList(t);
e.appendChild(w);
}
return e;
}
/**
* Create type-specific options
*/
createTypeSpecificOptions(t) {
const e = n("type-specific-options mb-3"), o = n("section-title text-sm font-medium mb-2");
switch (o.textContent = this.editor.t("Type-Specific Options"), e.appendChild(o), t.type) {
case "checkbox":
this.addCheckboxOptions(e, t);
break;
case "number":
case "range":
this.addNumberOptions(e, t);
break;
case "textarea":
this.addTextareaOptions(e, t);
break;
case "file":
this.addFileOptions(e, t);
break;
case "date":
case "time":
case "datetime-local":
case "month":
case "week":
this.addDateOptions(e, t);
break;
case "text":
case "email":
case "password":
case "tel":
case "url":
this.addTextOptions(e, t);
break;
case "color":
this.addColorOptions(e, t);
break;
case "image":
this.addImageOptions(e, t);
break;
default:
return null;
}
return e;
}
/**
* Add checkbox-specific options
*/
addCheckboxOptions(t, e) {
var l, u;
const o = n("setting-group mb-2"), s = x(this.editor.t("Checkbox Text:")), d = ((l = e.options) == null ? void 0 : l.value) || e.label || "", a = y(
"text",
this.editor.t("Enter text to display next to checkbox"),
d,
(b) => {
const i = this.formManager.getField(e.id), h = (i == null ? void 0 : i.options) || {};
this.onUpdate(e.id, {
options: { ...h, value: b }
});
}
);
o.appendChild(s), o.appendChild(a), t.appendChild(o);
const p = n("setting-group mb-2"), c = ((u = e.options) == null ? void 0 : u.checked) || !1, r = F(
this.editor.t("Checked by Default"),
c,
(b) => {
const i = this.formManager.getField(e.id), h = (i == null ? void 0 : i.options) || {};
this.onUpdate(e.id, {
options: { ...h, checked: b }
});
}
);
p.appendChild(r), t.appendChild(p);
}
/**
* Add number-specific options
*/
addNumberOptions(t, e) {
var m, v, k;
const o = n("setting-group mb-2"), s = x(this.editor.t("Minimum Value:")), d = ((m = e.options) == null ? void 0 : m.min) !== void 0 ? String(e.options.min) : "", a = y(
"number",
this.editor.t("Enter minimum value"),
d,
(g) => this.onUpdate(e.id, {
options: { ...e.options, min: g ? parseFloat(g) : void 0 }
})
);
o.appendChild(s), o.appendChild(a), t.appendChild(o);
const p = n("setting-group mb-2"), c = x(this.editor.t("Maximum Value:")), r = ((v = e.options) == null ? void 0 : v.max) !== void 0 ? String(e.options.max) : "", l = y(
"number",
this.editor.t("Enter maximum value"),
r,
(g) => this.onUpdate(e.id, {
options: { ...e.options, max: g ? parseFloat(g) : void 0 }
})
);
p.appendChild(c), p.appendChild(l), t.appendChild(p);
const u = n("setting-group mb-2"), b = x(this.editor.t("Step Value:")), i = ((k = e.options) == null ? void 0 : k.step) !== void 0 ? String(e.options.step) : "", h = y(
"number",
this.editor.t("Enter step value"),
i,
(g) => this.onUpdate(e.id, {
options: { ...e.options, step: g ? parseFloat(g) : void 0 }
})
);
u.appendChild(b), u.appendChild(h), t.appendChild(u);
}
/**
* Add textarea-specific options
*/
addTextareaOptions(t, e) {
var u, b;
const o = n("setting-group mb-2"), s = x(this.editor.t("Rows:")), d = ((u = e.options) == null ? void 0 : u.rows) !== void 0 ? String(e.options.rows) : "4", a = y(
"number",
this.editor.t("Enter number of rows"),
d,
(i) => this.onUpdate(e.id, {
options: { ...e.options, rows: i ? parseInt(i) : 4 }
})
);
o.appendChild(s), o.appendChild(a), t.appendChild(o);
const p = n("setting-group mb-2"), c = x(this.editor.t("Columns:")), r = ((b = e.options) == null ? void 0 : b.cols) !== void 0 ? String(e.options.cols) : "50", l = y(
"number",
this.editor.t("Enter number of columns"),
r,
(i) => this.onUpdate(e.id, {
options: { ...e.options, cols: i ? parseInt(i) : 50 }
})
);
p.appendChild(c), p.appendChild(l), t.appendChild(p);
}
/**
* Add file-specific options
*/
addFileOptions(t, e) {
var c, r;
const o = n("setting-group mb-2"), s = x(this.editor.t("Accepted File Types:")), d = y(
"text",
this.editor.t("e.g., .pdf,.doc,.jpg"),
((c = e.options) == null ? void 0 : c.accept) || "",
(l) => this.onUpdate(e.id, {
options: { ...e.options, accept: l }
})
);
o.appendChild(s), o.appendChild(d), t.appendChild(o);
const a = n("setting-group mb-2"), p = F(
this.editor.t("Allow Multiple Files"),
((r = e.options) == null ? void 0 : r.multiple) || !1,
(l) => this.onUpdate(e.id, {
options: { ...e.options, multiple: l }
})
);
a.appendChild(p), t.appendChild(a);
}
/**
* Add date-specific options
*/
addDateOptions(t, e) {
var r, l, u, b;
const o = n("setting-group mb-2"), s = x(this.editor.t("Minimum Date:")), d = y(
"date",
this.editor.t("Select minimum date"),
((l = (r = e.options) == null ? void 0 : r.min) == null ? void 0 : l.toString()) || "",
(i) => this.onUpdate(e.id, {
options: { ...e.options, min: i }
})
);
o.appendChild(s), o.appendChild(d), t.appendChild(o);
const a = n("setting-group mb-2"), p = x(this.editor.t("Maximum Date:")), c = y(
"date",
this.editor.t("Select maximum date"),
((b = (u = e.options) == null ? void 0 : u.max) == null ? void 0 : b.toString()) || "",
(i) => this.onUpdate(e.id, {
options: { ...e.options, max: i }
})
);
a.appendChild(p), a.appendChild(c), t.appendChild(a);
}
/**
* Add text-specific options
*/
addTextOptions(t, e) {
var m, v, k, g, S, L, O;
const o = n("setting-group mb-2"), s = x(this.editor.t("Size:")), d = y(
"number",
this.editor.t("Enter field size"),
((v = (m = e.options) == null ? void 0 : m.size) == null ? void 0 : v.toString()) || "",
(C) => this.onUpdate(e.id, {
options: { ...e.options, size: parseInt(C) || void 0 }
})
);
o.appendChild(s), o.appendChild(d), t.appendChild(o);
const a = n("setting-group mb-2"), p = x(this.editor.t("Maximum Length:")), c = y(
"number",
this.editor.t("Enter maximum length"),
((g = (k = e.options) == null ? void 0 : k.maxlength) == null ? void 0 : g.toString()) || "",
(C) => this.onUpdate(e.id, {
options: { ...e.options, maxlength: parseInt(C) || void 0 }
})
);
a.appendChild(p), a.appendChild(c), t.appendChild(a);
const r = n("setting-group mb-2"), l = x(this.editor.t("Minimum Length:")), u = y(
"number",
this.editor.t("Enter minimum length"),
((L = (S = e.options) == null ? void 0 : S.minlength) == null ? void 0 : L.toString()) || "",
(C) => this.onUpdate(e.id, {
options: { ...e.options, minlength: parseInt(C) || void 0 }
})
);
r.appendChild(l), r.appendChild(u), t.appendChild(r);
const b = n("setting-group mb-2"), i = x(this.editor.t("Autocomplete:")), h = R(
[
{ value: "", label: this.editor.t("Default") },
{ value: "on", label: this.editor.t("On") },
{ value: "off", label: this.editor.t("Off") },
{ value: "name", label: this.editor.t("Name") },
{ value: "email", label: this.editor.t("Email") },
{ value: "tel", label: this.editor.t("Phone") },
{ value: "url", label: this.editor.t("URL") },
{ value: "current-password", label: this.editor.t("Current Password") },
{ value: "new-password", label: this.editor.t("New Password") }
],
((O = e.options) == null ? void 0 : O.autocomplete) || "",
(C) => this.onUpdate(e.id, {
options: { ...e.options, autocomplete: C }
})
);
b.appendChild(i), b.appendChild(h), t.appendChild(b);
}
/**
* Add color-specific options
*/
addColorOptions(t, e) {
var a;
const o = n("setting-group mb-2"), s = x(this.editor.t("Default Color:")), d = y(
"color",
this.editor.t("Select default color"),
((a = e.options) == null ? void 0 : a.value) || "#000000",
(p) => this.onUpdate(e.id, {
options: { ...e.options, value: p }
})
);
o.appendChild(s), o.appendChild(d), t.appendChild(o);
}
/**
* Add image-specific options
*/
addImageOptions(t, e) {
var r, l;
const o = n("setting-group mb-2"), s = x(this.editor.t("Image Source:")), d = y(
"text",
this.editor.t("Enter image URL"),
((r = e.options) == null ? void 0 : r.src) || "",
(u) => this.onUpdate(e.id, {
options: { ...e.options, src: u }
})
);
o.appendChild(s), o.appendChild(d), t.appendChild(o);
const a = n("setting-group mb-2"), p = x(this.editor.t("Alt Text:")), c = y(
"text",
this.editor.t("Enter alt text"),
((l = e.options) == null ? void 0 : l.alt) || "",
(u) => this.onUpdate(e.id, {
options: { ...e.options, alt: u }
})
);
a.appendChild(p), a.appendChild(c), t.appendChild(a);
}
/**
* Create options list for select/radio fields
*/
createOptionsList(t) {
var b;
const e = n(
"options-list mb-3 p-3 bg-gray-50 rounded border border-gray-200"
), o = n("section-title text-sm font-medium mb-2 text-gray-700");
t.type === "checkbox" ? o.textContent = this.editor.t("Checkbox Options") : t.type === "radio" ? o.textContent = this.editor.t("Radio Options") : o.textContent = this.editor.t("Options"), e.appendChild(o);
const s = ((b = t.options) == null ? void 0 : b.options) || [], d = n("text-xs text-gray-500 mb-2");
t.type === "checkbox" ? d.textContent = this.editor.t("Add, edit, or reorder checkbox text options") : t.type === "radio" ? d.textContent = this.editor.t("Add, edit, or reorder radio button text options") : d.textContent = this.editor.t("Add, edit, or reorder options using buttons"), e.appendChild(d);
const a = n("options-container space-y-1");
if (a.setAttribute("data-field-id", t.id), s.length === 0) {
const i = n("empty-state text-center py-3 text-gray-400 text-xs");
i.innerHTML = `📝 ${this.editor.t("No options")}`, a.appendChild(i);
} else
s.forEach((i, h) => {
const m = n(
"option-item bg-white border border-gray-200 rounded p-2 hover:border-gray-300 transition-colors"
), v = n("flex items-center gap-2"), k = n(
"option-number text-xs font-medium text-gray-700 bg-blue-100 text-blue-800 px-2 py-1 rounded min-w-[24px] text-center"
);
k.textContent = `${h + 1}`;
const g = n("text-xs text-gray-500 min-w-[40px]");
t.type === "checkbox" || t.type === "radio" ? g.textContent = this.editor.t("Text:") : g.textContent = this.editor.t("Value:");
const S = y(
"text",
t.type === "checkbox" || t.type === "radio" ? this.editor.t("Enter checkbox text") : this.editor.t("Enter option value"),
i,
(C) => {
const E = [...s];
E[h] = C, this.onUpdate(t.id, {
options: { ...t.options, options: E }
}), this.onOptionsChange && this.onOptionsChange(t.id);
}
);
if (S.className = "flex-1 px-3 py-1.5 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white", S.placeholder = t.type === "checkbox" || t.type === "radio" ? this.editor.t("Checkbox text") : this.editor.t("Option value"), t.type === "select") {
const C = y(
"text",
this.editor.t("Display text (optional)"),
i,
// Пока используем то же значение
(T) => {
const M = [...s];
M[h] = T, this.onUpdate(t.id, {
options: { ...t.options, options: M }
}), this.onOptionsChange && this.onOptionsChange(t.id);
}
);
C.className = "flex-1 px-3 py-1.5 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white", C.placeholder = this.editor.t("Display text");
const E = n("flex items-center gap-2 mt-1"), w = n("text-xs text-gray-500 min-w-[60px]");
w.textContent = this.editor.t("Display:"), E.appendChild(w), E.appendChild(C), m.appendChild(E);
}
const L = n("flex gap-1");
if (h > 0) {
const C = I(
"↑",
() => this.moveOption(t.id, h, h - 1),
"secondary"
);
C.className = "px-1.5 py-0.5 text-xs bg-gray-100 hover:bg-gray-200 text-gray-600 rounded transition-colors", C.title = this.editor.t("Move up"), L.appendChild(C);
}
if (h < s.length - 1) {
const C = I(
"↓",
() => this.moveOption(t.id, h, h + 1),
"secondary"
);
C.className = "px-1.5 py-0.5 text-xs bg-gray-100 hover:bg-gray-200 text-gray-600 rounded transition-colors", C.title = this.editor.t("Move down"), L.appendChild(C);
}
const O = I(
"×",
() => {
var E, w;
const C = s.filter((T, M) => M !== h);
this.onUpdate(t.id, {
options: { ...t.options, options: C }
}), (w = (E = this.editor) == null ? void 0 : E.showInfoNotification) == null || w.call(
E,
t.type === "checkbox" ? this.editor.t("Checkbox removed") : t.type === "radio" ? this.editor.t("Radio option removed") : this.editor.t("Option removed")
), this.onOptionsChange && this.onOptionsChange(t.id);
},
"danger"
);
O.className = "px-1.5 py-0.5 text-xs bg-red-100 hover:bg-red-200 text-red-600 rounded transition-colors", O.title = this.editor.t("Remove option"), L.appendChild(O), v.appendChild(k), v.appendChild(g), v.appendChild(S), v.appendChild(L), m.appendChild(v), a.appendChild(m);
});
e.appendChild(a);
const p = n("action-buttons mt-2 space-y-1"), c = I(
t.type === "checkbox" ? `➕ ${this.editor.t("Add Checkbox")}` : t.type === "radio" ? `➕ ${this.editor.t("Add Radio")}` : `➕ ${this.editor.t("Add Option")}`,
() => {
var m, v;
const i = t.type === "checkbox" ? this.editor.t("New Checkbox") : t.type === "radio" ? this.editor.t("New Radio") : this.editor.t("New Option"), h = [...s, i];
this.onUpdate(t.id, {
options: { ...t.options, options: h }
}), (v = (m = this.editor) == null ? void 0 : m.showSuccessNotification) == null || v.call(
m,
t.type === "checkbox" ? this.editor.t("Checkbox added successfully") : t.type === "radio" ? this.editor.t("Radio option added successfully") : this.editor.t("Option added successfully")
), this.onOptionsChange && this.onOptionsChange(t.id);
},
"primary"
);
c.className = "w-full py-1.5 px-2 bg-blue-600 hover:bg-blue-700 text-white text-xs font-medium rounded transition-colors";
const r = n("bulk-actions flex gap-1"), l = I(
`🗑️ ${this.editor.t("Clear")}`,
() => {
var i, h;
this.onUpdate(t.id, {
options: { ...t.options, options: [] }
}), (h = (i = this.editor) == null ? void 0 : i.showInfoNotification) == null || h.call(i, this.editor.t("All options cleared")), this.onOptionsChange && this.onOptionsChange(t.id);
},
"danger"
);
l.className = "flex-1 py-1 px-2 bg-red-600 hover:bg-red-700 text-white text-xs rounded";
const u = I(
`📋 ${this.editor.t("Presets")}`,
() => this.showPresetOptions(t),
"secondary"
);
return u.className = "flex-1 py-1 px-2 bg-gray-600 hover:bg-gray-700 text-white text-xs rounded", r.appendChild(l), r.appendChild(u), p.appendChild(c), p.appendChild(r), e.appendChild(p), e;
}
/**
* Move option to new position
*/
moveOption(t, e, o) {
var p, c, r;
const s = this.getFieldById(t);
if (!s || !((p = s.options) != null && p.options)) return;
const d = [...s.options.options], [a] = d.splice(e, 1);
d.splice(o, 0, a), this.onUpdate(t, {
options: { ...s.options, options: d }
}), (r = (c = this.editor) == null ? void 0 : c.showInfoNotification) == null || r.call(
c,
s.type === "checkbox" ? this.editor.t("Checkbox moved") : s.type === "radio" ? this.editor.t("Radio option moved") : this.editor.t("Option moved")
), this.onOptionsChange && this.onOptionsChange(t);
}
/**
* Show preset options dialog
*/
showPresetOptions(t) {
const e = {
countries: [
"United States",
"Canada",
"United Kingdom",
"Germany",
"France",
"Japan",
"Australia",
"Brazil",
"India",
"China"
],
months: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
colors: [
"Red",
"Blue",
"Green",
"Yellow",
"Orange",
"Purple",
"Black",
"White",
"Gray",
"Pink"
],
sizes: ["XS", "S", "M", "L", "XL", "XXL"],
"age-groups": ["18-25", "26-35", "36-45", "46-55", "56-65", "65+"],
genders: [this.editor.t("Male"), this.editor.t("Female"), this.editor.t("Other")],
"yes-no": [this.editor.t("Yes"), this.editor.t("No")],
custom: []
}, o = document.createElement("div");
o.className = "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4";
const s = document.createElement("div");
s.className = "bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[80vh] overflow-hidden";
const d = document.createElement("div");
d.className = "bg-gradient-to-r from-blue-600 to-purple-600 text-white p-6";
const a = document.createElement("h3");
a.className = "text-2xl font-bold mb-2", a.textContent = this.editor.t("Select Preset Options");
const p = document.createElement("p");
p.className = "text-blue-100 text-sm", p.textContent = this.editor.t(
"Choose from predefined option sets or create custom options"
), d.appendChild(a), d.appendChild(p), s.appendChild(d);
const c = document.createElement("div");
c.className = "p-6 max-h-[60vh] overflow-y-auto";
const r = document.createElement("div");
r.className = "grid grid-cols-1 md:grid-cols-2 gap-4", Object.entries(e).forEach(([i, h]) => {
if (i === "custom") return;
const m = document.createElement("div");
m.className = "preset-card border border-gray-200 rounded-lg p-4 hover:border-blue-300 hover:shadow-md transition-all duration-200 cursor-pointer bg-white";
const v = document.createElement("div");
v.className = "text-2xl mb-3";
const k = {
countries: "🌍",
months: "📅",
days: "📆",
colors: "🎨",
sizes: "👕",
"age-groups": "👥",
genders: "👤",
"yes-no": "✅"
};
v.textContent = k[i] || "📋";
const g = document.createElement("h4");
g.className = "font-semibold text-gray-800 mb-2", g.textContent = this.editor.t(
i.charAt(0).toUpperCase() + i.slice(1).replace("-", " ")
);
const S = document.createElement("p");
S.className = "text-sm text-gray-600 mb-3", S.textContent = `${h.length} ${this.editor.t("options")}`;
const L = document.createElement("div");
L.className = "text-xs text-gray-500 bg-gray-50 p-2 rounded border", L.textContent = h.slice(0, 3).join(", ") + (h.length > 3 ? "..." : ""), m.appendChild(v), m.appendChild(g), m.appendChild(S), m.appendChild(L), m.addEventListener("click", () => {
var O, C;
this.onUpdate(t.id, {
options: { ...t.options, options: h }
}), (C = (O = this.editor) == null ? void 0 : O.showSuccessNotification) == null || C.call(
O,
`${this.editor.t("Applied")} ${h.length} ${this.editor.t("options")}`
), this.onOptionsChange && this.onOptionsChange(t.id), o.remove();
}), m.addEventListener("mouseenter", () => {
m.style.transform = "translateY(-2px)";
}), m.addEventListener("mouseleave", () => {
m.style.transform = "translateY(0)";
}), r.appendChild(m);
}), c.appendChild(r), s.appendChild(c);
const l = document.createElement("div");
l.className = "bg-gray-50 px-6 py-4 border-t border-gray-200 flex justify-end";
const u = document.createElement("button");
u.className = "px-6 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100 transition-colors duration-200 font-medium", u.textContent = this.editor.t("Cancel"), u.addEventListener("click", () => o.remove()), l.appendChild(u), s.appendChild(l), o.appendChild(s), o.addEventListener("click", (i) => {
i.target === o && o.remove();
});
const b = (i) => {
i.key === "Escape" && (o.remove(), this.editor.getDOMContext().removeEventListener("keydown", b));
};
this.editor.getDOMContext().addEventListener("keydown", b), document.body.appendChild(o);
}
/**
* Get field by ID (helper method)
*/
getFieldById(t) {
return this.formManager.getField(t) || null;
}
/**
* Get field type options
*/
getFieldTypeOptions() {
return [
{ value: "text", label: this.editor.t("Text Input") },
{ value: "textarea", label: this.editor.t("Text Area") },
{ value: "select", label: this.editor.t("Dropdown") },
{ value: "checkbox", label: this.editor.t("Checkbox") },
{ value: "radio", label: this.editor.t("Radio Button") },
{ value: "button", label: this.editor.t("Button") },
{ value: "file", label: this.editor.t("File Upload") },
{ value: "date", label: this.editor.t("Date") },
{ value: "time", label: this.editor.t("Time") },
{ value: "range", label: this.editor.t("Range") },
{ value: "email", label: this.editor.t("Email") },
{ value: "password", label: this.editor.t("Password") },
{ value: "number", label: this.editor.t("Number") },
{ value: "tel", label: this.editor.t("Phone") },
{ value: "url", label: this.editor.t("URL") },
{ value: "color", label: this.editor.t("Color") },
{ value: "datetime-local", label: this.editor.t("Date & Time") },
{ value: "month", label: this.editor.t("Month") },
{ value: "week", label: this.editor.t("Week") },
{ value: "hidden", label: this.editor.t("Hidden Field") },
{ value: "image", label: this.editor.t("Image Button") }
];
}
/**
* Create validation settings
*/
createValidationSettings(t) {
var m, v, k, g, S, L;
const e = n("validation-settings mb-4"), o = n("section-title text-md font-medium mb-2");
o.textContent = this.editor.t("Validation"), e.appendChild(o);
const s = n("setting-group mb-3"), d = F(
this.editor.t("Required Field"),
((m = t.validation) == null ? void 0 : m.required) || !1,
(O) => this.onUpdate(t.id, {
validation: { ...t.validation, required: O }
})
);
s.appendChild(d), e.appendChild(s);
const a = n("setting-group mb-3"), p = x(this.editor.t("Regular Expression:")), c = y(
"text",
this.editor.t("Enter regular expression"),
((v = t.validation) == null ? void 0 : v.pattern) || "",
(O) => this.onUpdate(t.id, {
validation: { ...t.validation, pattern: O }
})
);
a.appendChild(p), a.appendChild(c), e.appendChild(a);
const r = n("setting-group mb-3"), l = x(this.editor.t("Minimum Length:")), u = y(
"number",
this.editor.t("Enter minimum length"),
((g = (k = t.validation) == null ? void 0 : k.minLength) == null ? void 0 : g.toString()) || "",
(O) => this.onUpdate(t.id, {
validation: { ...t.validation, minLength: parseInt(O) || void 0 }
})
);
r.appendChild(l), r.appendChild(u), e.appendChild(r);
const b = n("setting-group mb-3"), i = x(this.editor.t("Maximum Length:")), h = y(
"number",
this.editor.t("Enter maximum length"),
((L = (S = t.validation) == null ? void 0 : S.maxLength) == null ? void 0 : L.toString()) || "",
(O) => this.onUpdate(t.id, {
validation: { ...t.validation, maxLength: parseInt(O) || void 0 }
})
);
return b.appendChild(i), b.appendChild(h), e.appendChild(b), e;
}
}
export {
V as FieldEditor
};