domma-cms 0.41.1 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- import{apiRequest as B}from"/admin/js/api.js";import{makeIconInput as ge}from"/admin/js/lib/shortcode-modal.js";import{enhancePickerFields as Z}from"/public/js/forms.js";const ee=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"chooser",label:"Chooser (visual options)"},{value:"icon",label:"Icon (icon picker)"},{value:"image",label:"Image (media library)"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"password",label:"Password"},{value:"file",label:"File upload"},{value:"hidden",label:"Hidden field"}],W=new Set(["select","radio","checkbox-group","chooser"]);let v=[],q=null,j=null,P=null,G={};function w(e,n,s=14){e.textContent="";const t=document.createElement("span");return t.setAttribute("data-icon",n),t.setAttribute("data-icon-size",String(s)),t.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",e.appendChild(t),window.I?.scan?.(e),e}function M(e,n,s,t=14){return w(e,n,t),e.appendChild(document.createTextNode(" "+s)),e}function Q(e){const n=document.createElement("span");return n.setAttribute("data-icon","help-circle"),n.setAttribute("data-icon-size","12"),n.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;margin-left:.3rem;opacity:.55;cursor:help;",n.title=e,window.I?.scan?.(n),requestAnimationFrame(()=>{try{n.parentNode&&typeof E<"u"&&E.tooltip&&(n.removeAttribute("title"),E.tooltip(n,{content:e,position:"top"}))}catch{}}),n}let D=null,te=null;function Y(){clearTimeout(te),te=setTimeout(()=>{D&&D()},350)}function ne(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")}function le(e){return ee.find(n=>n.value===e)?.label||e}function oe(e){return e?!!(e.visibility?.conditions?.length||e.requirement?.conditions?.length||e.validation?.length||e.cascade?.sourceField):!1}function ye(e){const n={...v[e]};if(n.type==="spacer")return n;if(n.type==="page-break"){const h=document.getElementById(`fb-pb-label-${e}`),m=document.getElementById(`fb-pb-desc-${e}`);return h&&(n.label=h.value.trim()||n.label),m&&(n.description=m.value.trim()),n}const s=document.getElementById(`fb-label-${e}`),t=document.getElementById(`fb-name-${e}`),o=document.getElementById(`fb-type-${e}`),l=document.getElementById(`fb-required-${e}`),i=document.getElementById(`fb-placeholder-${e}`),d=document.getElementById(`fb-helper-${e}`),r=document.getElementById(`fb-tooltip-${e}`);if(s&&(n.label=s.value.trim()||n.label),t&&(n.name=t.value.trim()||n.name),o&&(n.type=o.value||n.type),l&&(n.required=l.checked),i&&(n.placeholder=i.value.trim()),d&&(n.helper=d.value.trim()),r&&(n.tooltip=r.value.trim()),n.type==="chooser"){const h=document.getElementById(`fb-chooser-variant-${e}`)?.value;h&&(n.variant=h);const m=document.getElementById(`fb-chooser-multiple-${e}`);m&&(n.multiple=m.checked);const y=document.getElementById(`fb-chooser-density-${e}`)?.value;y&&(n.density=y);const x=document.getElementById(`fb-chooser-columns-${e}`)?.value;x!==""&&x!==void 0&&(n.columns=parseInt(x,10)||3);const C=document.getElementById(`fb-chooser-accent-${e}`)?.value.trim();C?n.accent=C:delete n.accent;const T=document.getElementById(`fb-chooser-accent-style-${e}`)?.value;T?n.accentStyle=T:delete n.accentStyle;const z=document.getElementById(`fb-chooser-glow-${e}`);z&&(n.glow=z.checked);const A=document.getElementById(`fb-chooser-glow-colour-${e}`)?.value.trim();A?n.glowColour=A:delete n.glowColour;const N=document.getElementById(`fb-chooser-shadow-${e}`)?.value;N&&N!=="none"?n.shadow=N:delete n.shadow;const O=document.getElementById(`fb-chooser-shadow-colour-${e}`)?.value.trim();O?n.shadowColour=O:delete n.shadowColour,J(e),v[e]&&Array.isArray(v[e].options)&&(n.options=v[e].options)}else if(W.has(n.type)){const h=document.getElementById(`fb-options-${e}`);h&&(n.options=h.value.split(`
2
- `).filter(m=>m.trim()).map(m=>{const[y,...x]=m.split(":");return{value:y.trim(),label:x.join(":").trim()||y.trim()}}))}if(n.type==="textarea"){const h=parseInt(document.getElementById(`fb-rows-${e}`)?.value,10);h>0&&(n.formConfig={...n.formConfig||{},rows:h})}const a=document.getElementById(`fb-span-${e}`),p=document.getElementById(`fb-fullwidth-${e}`);if(a||p){const h={...n.formConfig||{}};if(p?.checked)h.span="full";else{const m=parseInt(a?.value,10);m>1?h.span=m:delete h.span}n.formConfig=Object.keys(h).length?h:void 0}const c=document.getElementById(`fb-minlength-${e}`)?.value;c&&(n.minLength=parseInt(c,10));const u=document.getElementById(`fb-maxlength-${e}`)?.value;u&&(n.maxLength=parseInt(u,10));const f=document.getElementById(`fb-min-${e}`)?.value;f!==""&&f!==void 0&&(n.min=parseFloat(f));const g=document.getElementById(`fb-max-${e}`)?.value;g!==""&&g!==void 0&&(n.max=parseFloat(g));const b=ve(e);return b?n.logic=b:delete n.logic,n}function ve(e){const n=document.querySelector(`.fb-field-card[data-index="${e}"]`);if(!n)return;const s=n.querySelector(".fb-field-logic");if(!s)return;const t={};let o=!1;const l=s.querySelector('[data-logic-section="visibility"]');if(l){const a=l.querySelector(".fb-logic-vis-default"),p=l.querySelector(".fb-logic-vis-transition"),c=Array.from(l.querySelectorAll(".fb-logic-cond-row")).map(b=>{const h=b.querySelector(".fb-logic-cond-field"),m=b.querySelector(".fb-logic-cond-op"),y=b.querySelector(".fb-logic-cond-val"),x=b.querySelector(".fb-logic-vis-then");return h?.value?{when:{all:[{field:h.value,operator:m.value,value:y.value}]},then:x.value}:null}).filter(Boolean),u=a?.value||"visible",f=p?.value||"none",g=parseInt(l.querySelector(".fb-logic-vis-duration")?.value||"",10);(u!=="visible"||c.length>0||f!=="none")&&(t.visibility={default:u,conditions:c},f!=="none"&&(t.visibility.transition=f),f!=="none"&&Number.isFinite(g)&&(t.visibility.duration=g),o=!0)}const i=s.querySelector('[data-logic-section="requirement"]');if(i){const a=i.querySelector(".fb-logic-req-default"),p=Array.from(i.querySelectorAll(".fb-logic-cond-row")).map(c=>{const u=c.querySelector(".fb-logic-cond-field"),f=c.querySelector(".fb-logic-cond-op"),g=c.querySelector(".fb-logic-cond-val"),b=c.querySelector(".fb-logic-req-then");return u?.value?{when:{all:[{field:u.value,operator:f.value,value:g.value}]},then:b.value==="true"}:null}).filter(Boolean);p.length>0&&(t.requirement={default:a?.checked===!0,conditions:p},o=!0)}const d=s.querySelector('[data-logic-section="validation"]');if(d){const a=Array.from(d.querySelectorAll(".fb-logic-val-rule")).map(p=>{const c=p.querySelector(".fb-logic-val-type"),u=p.querySelector(".fb-logic-val-pattern"),f=p.querySelector(".fb-logic-val-flags"),g=p.querySelector(".fb-logic-val-message");if(!u?.value.trim())return null;const b=c?.value||"regex",h={type:b,message:g?.value.trim()||"Invalid value."};return b==="regex"?(h.pattern=u.value.trim(),f?.value.trim()&&(h.flags=f.value.trim())):h.field=u.value.trim(),h}).filter(Boolean);a.length>0&&(t.validation=a,o=!0)}const r=s.querySelector('[data-logic-section="cascade"]');if(r){const a=r.querySelector(".fb-logic-cascade-source"),p=r.querySelector(".fb-logic-cascade-mapping"),c=r.querySelector(".fb-logic-cascade-defaults"),u=a?.value?.trim();if(u){let f={};try{f=JSON.parse(p?.value||"{}")}catch{}const g=(c?.value||"").split(`
3
- `).filter(b=>b.trim()).map(b=>{const[h,...m]=b.split(":");return{value:h.trim(),label:m.join(":").trim()||h.trim()}});t.cascade={sourceField:u,mapping:f,defaultOptions:g},o=!0}}return o?t:void 0}function L(){v=v.map((e,n)=>ye(n))}let I=null;function xe(e,n,s){const t=e.firstElementChild;if(!t)return;const o=document.createElement("span");o.setAttribute("data-icon","menu"),o.setAttribute("data-icon-size","13"),o.title="Drag to reorder",o.style.cssText="cursor:grab;opacity:.35;flex-shrink:0;display:inline-flex;align-items:center;",t.insertBefore(o,t.firstChild),window.I?.scan?.(t),t.draggable=!0,t.addEventListener("dragstart",l=>{I=n,l.dataTransfer.effectAllowed="move",e.style.opacity="0.4"}),t.addEventListener("dragend",()=>{e.style.opacity="",document.querySelectorAll("#fields-list .fb-field-card").forEach(l=>l.classList.remove("fb-drag-over"))}),e.addEventListener("dragover",l=>{I!=null&&(l.preventDefault(),l.dataTransfer.dropEffect="move",document.querySelectorAll("#fields-list .fb-field-card").forEach(i=>i.classList.remove("fb-drag-over")),e.classList.add("fb-drag-over"))}),e.addEventListener("dragleave",()=>e.classList.remove("fb-drag-over")),e.addEventListener("drop",l=>{if(l.preventDefault(),e.classList.remove("fb-drag-over"),I==null||I===n){I=null;return}L();const[i]=v.splice(I,1);v.splice(n,0,i),I=null,$(s)})}function $(e){const n=e.find("#fields-list").get(0),s=e.find("#fields-empty-msg").get(0);if(n){if(Array.from(n.querySelectorAll(".fb-field-card")).forEach(t=>t.remove()),v.length===0){s&&(s.style.display=""),Y();return}s&&(s.style.display="none"),v.forEach((t,o)=>{const l=t.type==="page-break"?Ce(t,o,e):t.type==="spacer"?Ee(t,o,e):we(t,o,e);xe(l,o,e),n.appendChild(l)}),Y()}}function Ce(e,n,s){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:2px dashed var(--dm-border,#444);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg,rgba(255,255,255,.02));";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent="\u2014 Page Break \u2014",l.style.cssText="font-size:.7rem;padding:.15rem .5rem;border-radius:999px;background:color-mix(in srgb, var(--dm-text-muted) 20%, transparent);color:var(--dm-text-muted,#888);white-space:nowrap;flex-shrink:0;font-style:italic;";const i=document.createElement("span");i.textContent=e.label||"Untitled Step",i.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dm-text-muted,#888);";const d=document.createElement("div");d.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit step",w(r,"more-horizontal"),r.addEventListener("click",f=>{f.stopPropagation(),p.style.display=p.style.display==="none"?"":"none"}),d.appendChild(r);const a=document.createElement("button");a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove page break",w(a,"x"),a.addEventListener("click",async f=>{f.stopPropagation(),await E.confirm("Remove this page break?")&&(L(),v.splice(n,1),$(s))}),d.appendChild(a),o.appendChild(l),o.appendChild(i),o.appendChild(d),o.addEventListener("click",()=>{p.style.display=p.style.display==="none"?"":"none"});const p=document.createElement("div");p.className="fb-field-body",p.style.cssText="padding:.8rem;border-top:1px dashed var(--dm-border,#444);display:none;";const c=S([k("Step Title",`fb-pb-label-${n}`,"text",e.label||"","Shown as the wizard step heading"),k("Step Description",`fb-pb-desc-${n}`,"text",e.description||"","Optional sub-heading")]),u=c.querySelector(`#fb-pb-label-${n}`);return u&&u.addEventListener("input",()=>{i.textContent=u.value||"Untitled Step"}),p.appendChild(c),t.appendChild(o),t.appendChild(p),t}function Ee(e,n,s){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:1px dashed var(--dm-border,#444);border-radius:6px;margin-bottom:.5rem;background:transparent;";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.4rem .8rem;";const l=document.createElement("div");l.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const i=document.createElement("span");i.textContent="Spacer",i.style.cssText="font-size:.7rem;color:var(--dm-text-muted,#888);white-space:nowrap;padding:0 .4rem;font-style:italic;";const d=document.createElement("div");d.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const r=document.createElement("div");r.style.cssText="display:flex;gap:.25rem;flex-shrink:0;";const a=document.createElement("button");return a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove spacer",w(a,"x"),a.addEventListener("click",async p=>{p.stopPropagation(),L(),v.splice(n,1),$(s)}),r.appendChild(a),o.appendChild(l),o.appendChild(i),o.appendChild(d),o.appendChild(r),t.appendChild(o),t}function we(e,n,s){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:1px solid var(--dm-border,#333);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg);box-shadow:var(--dm-shadow-sm);";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;background:var(--dm-card-header-bg,rgba(255,255,255,.04));cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent=le(e.type),l.style.cssText="font-size:.7rem;padding:.15rem .45rem;border-radius:999px;background:color-mix(in srgb, var(--dm-primary) 14%, transparent);color:var(--dm-primary,#6366f1);white-space:nowrap;flex-shrink:0;";const i=document.createElement("span");i.textContent=e.label||"(unlabelled)",i.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";const d=document.createElement("div");d.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit field",w(r,"more-horizontal"),r.addEventListener("click",c=>{c.stopPropagation(),p.style.display=p.style.display==="none"?"":"none"}),d.appendChild(r);const a=document.createElement("button");if(a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove field",w(a,"x"),a.addEventListener("click",async c=>{c.stopPropagation(),await E.confirm("Remove this field?")&&(L(),v.splice(n,1),$(s))}),d.appendChild(a),o.appendChild(l),o.appendChild(i),e.required){const c=document.createElement("span");c.textContent="required",c.style.cssText="font-size:.7rem;color:var(--dm-danger,#ef4444);flex-shrink:0;",o.appendChild(c)}if(oe(e.logic)){const c=document.createElement("span");w(c,"zap"),c.title="Has conditional logic",c.style.cssText="font-size:.75rem;color:var(--dm-primary,#6366f1);flex-shrink:0;",o.appendChild(c)}o.appendChild(d),o.addEventListener("click",()=>{p.style.display=p.style.display==="none"?"":"none"});const p=Se(e,n,i);return p.style.display="none",t.appendChild(o),t.appendChild(p),t}function Se(e,n,s){const t=document.createElement("div");t.className="fb-field-body",t.style.cssText="padding:1rem .9rem;border-top:1px solid var(--dm-border,#333);";const o=S([k("Label",`fb-label-${n}`,"text",e.label||"","Shown above the field"),k("Field Name",`fb-name-${n}`,"text",e.name||"","Used as data key")]),l=S([_e("Type",`fb-type-${n}`,ee,e.type||"string"),ue("Required",`fb-required-${n}`,e.required||!1)]),i=S([k("Placeholder",`fb-placeholder-${n}`,"text",e.placeholder||"","Hint text inside the field")]),d=S([k("Helper Text",`fb-helper-${n}`,"text",e.helper||"","Shown below the field"),k("Tooltip",`fb-tooltip-${n}`,"text",e.tooltip||"","Shown on hover via a help icon next to the label")]),r=e.formConfig?.span,a=S([k("Column Span",`fb-span-${n}`,"number",r&&r!=="full"?String(r):"1","Columns to span (grid only)"),ue("Full Width",`fb-fullwidth-${n}`,r==="full")]);a.classList.add("fb-grid-row"),a.style.display=document.getElementById("setting-layout")?.value==="grid"?"flex":"none",t.appendChild(o),t.appendChild(l),t.appendChild(i),t.appendChild(d),t.appendChild(a);const p=t.querySelector(`#fb-label-${n}`),c=t.querySelector(`#fb-name-${n}`);p&&p.addEventListener("input",()=>{s&&(s.textContent=p.value||"(unlabelled)"),c&&!c.dataset.manuallyEdited&&(c.value=ne(p.value))}),c&&c.addEventListener("input",()=>{c.dataset.manuallyEdited="1"});const u=t.querySelector(`#fb-type-${n}`);u&&u.addEventListener("change",()=>{const g=t.closest(".fb-field-card");if(g){const m=g.querySelector("span");m&&(m.textContent=le(u.value))}const b=t.querySelector(".fb-field-extras");b&&b.remove();const h=re(u.value,e,n);h&&t.appendChild(h)});const f=re(e.type,e,n);return f&&t.appendChild(f),t.appendChild($e(e,n)),t}const ae=[{value:"equals",label:"equals"},{value:"not_equals",label:"does not equal"},{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"},{value:"starts_with",label:"starts with"},{value:"ends_with",label:"ends with"},{value:"greater_than",label:"is greater than"},{value:"less_than",label:"is less than"},{value:"is_empty",label:"is empty"},{value:"is_not_empty",label:"is not empty"},{value:"in",label:"is one of (comma sep)"},{value:"not_in",label:"is not one of (comma sep)"},{value:"matches_regex",label:"matches regex"}],se=new Set(["is_empty","is_not_empty"]),ke={equals:"includes",not_equals:"does not include",contains:"any value contains",not_contains:"no value contains",starts_with:"any value starts with",ends_with:"any value ends with",greater_than:"any value is greater than",less_than:"any value is less than",is_empty:"nothing selected",is_not_empty:"something selected",in:"includes one of (comma sep)",not_in:"includes none of (comma sep)",matches_regex:"any value matches regex"};function ie(e){return!!e&&(e.type==="checkbox-group"||!!e.multiple)}function V(e){const n=document.createElement("p");return n.textContent=e,n.style.cssText="font-size:.72rem;font-weight:700;color:var(--dm-text-muted,#888);margin:1rem 0 .45rem;text-transform:uppercase;letter-spacing:.06em;",n}function H(e,n,s,t,o){const l=document.createElement("div");l.className="fb-logic-cond-row",l.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const i=document.createElement("span");i.textContent="When",i.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const d=document.createElement("select");d.className="form-select fb-logic-cond-field",d.style.cssText="flex:1 1 140px;min-width:140px;",n.forEach(g=>{const b=document.createElement("option");b.value=g.value,b.textContent=g.label,e&&g.value===e.field&&(b.selected=!0),d.appendChild(b)});const r=document.createElement("select");r.className="form-select fb-logic-cond-op",r.style.cssText="flex:1 1 160px;min-width:140px;",ae.forEach(g=>{const b=document.createElement("option");b.value=g.value,b.textContent=g.label,e&&g.value===e.operator&&(b.selected=!0),r.appendChild(b)});const a=()=>{const g=n.find(b=>b.value===d.value);Array.from(r.options).forEach(b=>{const h=ae.find(m=>m.value===b.value);b.textContent=g?.multi&&ke[b.value]||h?.label||b.value})};a(),d.addEventListener("change",a);const p=document.createElement("input");p.type="text",p.className="form-input fb-logic-cond-val",p.placeholder="value",p.style.cssText="flex:1 1 120px;min-width:100px;",p.value=e?.value||"",e&&se.has(e.operator)&&(p.style.display="none"),r.addEventListener("change",()=>{p.style.display=se.has(r.value)?"none":""});const c=document.createElement("span");w(c,"arrow-right"),c.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const u=document.createElement("select");u.className=`form-select ${t}`,u.style.cssText="flex:1 1 140px;min-width:120px;",s.forEach(g=>{const b=document.createElement("option");b.value=g.value,b.textContent=g.label,g.value===o&&(b.selected=!0),u.appendChild(b)});const f=document.createElement("button");return f.type="button",f.className="btn btn-xs btn-ghost",f.style.cssText="line-height:1;opacity:.6;",w(f,"x"),f.style.flexShrink="0",f.addEventListener("click",()=>l.remove()),l.appendChild(i),l.appendChild(d),l.appendChild(r),l.appendChild(p),l.appendChild(c),l.appendChild(u),l.appendChild(f),l}function Te(e,n,s){const t=document.createElement("div");t.dataset.logicSection="visibility",t.appendChild(V("Visibility"));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const l=document.createElement("span");l.textContent="Default:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const i=document.createElement("select");i.className="form-select fb-logic-vis-default",i.style.cssText="max-width:240px;",[{value:"visible",label:"Visible"},{value:"hidden",label:"Hidden"}].forEach(m=>{const y=document.createElement("option");y.value=m.value,y.textContent=m.label,m.value===(e.default||"visible")&&(y.selected=!0),i.appendChild(y)}),o.appendChild(l),o.appendChild(i),t.appendChild(o);const d=document.createElement("div");d.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const r=document.createElement("span");r.textContent="Transition:",r.style.cssText="font-size:.8rem;flex-shrink:0;";const a=document.createElement("select");a.className="form-select fb-logic-vis-transition",a.style.cssText="max-width:240px;",[{value:"none",label:"None (instant)"},{value:"fade",label:"Fade"},{value:"slide",label:"Slide"},{value:"scale",label:"Scale"}].forEach(m=>{const y=document.createElement("option");y.value=m.value,y.textContent=m.label,m.value===(e.transition||"none")&&(y.selected=!0),a.appendChild(y)}),d.appendChild(r),d.appendChild(a),t.appendChild(d);const p=document.createElement("div");p.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const c=document.createElement("span");c.textContent="Speed:",c.style.cssText="font-size:.8rem;flex-shrink:0;";const u=document.createElement("select");u.className="form-select fb-logic-vis-duration",u.style.cssText="max-width:240px;",[{value:"",label:"Default"},{value:"120",label:"Very fast (120ms)"},{value:"200",label:"Fast (200ms)"},{value:"350",label:"Medium (350ms)"},{value:"600",label:"Slow (600ms)"},{value:"1000",label:"Very slow (1s)"}].forEach(m=>{const y=document.createElement("option");y.value=m.value,y.textContent=m.label,m.value===String(e.duration??"")&&(y.selected=!0),u.appendChild(y)}),p.appendChild(c),p.appendChild(u),t.appendChild(p);const f=()=>{p.style.display=a.value==="none"?"none":""};f(),a.addEventListener("change",f);const g=document.createElement("div");g.className="fb-logic-vis-rules";const b=s.map(m=>({value:m.name,label:m.label||m.name,multi:ie(m)})),h=[{value:"visible",label:"Show"},{value:"hidden",label:"Hide"}];if((e.conditions||[]).forEach(m=>{const y=(m.when?.all||m.when?.any||[])[0],x=m.then==="hidden"?"hidden":"visible";b.length>0&&g.appendChild(H(y,b,h,"fb-logic-vis-then",x))}),t.appendChild(g),b.length>0){const m=document.createElement("button");m.type="button",m.className="btn btn-xs btn-ghost",m.style.cssText="font-size:.73rem;margin-top:.2rem;",M(m,"plus","Add visibility rule"),m.addEventListener("click",()=>g.appendChild(H(null,b,h,"fb-logic-vis-then","visible"))),t.appendChild(m)}return t}function Ne(e,n,s){const t=document.createElement("div");t.dataset.logicSection="requirement",t.appendChild(V("Conditional Requirement"));const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;font-size:.8rem;cursor:pointer;margin-bottom:.4rem;";const l=document.createElement("input");l.type="checkbox",l.className="fb-logic-req-default",l.checked=e.default===!0,o.appendChild(l),o.appendChild(document.createTextNode("Required by default")),t.appendChild(o);const i=document.createElement("div");i.className="fb-logic-req-rules";const d=s.map(a=>({value:a.name,label:a.label||a.name,multi:ie(a)})),r=[{value:"true",label:"Make required"},{value:"false",label:"Make optional"}];if((e.conditions||[]).forEach(a=>{const p=(a.when?.all||a.when?.any||[])[0],c=a.then===!0?"true":"false";d.length>0&&i.appendChild(H(p,d,r,"fb-logic-req-then",c))}),t.appendChild(i),d.length>0){const a=document.createElement("button");a.type="button",a.className="btn btn-xs btn-ghost",a.style.cssText="font-size:.73rem;margin-top:.2rem;",M(a,"plus","Add requirement rule"),a.addEventListener("click",()=>i.appendChild(H(null,d,r,"fb-logic-req-then","true"))),t.appendChild(a)}return t}function ce(e){const n=document.createElement("div");n.className="fb-logic-val-rule",n.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const s=document.createElement("select");s.className="form-select fb-logic-val-type",s.style.cssText="flex:0 0 140px;",[{value:"regex",label:"Regex"},{value:"match",label:"Match field"}].forEach(d=>{const r=document.createElement("option");r.value=d.value,r.textContent=d.label,d.value===(e?.type||"regex")&&(r.selected=!0),s.appendChild(r)});const t=document.createElement("input");t.type="text",t.className="form-input fb-logic-val-pattern",t.placeholder=e?.type==="match"?"field name":"pattern",t.value=e?.pattern||e?.field||"",t.style.cssText="flex:3;";const o=document.createElement("input");o.type="text",o.className="form-input fb-logic-val-flags",o.placeholder="flags",o.value=e?.flags||"",o.style.cssText="flex:0 0 55px;",e?.type==="match"&&(o.style.display="none"),s.addEventListener("change",()=>{o.style.display=s.value==="match"?"none":"",t.placeholder=s.value==="match"?"field name":"pattern"});const l=document.createElement("input");l.type="text",l.className="form-input fb-logic-val-message",l.placeholder="Error message",l.value=e?.message||"",l.style.cssText="flex:4;";const i=document.createElement("button");return i.type="button",i.className="btn btn-xs btn-ghost",i.style.cssText="line-height:1;opacity:.6;",w(i,"x"),i.style.flexShrink="0",i.addEventListener("click",()=>n.remove()),n.appendChild(s),n.appendChild(t),n.appendChild(o),n.appendChild(l),n.appendChild(i),n}function qe(e,n,s){const t=document.createElement("div");t.dataset.logicSection="validation",t.appendChild(V("Custom Validation"));const o=document.createElement("div");o.className="fb-logic-val-rules",(e||[]).forEach(i=>o.appendChild(ce(i))),t.appendChild(o);const l=document.createElement("button");return l.type="button",l.className="btn btn-xs btn-ghost",l.style.cssText="font-size:.73rem;margin-top:.2rem;",M(l,"plus","Add validation rule"),l.addEventListener("click",()=>o.appendChild(ce(null))),t.appendChild(l),t}function Le(e,n,s){const t=document.createElement("div");t.dataset.logicSection="cascade",t.appendChild(V("Cascade Options")),t.lastChild.appendChild(Q("Make this field's options depend on another field. When the source field changes, the options here are replaced by the mapping entry for its value; if nothing matches, the default options below are shown."));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;";const l=document.createElement("span");l.textContent="Source field:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const i=document.createElement("select");i.className="form-select fb-logic-cascade-source",i.style.cssText="flex:1;";const d=document.createElement("option");d.value="",d.textContent="\u2014 none \u2014",i.appendChild(d),s.forEach(u=>{const f=document.createElement("option");f.value=u.name,f.textContent=u.label||u.name,u.name===e.sourceField&&(f.selected=!0),i.appendChild(f)}),o.appendChild(l),o.appendChild(i),t.appendChild(o);const r=document.createElement("p");r.textContent='Mapping JSON \u2014 {"value":[{"value":"...","label":"..."}]}',r.appendChild(Q(`Each key is a value of the source field; its list becomes this field's options when that value is picked. Example: {"uk":[{"value":"london","label":"London"}]} shows London when the source is "uk".`)),r.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const a=document.createElement("textarea");a.className="form-input fb-logic-cascade-mapping",a.rows=4,a.style.cssText="font-family:monospace;",a.placeholder='{"uk": [{"value": "london", "label": "London"}]}',a.value=e.mapping?JSON.stringify(e.mapping,null,2):"",t.appendChild(r),t.appendChild(a);const p=document.createElement("p");p.textContent="Default options (one per line: value:Label)",p.appendChild(Q("Shown before the source field has a value, or when its value has no mapping entry.")),p.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const c=document.createElement("textarea");return c.className="form-input fb-logic-cascade-defaults",c.rows=3,c.style.cssText="font-family:monospace;",c.placeholder=`option1:Option 1
1
+ import{apiRequest as A}from"/admin/js/api.js";import{makeIconInput as ge}from"/admin/js/lib/shortcode-modal.js";import{enhancePickerFields as Z}from"/public/js/forms.js";const ee=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"chooser",label:"Chooser (visual options)"},{value:"icon",label:"Icon (icon picker)"},{value:"image",label:"Image (media library)"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"password",label:"Password"},{value:"file",label:"File upload"},{value:"hidden",label:"Hidden field"}],G=new Set(["select","radio","checkbox-group","chooser"]);let v=[],q=null,P=null,M=null,J={};function w(e,n,i=14){e.textContent="";const t=document.createElement("span");return t.setAttribute("data-icon",n),t.setAttribute("data-icon-size",String(i)),t.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",e.appendChild(t),window.I?.scan?.(e),e}function j(e,n,i,t=14){return w(e,n,t),e.appendChild(document.createTextNode(" "+i)),e}function Y(e){const n=document.createElement("span");return n.setAttribute("data-icon","help-circle"),n.setAttribute("data-icon-size","12"),n.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;margin-left:.3rem;opacity:.55;cursor:help;",n.title=e,window.I?.scan?.(n),requestAnimationFrame(()=>{try{n.parentNode&&typeof E<"u"&&E.tooltip&&(n.removeAttribute("title"),E.tooltip(n,{content:e,position:"top"}))}catch{}}),n}let D=null,te=null;function Q(){clearTimeout(te),te=setTimeout(()=>{D&&D()},350)}function ne(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")}function le(e){return ee.find(n=>n.value===e)?.label||e}function oe(e){return e?!!(e.visibility?.conditions?.length||e.requirement?.conditions?.length||e.validation?.length||e.cascade?.sourceField):!1}function ye(e){const n={...v[e]};if(n.type==="spacer")return n;if(n.type==="page-break"){const h=document.getElementById(`fb-pb-label-${e}`),m=document.getElementById(`fb-pb-desc-${e}`);return h&&(n.label=h.value.trim()||n.label),m&&(n.description=m.value.trim()),n}const i=document.getElementById(`fb-label-${e}`),t=document.getElementById(`fb-name-${e}`),o=document.getElementById(`fb-type-${e}`),l=document.getElementById(`fb-required-${e}`),s=document.getElementById(`fb-placeholder-${e}`),d=document.getElementById(`fb-helper-${e}`),r=document.getElementById(`fb-tooltip-${e}`);if(i&&(n.label=i.value.trim()||n.label),t&&(n.name=t.value.trim()||n.name),o&&(n.type=o.value||n.type),l&&(n.required=l.checked),s&&(n.placeholder=s.value.trim()),d&&(n.helper=d.value.trim()),r&&(n.tooltip=r.value.trim()),n.type==="chooser"){const h=document.getElementById(`fb-chooser-variant-${e}`)?.value;h&&(n.variant=h);const m=document.getElementById(`fb-chooser-multiple-${e}`);m&&(n.multiple=m.checked);const y=document.getElementById(`fb-chooser-density-${e}`)?.value;y&&(n.density=y);const x=document.getElementById(`fb-chooser-columns-${e}`)?.value;x!==""&&x!==void 0&&(n.columns=parseInt(x,10)||3);const C=document.getElementById(`fb-chooser-accent-${e}`)?.value.trim();C?n.accent=C:delete n.accent;const T=document.getElementById(`fb-chooser-accent-style-${e}`)?.value;T?n.accentStyle=T:delete n.accentStyle;const z=document.getElementById(`fb-chooser-glow-${e}`);z&&(n.glow=z.checked);const I=document.getElementById(`fb-chooser-glow-colour-${e}`)?.value.trim();I?n.glowColour=I:delete n.glowColour;const N=document.getElementById(`fb-chooser-shadow-${e}`)?.value;N&&N!=="none"?n.shadow=N:delete n.shadow;const O=document.getElementById(`fb-chooser-shadow-colour-${e}`)?.value.trim();O?n.shadowColour=O:delete n.shadowColour,W(e),v[e]&&Array.isArray(v[e].options)&&(n.options=v[e].options)}else if(G.has(n.type)){const h=document.getElementById(`fb-options-${e}`);h&&(n.options=h.value.split(`
2
+ `).filter(m=>m.trim()).map(m=>{const[y,...x]=m.split(":");return{value:y.trim(),label:x.join(":").trim()||y.trim()}}))}if(n.type==="textarea"){const h=parseInt(document.getElementById(`fb-rows-${e}`)?.value,10);h>0&&(n.formConfig={...n.formConfig||{},rows:h})}const a=document.getElementById(`fb-span-${e}`),p=document.getElementById(`fb-fullwidth-${e}`);if(a||p){const h={...n.formConfig||{}};if(p?.checked)h.span="full";else{const m=parseInt(a?.value,10);m>1?h.span=m:delete h.span}n.formConfig=Object.keys(h).length?h:void 0}const c=document.getElementById(`fb-minlength-${e}`)?.value;c&&(n.minLength=parseInt(c,10));const u=document.getElementById(`fb-maxlength-${e}`)?.value;u&&(n.maxLength=parseInt(u,10));const f=document.getElementById(`fb-min-${e}`)?.value;f!==""&&f!==void 0&&(n.min=parseFloat(f));const g=document.getElementById(`fb-max-${e}`)?.value;g!==""&&g!==void 0&&(n.max=parseFloat(g));const b=ve(e);return b?n.logic=b:delete n.logic,n}function ve(e){const n=document.querySelector(`.fb-field-card[data-index="${e}"]`);if(!n)return;const i=n.querySelector(".fb-field-logic");if(!i)return;const t={};let o=!1;const l=i.querySelector('[data-logic-section="visibility"]');if(l){const a=l.querySelector(".fb-logic-vis-default"),p=l.querySelector(".fb-logic-vis-transition"),c=Array.from(l.querySelectorAll(".fb-logic-cond-row")).map(b=>{const h=b.querySelector(".fb-logic-cond-field"),m=b.querySelector(".fb-logic-cond-op"),y=b.querySelector(".fb-logic-cond-val"),x=b.querySelector(".fb-logic-vis-then");return h?.value?{when:{all:[{field:h.value,operator:m.value,value:y.value}]},then:x.value}:null}).filter(Boolean),u=a?.value||"visible",f=p?.value||"none",g=parseInt(l.querySelector(".fb-logic-vis-duration")?.value||"",10);(u!=="visible"||c.length>0||f!=="none")&&(t.visibility={default:u,conditions:c},f!=="none"&&(t.visibility.transition=f),f!=="none"&&Number.isFinite(g)&&(t.visibility.duration=g),o=!0)}const s=i.querySelector('[data-logic-section="requirement"]');if(s){const a=s.querySelector(".fb-logic-req-default"),p=Array.from(s.querySelectorAll(".fb-logic-cond-row")).map(c=>{const u=c.querySelector(".fb-logic-cond-field"),f=c.querySelector(".fb-logic-cond-op"),g=c.querySelector(".fb-logic-cond-val"),b=c.querySelector(".fb-logic-req-then");return u?.value?{when:{all:[{field:u.value,operator:f.value,value:g.value}]},then:b.value==="true"}:null}).filter(Boolean);p.length>0&&(t.requirement={default:a?.checked===!0,conditions:p},o=!0)}const d=i.querySelector('[data-logic-section="validation"]');if(d){const a=Array.from(d.querySelectorAll(".fb-logic-val-rule")).map(p=>{const c=p.querySelector(".fb-logic-val-type"),u=p.querySelector(".fb-logic-val-pattern"),f=p.querySelector(".fb-logic-val-flags"),g=p.querySelector(".fb-logic-val-message");if(!u?.value.trim())return null;const b=c?.value||"regex",h={type:b,message:g?.value.trim()||"Invalid value."};return b==="regex"?(h.pattern=u.value.trim(),f?.value.trim()&&(h.flags=f.value.trim())):h.field=u.value.trim(),h}).filter(Boolean);a.length>0&&(t.validation=a,o=!0)}const r=i.querySelector('[data-logic-section="cascade"]');if(r){const a=r.querySelector(".fb-logic-cascade-source"),p=r.querySelector(".fb-logic-cascade-mapping"),c=r.querySelector(".fb-logic-cascade-defaults"),u=a?.value?.trim();if(u){let f={};try{f=JSON.parse(p?.value||"{}")}catch{}const g=(c?.value||"").split(`
3
+ `).filter(b=>b.trim()).map(b=>{const[h,...m]=b.split(":");return{value:h.trim(),label:m.join(":").trim()||h.trim()}});t.cascade={sourceField:u,mapping:f,defaultOptions:g},o=!0}}return o?t:void 0}function L(){v=v.map((e,n)=>ye(n))}let B=null;function xe(e,n,i){const t=e.firstElementChild;if(!t)return;const o=document.createElement("span");o.setAttribute("data-icon","menu"),o.setAttribute("data-icon-size","13"),o.title="Drag to reorder",o.style.cssText="cursor:grab;opacity:.35;flex-shrink:0;display:inline-flex;align-items:center;",t.insertBefore(o,t.firstChild),window.I?.scan?.(t),t.draggable=!0,t.addEventListener("dragstart",l=>{B=n,l.dataTransfer.effectAllowed="move",e.style.opacity="0.4"}),t.addEventListener("dragend",()=>{e.style.opacity="",document.querySelectorAll("#fields-list .fb-field-card").forEach(l=>l.classList.remove("fb-drag-over"))}),e.addEventListener("dragover",l=>{B!=null&&(l.preventDefault(),l.dataTransfer.dropEffect="move",document.querySelectorAll("#fields-list .fb-field-card").forEach(s=>s.classList.remove("fb-drag-over")),e.classList.add("fb-drag-over"))}),e.addEventListener("dragleave",()=>e.classList.remove("fb-drag-over")),e.addEventListener("drop",l=>{if(l.preventDefault(),e.classList.remove("fb-drag-over"),B==null||B===n){B=null;return}L();const[s]=v.splice(B,1);v.splice(n,0,s),B=null,$(i)})}function $(e){const n=e.find("#fields-list").get(0),i=e.find("#fields-empty-msg").get(0);if(n){if(Array.from(n.querySelectorAll(".fb-field-card")).forEach(t=>t.remove()),v.length===0){i&&(i.style.display=""),Q();return}i&&(i.style.display="none"),v.forEach((t,o)=>{const l=t.type==="page-break"?Ce(t,o,e):t.type==="spacer"?Ee(t,o,e):we(t,o,e);xe(l,o,e),n.appendChild(l)}),Q()}}function Ce(e,n,i){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:2px dashed var(--dm-border,#444);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg,rgba(255,255,255,.02));";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent="\u2014 Page Break \u2014",l.style.cssText="font-size:.7rem;padding:.15rem .5rem;border-radius:999px;background:color-mix(in srgb, var(--dm-text-muted) 20%, transparent);color:var(--dm-text-muted,#888);white-space:nowrap;flex-shrink:0;font-style:italic;";const s=document.createElement("span");s.textContent=e.label||"Untitled Step",s.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dm-text-muted,#888);";const d=document.createElement("div");d.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit step",w(r,"more-horizontal"),r.addEventListener("click",f=>{f.stopPropagation(),p.style.display=p.style.display==="none"?"":"none"}),d.appendChild(r);const a=document.createElement("button");a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove page break",w(a,"x"),a.addEventListener("click",async f=>{f.stopPropagation(),await E.confirm("Remove this page break?")&&(L(),v.splice(n,1),$(i))}),d.appendChild(a),o.appendChild(l),o.appendChild(s),o.appendChild(d),o.addEventListener("click",()=>{p.style.display=p.style.display==="none"?"":"none"});const p=document.createElement("div");p.className="fb-field-body",p.style.cssText="padding:.8rem;border-top:1px dashed var(--dm-border,#444);display:none;";const c=S([k("Step Title",`fb-pb-label-${n}`,"text",e.label||"","Shown as the wizard step heading"),k("Step Description",`fb-pb-desc-${n}`,"text",e.description||"","Optional sub-heading")]),u=c.querySelector(`#fb-pb-label-${n}`);return u&&u.addEventListener("input",()=>{s.textContent=u.value||"Untitled Step"}),p.appendChild(c),t.appendChild(o),t.appendChild(p),t}function Ee(e,n,i){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:1px dashed var(--dm-border,#444);border-radius:6px;margin-bottom:.5rem;background:transparent;";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.4rem .8rem;";const l=document.createElement("div");l.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const s=document.createElement("span");s.textContent="Spacer",s.style.cssText="font-size:.7rem;color:var(--dm-text-muted,#888);white-space:nowrap;padding:0 .4rem;font-style:italic;";const d=document.createElement("div");d.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const r=document.createElement("div");r.style.cssText="display:flex;gap:.25rem;flex-shrink:0;";const a=document.createElement("button");return a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove spacer",w(a,"x"),a.addEventListener("click",async p=>{p.stopPropagation(),L(),v.splice(n,1),$(i)}),r.appendChild(a),o.appendChild(l),o.appendChild(s),o.appendChild(d),o.appendChild(r),t.appendChild(o),t}function we(e,n,i){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:1px solid var(--dm-border,#333);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg);box-shadow:var(--dm-shadow-sm);";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;background:var(--dm-card-header-bg,rgba(255,255,255,.04));cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent=le(e.type),l.style.cssText="font-size:.7rem;padding:.15rem .45rem;border-radius:999px;background:color-mix(in srgb, var(--dm-primary) 14%, transparent);color:var(--dm-primary,#6366f1);white-space:nowrap;flex-shrink:0;";const s=document.createElement("span");s.textContent=e.label||"(unlabelled)",s.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";const d=document.createElement("div");d.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit field",w(r,"more-horizontal"),r.addEventListener("click",c=>{c.stopPropagation(),p.style.display=p.style.display==="none"?"":"none"}),d.appendChild(r);const a=document.createElement("button");if(a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove field",w(a,"x"),a.addEventListener("click",async c=>{c.stopPropagation(),await E.confirm("Remove this field?")&&(L(),v.splice(n,1),$(i))}),d.appendChild(a),o.appendChild(l),o.appendChild(s),e.required){const c=document.createElement("span");c.textContent="required",c.style.cssText="font-size:.7rem;color:var(--dm-danger,#ef4444);flex-shrink:0;",o.appendChild(c)}if(oe(e.logic)){const c=document.createElement("span");w(c,"zap"),c.title="Has conditional logic",c.style.cssText="font-size:.75rem;color:var(--dm-primary,#6366f1);flex-shrink:0;",o.appendChild(c)}o.appendChild(d),o.addEventListener("click",()=>{p.style.display=p.style.display==="none"?"":"none"});const p=Se(e,n,s);return p.style.display="none",t.appendChild(o),t.appendChild(p),t}function Se(e,n,i){const t=document.createElement("div");t.className="fb-field-body",t.style.cssText="padding:1rem .9rem;border-top:1px solid var(--dm-border,#333);";const o=S([k("Label",`fb-label-${n}`,"text",e.label||"","Shown above the field"),k("Field Name",`fb-name-${n}`,"text",e.name||"","Used as data key")]),l=S([_e("Type",`fb-type-${n}`,ee,e.type||"string"),ue("Required",`fb-required-${n}`,e.required||!1)]),s=S([k("Placeholder",`fb-placeholder-${n}`,"text",e.placeholder||"","Hint text inside the field")]),d=S([k("Helper Text",`fb-helper-${n}`,"text",e.helper||"","Shown below the field"),k("Tooltip",`fb-tooltip-${n}`,"text",e.tooltip||"","Shown on hover via a help icon next to the label")]),r=e.formConfig?.span,a=S([k("Column Span",`fb-span-${n}`,"number",r&&r!=="full"?String(r):"1","Columns to span (grid only)"),ue("Full Width",`fb-fullwidth-${n}`,r==="full")]);a.classList.add("fb-grid-row"),a.style.display=document.getElementById("setting-layout")?.value==="grid"?"flex":"none",t.appendChild(o),t.appendChild(l),t.appendChild(s),t.appendChild(d),t.appendChild(a);const p=t.querySelector(`#fb-label-${n}`),c=t.querySelector(`#fb-name-${n}`);p&&p.addEventListener("input",()=>{i&&(i.textContent=p.value||"(unlabelled)"),c&&!c.dataset.manuallyEdited&&(c.value=ne(p.value))}),c&&c.addEventListener("input",()=>{c.dataset.manuallyEdited="1"});const u=t.querySelector(`#fb-type-${n}`);u&&u.addEventListener("change",()=>{const g=t.closest(".fb-field-card");if(g){const m=g.querySelector("span");m&&(m.textContent=le(u.value))}const b=t.querySelector(".fb-field-extras");b&&b.remove();const h=re(u.value,e,n);h&&t.appendChild(h)});const f=re(e.type,e,n);return f&&t.appendChild(f),t.appendChild($e(e,n)),t}const ae=[{value:"equals",label:"equals"},{value:"not_equals",label:"does not equal"},{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"},{value:"starts_with",label:"starts with"},{value:"ends_with",label:"ends with"},{value:"greater_than",label:"is greater than"},{value:"less_than",label:"is less than"},{value:"is_empty",label:"is empty"},{value:"is_not_empty",label:"is not empty"},{value:"in",label:"is one of (comma sep)"},{value:"not_in",label:"is not one of (comma sep)"},{value:"matches_regex",label:"matches regex"}],ie=new Set(["is_empty","is_not_empty"]),ke={equals:"includes",not_equals:"does not include",contains:"any value contains",not_contains:"no value contains",starts_with:"any value starts with",ends_with:"any value ends with",greater_than:"any value is greater than",less_than:"any value is less than",is_empty:"nothing selected",is_not_empty:"something selected",in:"includes one of (comma sep)",not_in:"includes none of (comma sep)",matches_regex:"any value matches regex"};function se(e){return!!e&&(e.type==="checkbox-group"||!!e.multiple)}function V(e){const n=document.createElement("p");return n.textContent=e,n.style.cssText="font-size:.72rem;font-weight:700;color:var(--dm-text-muted,#888);margin:1rem 0 .45rem;text-transform:uppercase;letter-spacing:.06em;",n}function H(e,n,i,t,o){const l=document.createElement("div");l.className="fb-logic-cond-row",l.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const s=document.createElement("span");s.textContent="When",s.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const d=document.createElement("select");d.className="form-select fb-logic-cond-field",d.style.cssText="flex:1 1 140px;min-width:140px;",n.forEach(g=>{const b=document.createElement("option");b.value=g.value,b.textContent=g.label,e&&g.value===e.field&&(b.selected=!0),d.appendChild(b)});const r=document.createElement("select");r.className="form-select fb-logic-cond-op",r.style.cssText="flex:1 1 160px;min-width:140px;",ae.forEach(g=>{const b=document.createElement("option");b.value=g.value,b.textContent=g.label,e&&g.value===e.operator&&(b.selected=!0),r.appendChild(b)});const a=()=>{const g=n.find(b=>b.value===d.value);Array.from(r.options).forEach(b=>{const h=ae.find(m=>m.value===b.value);b.textContent=g?.multi&&ke[b.value]||h?.label||b.value})};a(),d.addEventListener("change",a);const p=document.createElement("input");p.type="text",p.className="form-input fb-logic-cond-val",p.placeholder="value",p.style.cssText="flex:1 1 120px;min-width:100px;",p.value=e?.value||"",e&&ie.has(e.operator)&&(p.style.display="none"),r.addEventListener("change",()=>{p.style.display=ie.has(r.value)?"none":""});const c=document.createElement("span");w(c,"arrow-right"),c.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const u=document.createElement("select");u.className=`form-select ${t}`,u.style.cssText="flex:1 1 140px;min-width:120px;",i.forEach(g=>{const b=document.createElement("option");b.value=g.value,b.textContent=g.label,g.value===o&&(b.selected=!0),u.appendChild(b)});const f=document.createElement("button");return f.type="button",f.className="btn btn-xs btn-ghost",f.style.cssText="line-height:1;opacity:.6;",w(f,"x"),f.style.flexShrink="0",f.addEventListener("click",()=>l.remove()),l.appendChild(s),l.appendChild(d),l.appendChild(r),l.appendChild(p),l.appendChild(c),l.appendChild(u),l.appendChild(f),l}function Te(e,n,i){const t=document.createElement("div");t.dataset.logicSection="visibility",t.appendChild(V("Visibility"));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const l=document.createElement("span");l.textContent="Default:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const s=document.createElement("select");s.className="form-select fb-logic-vis-default",s.style.cssText="max-width:240px;",[{value:"visible",label:"Visible"},{value:"hidden",label:"Hidden"}].forEach(m=>{const y=document.createElement("option");y.value=m.value,y.textContent=m.label,m.value===(e.default||"visible")&&(y.selected=!0),s.appendChild(y)}),o.appendChild(l),o.appendChild(s),t.appendChild(o);const d=document.createElement("div");d.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const r=document.createElement("span");r.textContent="Transition:",r.style.cssText="font-size:.8rem;flex-shrink:0;";const a=document.createElement("select");a.className="form-select fb-logic-vis-transition",a.style.cssText="max-width:240px;",[{value:"none",label:"None (instant)"},{value:"fade",label:"Fade"},{value:"slide",label:"Slide"},{value:"scale",label:"Scale"}].forEach(m=>{const y=document.createElement("option");y.value=m.value,y.textContent=m.label,m.value===(e.transition||"none")&&(y.selected=!0),a.appendChild(y)}),d.appendChild(r),d.appendChild(a),t.appendChild(d);const p=document.createElement("div");p.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const c=document.createElement("span");c.textContent="Speed:",c.style.cssText="font-size:.8rem;flex-shrink:0;";const u=document.createElement("select");u.className="form-select fb-logic-vis-duration",u.style.cssText="max-width:240px;",[{value:"",label:"Default"},{value:"120",label:"Very fast (120ms)"},{value:"200",label:"Fast (200ms)"},{value:"350",label:"Medium (350ms)"},{value:"600",label:"Slow (600ms)"},{value:"1000",label:"Very slow (1s)"}].forEach(m=>{const y=document.createElement("option");y.value=m.value,y.textContent=m.label,m.value===String(e.duration??"")&&(y.selected=!0),u.appendChild(y)}),p.appendChild(c),p.appendChild(u),t.appendChild(p);const f=()=>{p.style.display=a.value==="none"?"none":""};f(),a.addEventListener("change",f);const g=document.createElement("div");g.className="fb-logic-vis-rules";const b=i.map(m=>({value:m.name,label:m.label||m.name,multi:se(m)})),h=[{value:"visible",label:"Show"},{value:"hidden",label:"Hide"}];if((e.conditions||[]).forEach(m=>{const y=(m.when?.all||m.when?.any||[])[0],x=m.then==="hidden"?"hidden":"visible";b.length>0&&g.appendChild(H(y,b,h,"fb-logic-vis-then",x))}),t.appendChild(g),b.length>0){const m=document.createElement("button");m.type="button",m.className="btn btn-xs btn-ghost",m.style.cssText="font-size:.73rem;margin-top:.2rem;",j(m,"plus","Add visibility rule"),m.addEventListener("click",()=>g.appendChild(H(null,b,h,"fb-logic-vis-then","visible"))),t.appendChild(m)}return t}function Ne(e,n,i){const t=document.createElement("div");t.dataset.logicSection="requirement",t.appendChild(V("Conditional Requirement"));const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;font-size:.8rem;cursor:pointer;margin-bottom:.4rem;";const l=document.createElement("input");l.type="checkbox",l.className="fb-logic-req-default",l.checked=e.default===!0,o.appendChild(l),o.appendChild(document.createTextNode("Required by default")),t.appendChild(o);const s=document.createElement("div");s.className="fb-logic-req-rules";const d=i.map(a=>({value:a.name,label:a.label||a.name,multi:se(a)})),r=[{value:"true",label:"Make required"},{value:"false",label:"Make optional"}];if((e.conditions||[]).forEach(a=>{const p=(a.when?.all||a.when?.any||[])[0],c=a.then===!0?"true":"false";d.length>0&&s.appendChild(H(p,d,r,"fb-logic-req-then",c))}),t.appendChild(s),d.length>0){const a=document.createElement("button");a.type="button",a.className="btn btn-xs btn-ghost",a.style.cssText="font-size:.73rem;margin-top:.2rem;",j(a,"plus","Add requirement rule"),a.addEventListener("click",()=>s.appendChild(H(null,d,r,"fb-logic-req-then","true"))),t.appendChild(a)}return t}function ce(e){const n=document.createElement("div");n.className="fb-logic-val-rule",n.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const i=document.createElement("select");i.className="form-select fb-logic-val-type",i.style.cssText="flex:0 0 140px;",[{value:"regex",label:"Regex"},{value:"match",label:"Match field"}].forEach(d=>{const r=document.createElement("option");r.value=d.value,r.textContent=d.label,d.value===(e?.type||"regex")&&(r.selected=!0),i.appendChild(r)});const t=document.createElement("input");t.type="text",t.className="form-input fb-logic-val-pattern",t.placeholder=e?.type==="match"?"field name":"pattern",t.value=e?.pattern||e?.field||"",t.style.cssText="flex:3;";const o=document.createElement("input");o.type="text",o.className="form-input fb-logic-val-flags",o.placeholder="flags",o.value=e?.flags||"",o.style.cssText="flex:0 0 55px;",e?.type==="match"&&(o.style.display="none"),i.addEventListener("change",()=>{o.style.display=i.value==="match"?"none":"",t.placeholder=i.value==="match"?"field name":"pattern"});const l=document.createElement("input");l.type="text",l.className="form-input fb-logic-val-message",l.placeholder="Error message",l.value=e?.message||"",l.style.cssText="flex:4;";const s=document.createElement("button");return s.type="button",s.className="btn btn-xs btn-ghost",s.style.cssText="line-height:1;opacity:.6;",w(s,"x"),s.style.flexShrink="0",s.addEventListener("click",()=>n.remove()),n.appendChild(i),n.appendChild(t),n.appendChild(o),n.appendChild(l),n.appendChild(s),n}function qe(e,n,i){const t=document.createElement("div");t.dataset.logicSection="validation",t.appendChild(V("Custom Validation"));const o=document.createElement("div");o.className="fb-logic-val-rules",(e||[]).forEach(s=>o.appendChild(ce(s))),t.appendChild(o);const l=document.createElement("button");return l.type="button",l.className="btn btn-xs btn-ghost",l.style.cssText="font-size:.73rem;margin-top:.2rem;",j(l,"plus","Add validation rule"),l.addEventListener("click",()=>o.appendChild(ce(null))),t.appendChild(l),t}function Le(e,n,i){const t=document.createElement("div");t.dataset.logicSection="cascade",t.appendChild(V("Cascade Options")),t.lastChild.appendChild(Y("Make this field's options depend on another field. When the source field changes, the options here are replaced by the mapping entry for its value; if nothing matches, the default options below are shown."));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;";const l=document.createElement("span");l.textContent="Source field:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const s=document.createElement("select");s.className="form-select fb-logic-cascade-source",s.style.cssText="flex:1;";const d=document.createElement("option");d.value="",d.textContent="\u2014 none \u2014",s.appendChild(d),i.forEach(u=>{const f=document.createElement("option");f.value=u.name,f.textContent=u.label||u.name,u.name===e.sourceField&&(f.selected=!0),s.appendChild(f)}),o.appendChild(l),o.appendChild(s),t.appendChild(o);const r=document.createElement("p");r.textContent='Mapping JSON \u2014 {"value":[{"value":"...","label":"..."}]}',r.appendChild(Y(`Each key is a value of the source field; its list becomes this field's options when that value is picked. Example: {"uk":[{"value":"london","label":"London"}]} shows London when the source is "uk".`)),r.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const a=document.createElement("textarea");a.className="form-input fb-logic-cascade-mapping",a.rows=4,a.style.cssText="font-family:monospace;",a.placeholder='{"uk": [{"value": "london", "label": "London"}]}',a.value=e.mapping?JSON.stringify(e.mapping,null,2):"",t.appendChild(r),t.appendChild(a);const p=document.createElement("p");p.textContent="Default options (one per line: value:Label)",p.appendChild(Y("Shown before the source field has a value, or when its value has no mapping entry.")),p.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const c=document.createElement("textarea");return c.className="form-input fb-logic-cascade-defaults",c.rows=3,c.style.cssText="font-family:monospace;",c.placeholder=`option1:Option 1
4
4
  option2:Option 2`,c.value=(e.defaultOptions||[]).map(u=>{const f=typeof u=="string"?u:u.value??"",g=typeof u=="string"?u:u.label??f;return f===g?f:`${f}:${g}`}).join(`
5
- `),t.appendChild(p),t.appendChild(c),t}function $e(e,n){const s=e.logic||{},t=v.filter((c,u)=>u!==n&&c.type!=="page-break"&&c.type!=="spacer"),o=document.createElement("div");o.className="fb-field-logic",o.style.cssText="margin-top:.75rem;border-top:1px solid var(--dm-border,#333);padding-top:.5rem;";const l=document.createElement("div");l.style.cssText="display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:.15rem 0;";const i=document.createElement("span");i.style.cssText="font-size:.8rem;font-weight:600;color:var(--dm-text-muted,#888);",i.textContent="\u26A1 Conditional Logic";const d=oe(s),r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",w(r,d?"chevron-down":"chevron-right",12);const a=document.createElement("div");a.className="fb-logic-body",a.style.cssText="padding:.25rem 0 .25rem;"+(d?"":"display:none;"),l.addEventListener("click",()=>{const c=a.style.display==="none";a.style.display=c?"":"none",w(r,c?"chevron-down":"chevron-right",12)}),l.appendChild(i),l.appendChild(r),o.appendChild(l),a.appendChild(Te(s.visibility||{},n,t)),a.appendChild(Ne(s.requirement||{},n,t)),a.appendChild(qe(s.validation||[],n,t));const p=document.getElementById(`fb-type-${n}`)?.value||e.type;return W.has(p)&&a.appendChild(Le(s.cascade||{},n,t)),o.appendChild(a),o}function re(e,n,s){const t=document.createElement("div");return t.className="fb-field-extras",e==="chooser"?(t.appendChild(ze(n,s)),t.appendChild(Ie(n.options||[],s))):(W.has(e)&&t.appendChild(je(n.options||[],s)),e==="textarea"&&t.appendChild(S([k("Rows",`fb-rows-${s}`,"number",n.formConfig?.rows||4,"Height of textarea")])),(e==="string"||e==="textarea")&&t.appendChild(S([k("Min Length",`fb-minlength-${s}`,"number",n.minLength||"",""),k("Max Length",`fb-maxlength-${s}`,"number",n.maxLength||"","")])),e==="number"&&t.appendChild(S([k("Min",`fb-min-${s}`,"number",n.min??"",""),k("Max",`fb-max-${s}`,"number",n.max??"","")]))),t.children.length?t:null}function de(e){const n=document.createElement("div");n.className="fb-chooser-section",n.style.cssText="border:1px solid var(--dm-border, #e5e7eb); border-radius:6px; margin-top:.5rem; overflow:hidden;";const s=document.createElement("div");s.style.cssText="padding:.4rem .6rem; background:color-mix(in srgb, var(--dm-background, #f9fafb) 60%, transparent); font-weight:600; font-size:.82rem; border-bottom:1px solid var(--dm-border, #e5e7eb);",s.textContent=e,n.appendChild(s);const t=document.createElement("div");return t.className="fb-chooser-section-body",t.style.cssText="padding:.55rem .6rem; display:flex; flex-direction:column; gap:.45rem;",n.appendChild(t),{wrap:n,body:t}}function U(e,n,s,t,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=e,i.className="form-label",i.textContent=n,i.style.fontSize=".8rem";const d=document.createElement("select");if(d.id=e,d.className="form-input",t.forEach(([r,a])=>{const p=document.createElement("option");p.value=r,p.textContent=a,String(r)===String(s)&&(p.selected=!0),d.appendChild(p)}),l.appendChild(i),l.appendChild(d),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(r)}return l}function pe(e,n,s,t){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.style.cssText="display:inline-flex;align-items:center;gap:.4rem;font-size:.82rem;";const i=document.createElement("input");if(i.id=e,i.type="checkbox",i.checked=!!s,l.appendChild(i),l.appendChild(document.createTextNode(" "+n)),o.appendChild(l),t){const d=document.createElement("p");d.className="form-hint text-muted",d.textContent=t,d.style.cssText="font-size:.72rem;margin-top:.2rem;",o.appendChild(d)}return o}function K(e,n,s,t,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=e,i.className="form-label",i.textContent=n,i.style.fontSize=".8rem",l.appendChild(i);const d=document.createElement("div");d.style.cssText="display:flex;gap:.4rem;align-items:stretch;";const r=document.createElement("input");r.id=e,r.type="text",r.className="form-input",r.value=s||"",t&&(r.placeholder=t),r.style.flex="1";const a=document.createElement("input");a.type="color",a.title="Pick a colour",a.style.cssText="width:36px;height:auto;padding:0;border:1px solid var(--dm-border,#e5e7eb);border-radius:4px;cursor:pointer;";const p=String(r.value).match(/^#[0-9a-fA-F]{3,8}$/);if(a.value=p?r.value:"#000000",a.addEventListener("input",()=>{r.value=a.value,r.dispatchEvent(new Event("input",{bubbles:!0}))}),d.appendChild(r),d.appendChild(a),l.appendChild(d),o){const c=document.createElement("p");c.className="form-hint text-muted",c.textContent=o,c.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(c)}return l}function ze(e,n){const s=document.createElement("div");s.style.cssText="margin-top:.5rem; display:flex; flex-direction:column; gap:.4rem;";const t=de("Layout");t.body.appendChild(S([U(`fb-chooser-variant-${n}`,"Variant",e.variant||"card",[["card","Card \u2014 rich tiles"],["chip","Chip \u2014 compact pills"]],"Card supports description and grid columns; chips wrap."),pe(`fb-chooser-multiple-${n}`,"Multi-select",!!e.multiple,"Off = single (radio); on = multi (checkbox).")])),t.body.appendChild(S([U(`fb-chooser-density-${n}`,"Density",e.density||"comfortable",[["comfortable","Comfortable"],["compact","Compact"]],"Compact strips description (card variant only)."),k("Columns",`fb-chooser-columns-${n}`,"number",e.columns||3,"Card grid (1\u20136). Ignored for chips.")])),s.appendChild(t.wrap);const o=de("Visual");return o.body.appendChild(S([K(`fb-chooser-accent-${n}`,"Accent",e.accent||"","primary / success / #ec4899","Selected highlight colour \u2014 semantic name or any CSS colour."),U(`fb-chooser-accent-style-${n}`,"Accent style",e.accentStyle||"border",[["border","Border (default)"],["solid","Solid"],["glow","Glow"],["overlay","Overlay"],["underline","Underline"]],"Visual treatment of the selected state.")])),o.body.appendChild(S([pe(`fb-chooser-glow-${n}`,"Glow on selected",!!e.glow,"Soft outer glow."),K(`fb-chooser-glow-colour-${n}`,"Glow colour",e.glowColour||"","defaults to accent","Optional; semantic name or CSS colour.")])),o.body.appendChild(S([U(`fb-chooser-shadow-${n}`,"Shadow",e.shadow||"none",[["none","None"],["sm","Small"],["md","Medium"],["lg","Large"],["xl","Extra Large"]],"Drop shadow on every option."),K(`fb-chooser-shadow-colour-${n}`,"Shadow colour",e.shadowColour||"","rgba(0,0,0,0.1)","Optional shadow tint.")])),s.appendChild(o.wrap),s}function Ae(e,n,s,t){const o=document.createElement("div");o.className="fb-chooser-option-row",o.dataset.optIdx=String(s),o.style.cssText="border:1px solid var(--dm-border,#e5e7eb); border-radius:4px; padding:.5rem; background:var(--dm-background-alt, color-mix(in srgb, var(--dm-card-bg, #fff) 92%, var(--dm-text, #111))); display:flex; flex-direction:column; gap:.35rem;";const l=document.createElement("div");l.style.cssText="display:flex; gap:.4rem; align-items:center;";const i=document.createElement("div");i.style.cssText="display:flex; flex-direction:column; gap:1px;";const d=document.createElement("button");d.type="button",d.className="btn btn-xs btn-ghost",d.title="Move up",w(d,"arrow-up"),d.addEventListener("click",N=>{N.preventDefault(),me(n,s,-1,t)});const r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",r.title="Move down",w(r,"arrow-down"),r.addEventListener("click",N=>{N.preventDefault(),me(n,s,1,t)}),i.appendChild(d),i.appendChild(r),l.appendChild(i);const a=document.createElement("input");a.type="text",a.className="form-input fb-chooser-opt-value",a.placeholder="value",a.value=e.value||"",a.style.flex="1",l.appendChild(a);const p=document.createElement("input");p.type="text",p.className="form-input fb-chooser-opt-label",p.placeholder="label (visible to users)",p.value=e.label||"",p.style.flex="2",l.appendChild(p);const c=document.createElement("button");c.type="button",c.className="btn btn-xs btn-ghost",c.style.cssText="line-height:1;opacity:.6;",c.title="Remove option",w(c,"x"),c.addEventListener("click",N=>{N.preventDefault(),Oe(n,s,t)}),l.appendChild(c),o.appendChild(l);const u=document.createElement("div");u.style.cssText="display:flex; gap:.4rem;";const f=ge("icon name (optional)",e.icon||"");f.input.classList.add("fb-chooser-opt-icon"),f.el.style.flex="1",u.appendChild(f.el);const g=document.createElement("input");g.type="text",g.className="form-input fb-chooser-opt-description",g.placeholder="description (card + comfortable only)",g.value=e.description||"",g.style.flex="2",u.appendChild(g),o.appendChild(u);const b=document.createElement("div");b.style.cssText="display:flex; gap:.4rem;";const h=document.createElement("input");h.type="text",h.className="form-input fb-chooser-opt-tooltip",h.placeholder="tooltip (hover hint)",h.value=e.tooltip||"",h.style.flex="2",b.appendChild(h);const m=document.createElement("input");m.type="text",m.className="form-input fb-chooser-opt-badge-text",m.placeholder="badge text",m.value=e.badge?.text||"",m.style.flex="1",b.appendChild(m);const y=document.createElement("select");y.className="form-input fb-chooser-opt-badge-type",y.style.flex="1",[["","no badge"],["primary","primary"],["success","success"],["info","info"],["warning","warning"],["danger","danger"]].forEach(([N,O])=>{const _=document.createElement("option");_.value=N,_.textContent=O,(e.badge?.type||"")===N&&(_.selected=!0),y.appendChild(_)}),b.appendChild(y),o.appendChild(b);const x=document.createElement("div");x.style.cssText="display:flex; gap:1rem; font-size:.8rem;";const C=document.createElement("label");C.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const T=document.createElement("input");T.type="checkbox",T.className="fb-chooser-opt-recommended",T.checked=!!e.recommended,C.appendChild(T),C.appendChild(document.createTextNode(" Recommended")),x.appendChild(C);const z=document.createElement("label");z.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const A=document.createElement("input");return A.type="checkbox",A.className="fb-chooser-opt-disabled",A.checked=!!e.disabled,z.appendChild(A),z.appendChild(document.createTextNode(" Disabled")),x.appendChild(z),o.appendChild(x),o}function Ie(e,n){const s=document.createElement("div");s.style.cssText="margin-top:.5rem;";const t=document.createElement("div");t.style.cssText="display:flex; align-items:center; justify-content:space-between; margin-bottom:.4rem;";const o=document.createElement("p");o.textContent="Options",o.style.cssText="font-size:.85rem;font-weight:600;margin:0;",t.appendChild(o);const l=document.createElement("button");l.type="button",l.className="btn btn-xs btn-ghost",M(l,"plus","Add option"),t.appendChild(l),s.appendChild(t);const i=document.createElement("div");i.className="fb-chooser-options-list",i.id=`fb-chooser-options-${n}`,i.style.cssText="display:flex; flex-direction:column; gap:.4rem;",s.appendChild(i);const d=()=>{i.replaceChildren();const r=Be(n);(r.length?r:e||[]).forEach((p,c)=>{i.appendChild(Ae(p,n,c,d))})};return l.addEventListener("click",r=>{r.preventDefault(),Fe(n,d)}),d(),s}function Be(e){const n=v[e];return!n||!Array.isArray(n.options)?[]:n.options}function X(e){return v[e]?(Array.isArray(v[e].options)||(v[e].options=[]),v[e].options):[]}function Fe(e,n){J(e),X(e).push({value:"new",label:"New option"}),n()}function Oe(e,n,s){J(e),X(e).splice(n,1),s()}function me(e,n,s,t){J(e);const o=X(e),l=n+s;if(l<0||l>=o.length)return;const[i]=o.splice(n,1);o.splice(l,0,i),t()}function J(e){const n=document.getElementById(`fb-chooser-options-${e}`);if(!n)return;const s=n.querySelectorAll(".fb-chooser-option-row"),t=[];s.forEach(o=>{const l={value:o.querySelector(".fb-chooser-opt-value")?.value.trim()||"",label:o.querySelector(".fb-chooser-opt-label")?.value.trim()||""},i=o.querySelector(".fb-chooser-opt-icon")?.value.trim();i&&(l.icon=i);const d=o.querySelector(".fb-chooser-opt-description")?.value.trim();d&&(l.description=d);const r=o.querySelector(".fb-chooser-opt-tooltip")?.value.trim();r&&(l.tooltip=r);const a=o.querySelector(".fb-chooser-opt-badge-text")?.value.trim(),p=o.querySelector(".fb-chooser-opt-badge-type")?.value;(a||p)&&(l.badge={},a&&(l.badge.text=a),p&&(l.badge.type=p)),o.querySelector(".fb-chooser-opt-recommended")?.checked&&(l.recommended=!0),o.querySelector(".fb-chooser-opt-disabled")?.checked&&(l.disabled=!0),t.push(l)}),v[e]&&(v[e].options=t)}function S(e){const n=document.createElement("div");return n.style.cssText="display:flex;gap:.85rem;margin-bottom:.75rem;",e.forEach(s=>{s&&n.appendChild(s)}),n}function k(e,n,s,t,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=n,i.className="form-label",i.textContent=e,i.style.fontSize=".8rem";const d=document.createElement("input");if(d.id=n,d.type=s||"text",d.className="form-input",d.value=t??"",l.appendChild(i),l.appendChild(d),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.73rem;margin-top:.2rem;",l.appendChild(r)}return l}function _e(e,n,s,t){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.htmlFor=n,l.className="form-label",l.textContent=e,l.style.fontSize=".8rem";const i=document.createElement("select");return i.id=n,i.className="form-select",s.forEach(d=>{const r=document.createElement("option");r.value=d.value,r.textContent=d.label,d.value===t&&(r.selected=!0),i.appendChild(r)}),o.appendChild(l),o.appendChild(i),o}function ue(e,n,s){const t=document.createElement("div");t.style.cssText="flex:0;min-width:80px;display:flex;flex-direction:column;justify-content:flex-end;";const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.8rem;white-space:nowrap;";const l=document.createElement("input");return l.id=n,l.type="checkbox",l.checked=s,o.appendChild(l),o.appendChild(document.createTextNode(e)),t.appendChild(o),t}function je(e,n){const s=document.createElement("div");s.style.cssText="margin-top:.4rem;";const t=document.createElement("p");t.textContent="Options (one per line: value or value:Label)",t.style.cssText="font-size:.8rem;font-weight:600;margin-bottom:.3rem;";const o=document.createElement("textarea");return o.id=`fb-options-${n}`,o.className="form-input",o.rows=4,o.placeholder=`yes:Yes
5
+ `),t.appendChild(p),t.appendChild(c),t}function $e(e,n){const i=e.logic||{},t=v.filter((c,u)=>u!==n&&c.type!=="page-break"&&c.type!=="spacer"),o=document.createElement("div");o.className="fb-field-logic",o.style.cssText="margin-top:.75rem;border-top:1px solid var(--dm-border,#333);padding-top:.5rem;";const l=document.createElement("div");l.style.cssText="display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:.15rem 0;";const s=document.createElement("span");s.style.cssText="font-size:.8rem;font-weight:600;color:var(--dm-text-muted,#888);",s.textContent="\u26A1 Conditional Logic";const d=oe(i),r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",w(r,d?"chevron-down":"chevron-right",12);const a=document.createElement("div");a.className="fb-logic-body",a.style.cssText="padding:.25rem 0 .25rem;"+(d?"":"display:none;"),l.addEventListener("click",()=>{const c=a.style.display==="none";a.style.display=c?"":"none",w(r,c?"chevron-down":"chevron-right",12)}),l.appendChild(s),l.appendChild(r),o.appendChild(l),a.appendChild(Te(i.visibility||{},n,t)),a.appendChild(Ne(i.requirement||{},n,t)),a.appendChild(qe(i.validation||[],n,t));const p=document.getElementById(`fb-type-${n}`)?.value||e.type;return G.has(p)&&a.appendChild(Le(i.cascade||{},n,t)),o.appendChild(a),o}function re(e,n,i){const t=document.createElement("div");return t.className="fb-field-extras",e==="chooser"?(t.appendChild(Fe(n,i)),t.appendChild(Ie(n.options||[],i))):(G.has(e)&&t.appendChild(Pe(n.options||[],i)),e==="textarea"&&t.appendChild(S([k("Rows",`fb-rows-${i}`,"number",n.formConfig?.rows||4,"Height of textarea")])),(e==="string"||e==="textarea")&&t.appendChild(S([k("Min Length",`fb-minlength-${i}`,"number",n.minLength||"",""),k("Max Length",`fb-maxlength-${i}`,"number",n.maxLength||"","")])),e==="number"&&t.appendChild(S([k("Min",`fb-min-${i}`,"number",n.min??"",""),k("Max",`fb-max-${i}`,"number",n.max??"","")]))),t.children.length?t:null}function de(e){const n=document.createElement("div");n.className="fb-chooser-section",n.style.cssText="border:1px solid var(--dm-border, #e5e7eb); border-radius:6px; margin-top:.5rem; overflow:hidden;";const i=document.createElement("div");i.style.cssText="padding:.4rem .6rem; background:color-mix(in srgb, var(--dm-background, #f9fafb) 60%, transparent); font-weight:600; font-size:.82rem; border-bottom:1px solid var(--dm-border, #e5e7eb);",i.textContent=e,n.appendChild(i);const t=document.createElement("div");return t.className="fb-chooser-section-body",t.style.cssText="padding:.55rem .6rem; display:flex; flex-direction:column; gap:.45rem;",n.appendChild(t),{wrap:n,body:t}}function U(e,n,i,t,o){const l=document.createElement("div");l.style.flex="1";const s=document.createElement("label");s.htmlFor=e,s.className="form-label",s.textContent=n,s.style.fontSize=".8rem";const d=document.createElement("select");if(d.id=e,d.className="form-input",t.forEach(([r,a])=>{const p=document.createElement("option");p.value=r,p.textContent=a,String(r)===String(i)&&(p.selected=!0),d.appendChild(p)}),l.appendChild(s),l.appendChild(d),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(r)}return l}function pe(e,n,i,t){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.style.cssText="display:inline-flex;align-items:center;gap:.4rem;font-size:.82rem;";const s=document.createElement("input");if(s.id=e,s.type="checkbox",s.checked=!!i,l.appendChild(s),l.appendChild(document.createTextNode(" "+n)),o.appendChild(l),t){const d=document.createElement("p");d.className="form-hint text-muted",d.textContent=t,d.style.cssText="font-size:.72rem;margin-top:.2rem;",o.appendChild(d)}return o}function X(e,n,i,t,o){const l=document.createElement("div");l.style.flex="1";const s=document.createElement("label");s.htmlFor=e,s.className="form-label",s.textContent=n,s.style.fontSize=".8rem",l.appendChild(s);const d=document.createElement("div");d.style.cssText="display:flex;gap:.4rem;align-items:stretch;";const r=document.createElement("input");r.id=e,r.type="text",r.className="form-input",r.value=i||"",t&&(r.placeholder=t),r.style.flex="1";const a=document.createElement("input");a.type="color",a.title="Pick a colour",a.style.cssText="width:36px;height:auto;padding:0;border:1px solid var(--dm-border,#e5e7eb);border-radius:4px;cursor:pointer;";const p=String(r.value).match(/^#[0-9a-fA-F]{3,8}$/);if(a.value=p?r.value:"#000000",a.addEventListener("input",()=>{r.value=a.value,r.dispatchEvent(new Event("input",{bubbles:!0}))}),d.appendChild(r),d.appendChild(a),l.appendChild(d),o){const c=document.createElement("p");c.className="form-hint text-muted",c.textContent=o,c.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(c)}return l}function Fe(e,n){const i=document.createElement("div");i.style.cssText="margin-top:.5rem; display:flex; flex-direction:column; gap:.4rem;";const t=de("Layout");t.body.appendChild(S([U(`fb-chooser-variant-${n}`,"Variant",e.variant||"card",[["card","Card \u2014 rich tiles"],["chip","Chip \u2014 compact pills"]],"Card supports description and grid columns; chips wrap."),pe(`fb-chooser-multiple-${n}`,"Multi-select",!!e.multiple,"Off = single (radio); on = multi (checkbox).")])),t.body.appendChild(S([U(`fb-chooser-density-${n}`,"Density",e.density||"comfortable",[["comfortable","Comfortable"],["compact","Compact"]],"Compact strips description (card variant only)."),k("Columns",`fb-chooser-columns-${n}`,"number",e.columns||3,"Card grid (1\u20136). Ignored for chips.")])),i.appendChild(t.wrap);const o=de("Visual");return o.body.appendChild(S([X(`fb-chooser-accent-${n}`,"Accent",e.accent||"","primary / success / #ec4899","Selected highlight colour \u2014 semantic name or any CSS colour."),U(`fb-chooser-accent-style-${n}`,"Accent style",e.accentStyle||"border",[["border","Border (default)"],["solid","Solid"],["glow","Glow"],["overlay","Overlay"],["underline","Underline"]],"Visual treatment of the selected state.")])),o.body.appendChild(S([pe(`fb-chooser-glow-${n}`,"Glow on selected",!!e.glow,"Soft outer glow."),X(`fb-chooser-glow-colour-${n}`,"Glow colour",e.glowColour||"","defaults to accent","Optional; semantic name or CSS colour.")])),o.body.appendChild(S([U(`fb-chooser-shadow-${n}`,"Shadow",e.shadow||"none",[["none","None"],["sm","Small"],["md","Medium"],["lg","Large"],["xl","Extra Large"]],"Drop shadow on every option."),X(`fb-chooser-shadow-colour-${n}`,"Shadow colour",e.shadowColour||"","rgba(0,0,0,0.1)","Optional shadow tint.")])),i.appendChild(o.wrap),i}function ze(e,n,i,t){const o=document.createElement("div");o.className="fb-chooser-option-row",o.dataset.optIdx=String(i),o.style.cssText="border:1px solid var(--dm-border,#e5e7eb); border-radius:4px; padding:.5rem; background:var(--dm-background-alt, color-mix(in srgb, var(--dm-card-bg, #fff) 92%, var(--dm-text, #111))); display:flex; flex-direction:column; gap:.35rem;";const l=document.createElement("div");l.style.cssText="display:flex; gap:.4rem; align-items:center;";const s=document.createElement("div");s.style.cssText="display:flex; flex-direction:column; gap:1px;";const d=document.createElement("button");d.type="button",d.className="btn btn-xs btn-ghost",d.title="Move up",w(d,"arrow-up"),d.addEventListener("click",N=>{N.preventDefault(),me(n,i,-1,t)});const r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",r.title="Move down",w(r,"arrow-down"),r.addEventListener("click",N=>{N.preventDefault(),me(n,i,1,t)}),s.appendChild(d),s.appendChild(r),l.appendChild(s);const a=document.createElement("input");a.type="text",a.className="form-input fb-chooser-opt-value",a.placeholder="value",a.value=e.value||"",a.style.flex="1",l.appendChild(a);const p=document.createElement("input");p.type="text",p.className="form-input fb-chooser-opt-label",p.placeholder="label (visible to users)",p.value=e.label||"",p.style.flex="2",l.appendChild(p);const c=document.createElement("button");c.type="button",c.className="btn btn-xs btn-ghost",c.style.cssText="line-height:1;opacity:.6;",c.title="Remove option",w(c,"x"),c.addEventListener("click",N=>{N.preventDefault(),Oe(n,i,t)}),l.appendChild(c),o.appendChild(l);const u=document.createElement("div");u.style.cssText="display:flex; gap:.4rem;";const f=ge("icon name (optional)",e.icon||"");f.input.classList.add("fb-chooser-opt-icon"),f.el.style.flex="1",u.appendChild(f.el);const g=document.createElement("input");g.type="text",g.className="form-input fb-chooser-opt-description",g.placeholder="description (card + comfortable only)",g.value=e.description||"",g.style.flex="2",u.appendChild(g),o.appendChild(u);const b=document.createElement("div");b.style.cssText="display:flex; gap:.4rem;";const h=document.createElement("input");h.type="text",h.className="form-input fb-chooser-opt-tooltip",h.placeholder="tooltip (hover hint)",h.value=e.tooltip||"",h.style.flex="2",b.appendChild(h);const m=document.createElement("input");m.type="text",m.className="form-input fb-chooser-opt-badge-text",m.placeholder="badge text",m.value=e.badge?.text||"",m.style.flex="1",b.appendChild(m);const y=document.createElement("select");y.className="form-input fb-chooser-opt-badge-type",y.style.flex="1",[["","no badge"],["primary","primary"],["success","success"],["info","info"],["warning","warning"],["danger","danger"]].forEach(([N,O])=>{const _=document.createElement("option");_.value=N,_.textContent=O,(e.badge?.type||"")===N&&(_.selected=!0),y.appendChild(_)}),b.appendChild(y),o.appendChild(b);const x=document.createElement("div");x.style.cssText="display:flex; gap:1rem; font-size:.8rem;";const C=document.createElement("label");C.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const T=document.createElement("input");T.type="checkbox",T.className="fb-chooser-opt-recommended",T.checked=!!e.recommended,C.appendChild(T),C.appendChild(document.createTextNode(" Recommended")),x.appendChild(C);const z=document.createElement("label");z.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const I=document.createElement("input");return I.type="checkbox",I.className="fb-chooser-opt-disabled",I.checked=!!e.disabled,z.appendChild(I),z.appendChild(document.createTextNode(" Disabled")),x.appendChild(z),o.appendChild(x),o}function Ie(e,n){const i=document.createElement("div");i.style.cssText="margin-top:.5rem;";const t=document.createElement("div");t.style.cssText="display:flex; align-items:center; justify-content:space-between; margin-bottom:.4rem;";const o=document.createElement("p");o.textContent="Options",o.style.cssText="font-size:.85rem;font-weight:600;margin:0;",t.appendChild(o);const l=document.createElement("button");l.type="button",l.className="btn btn-xs btn-ghost",j(l,"plus","Add option"),t.appendChild(l),i.appendChild(t);const s=document.createElement("div");s.className="fb-chooser-options-list",s.id=`fb-chooser-options-${n}`,s.style.cssText="display:flex; flex-direction:column; gap:.4rem;",i.appendChild(s);const d=()=>{s.replaceChildren();const r=Be(n);(r.length?r:e||[]).forEach((p,c)=>{s.appendChild(ze(p,n,c,d))})};return l.addEventListener("click",r=>{r.preventDefault(),Ae(n,d)}),d(),i}function Be(e){const n=v[e];return!n||!Array.isArray(n.options)?[]:n.options}function K(e){return v[e]?(Array.isArray(v[e].options)||(v[e].options=[]),v[e].options):[]}function Ae(e,n){W(e),K(e).push({value:"new",label:"New option"}),n()}function Oe(e,n,i){W(e),K(e).splice(n,1),i()}function me(e,n,i,t){W(e);const o=K(e),l=n+i;if(l<0||l>=o.length)return;const[s]=o.splice(n,1);o.splice(l,0,s),t()}function W(e){const n=document.getElementById(`fb-chooser-options-${e}`);if(!n)return;const i=n.querySelectorAll(".fb-chooser-option-row"),t=[];i.forEach(o=>{const l={value:o.querySelector(".fb-chooser-opt-value")?.value.trim()||"",label:o.querySelector(".fb-chooser-opt-label")?.value.trim()||""},s=o.querySelector(".fb-chooser-opt-icon")?.value.trim();s&&(l.icon=s);const d=o.querySelector(".fb-chooser-opt-description")?.value.trim();d&&(l.description=d);const r=o.querySelector(".fb-chooser-opt-tooltip")?.value.trim();r&&(l.tooltip=r);const a=o.querySelector(".fb-chooser-opt-badge-text")?.value.trim(),p=o.querySelector(".fb-chooser-opt-badge-type")?.value;(a||p)&&(l.badge={},a&&(l.badge.text=a),p&&(l.badge.type=p)),o.querySelector(".fb-chooser-opt-recommended")?.checked&&(l.recommended=!0),o.querySelector(".fb-chooser-opt-disabled")?.checked&&(l.disabled=!0),t.push(l)}),v[e]&&(v[e].options=t)}function S(e){const n=document.createElement("div");return n.style.cssText="display:flex;gap:.85rem;margin-bottom:.75rem;",e.forEach(i=>{i&&n.appendChild(i)}),n}function k(e,n,i,t,o){const l=document.createElement("div");l.style.flex="1";const s=document.createElement("label");s.htmlFor=n,s.className="form-label",s.textContent=e,s.style.fontSize=".8rem";const d=document.createElement("input");if(d.id=n,d.type=i||"text",d.className="form-input",d.value=t??"",l.appendChild(s),l.appendChild(d),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.73rem;margin-top:.2rem;",l.appendChild(r)}return l}function _e(e,n,i,t){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.htmlFor=n,l.className="form-label",l.textContent=e,l.style.fontSize=".8rem";const s=document.createElement("select");return s.id=n,s.className="form-select",i.forEach(d=>{const r=document.createElement("option");r.value=d.value,r.textContent=d.label,d.value===t&&(r.selected=!0),s.appendChild(r)}),o.appendChild(l),o.appendChild(s),o}function ue(e,n,i){const t=document.createElement("div");t.style.cssText="flex:0;min-width:80px;display:flex;flex-direction:column;justify-content:flex-end;";const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.8rem;white-space:nowrap;";const l=document.createElement("input");return l.id=n,l.type="checkbox",l.checked=i,o.appendChild(l),o.appendChild(document.createTextNode(e)),t.appendChild(o),t}function Pe(e,n){const i=document.createElement("div");i.style.cssText="margin-top:.4rem;";const t=document.createElement("p");t.textContent="Options (one per line: value or value:Label)",t.style.cssText="font-size:.8rem;font-weight:600;margin-bottom:.3rem;";const o=document.createElement("textarea");return o.id=`fb-options-${n}`,o.className="form-input",o.rows=4,o.placeholder=`yes:Yes
6
6
  no:No
7
- maybe:Maybe`,o.value=(e||[]).map(l=>{const i=typeof l=="string"?l:l.value??"",d=typeof l=="string"?l:l.label??i;return i===d?i:`${i}:${d}`}).join(`
8
- `),o.style.fontFamily="monospace",s.appendChild(t),s.appendChild(o),s}function fe(e){const n=e.find("#field-project").val()||"";return L(),{title:e.find("#field-title").val().trim(),slug:e.find("#field-slug").val().trim(),description:e.find("#field-description").val().trim(),...e.find("#field-bundled").is(":checked")?{bundled:!0}:{},meta:{...G||{},project:n||null},fields:v,settings:{submitText:e.find("#setting-submit-text").val().trim()||"Submit",successMessage:e.find("#setting-success-message").val().trim()||"Thank you.",layout:e.find("#setting-layout").val()||"stacked",columns:parseInt(e.find("#setting-columns").val(),10)||2,submitSpan:e.find("#setting-submit-span").val()||"",honeypot:e.find("#setting-honeypot").prop("checked"),rateLimitPerMinute:parseInt(e.find("#setting-rate-limit").val(),10)||3,successRedirect:e.find("#setting-success-redirect").val().trim()||null,actionSlug:e.find("#action-cms-slug").val()||null},actions:{email:{enabled:e.find("#action-email-enabled").prop("checked"),recipients:e.find("#action-email-recipients").val().trim(),subjectPrefix:e.find("#action-email-subject-prefix").val().trim()},webhook:{enabled:e.find("#action-webhook-enabled").prop("checked"),url:e.find("#action-webhook-url").val().trim(),method:e.find("#action-webhook-method").val()},...j!==null&&{collection:j}}}}function Pe(e){const n=[];let s=[],t="Step 1",o="";return e.forEach(l=>{l.type==="page-break"?(n.push({title:t,description:o,fields:s}),s=[],t=l.label||`Step ${n.length+1}`,o=l.description||""):l.type!=="spacer"&&s.push(l)}),(s.length||n.length===0)&&n.push({title:t,description:o,fields:s}),n}function he(e,n){const s={};return e.forEach(t=>{if(t.type==="page-break"||t.type==="spacer")return;const o={...t.formConfig||{}};o.span==="full"&&n&&(o.span=n);const l=t.type==="chooser"||!!(t.variant&&["select","radio","checkbox-group"].includes(t.type)),d={type:t.type==="checkbox"?"boolean":t.type==="date"||t.type==="icon"||t.type==="image"?"string":l?"chooser":t.type,label:t.label,required:t.required,options:t.options,formConfig:{...t.placeholder&&{placeholder:t.placeholder},...t.helper&&{helperText:t.helper},...t.tooltip&&{tooltip:t.tooltip},...o}};l&&(t.variant&&(d.variant=t.variant),(t.multiple||t.type==="checkbox-group")&&(d.multiple=!0),t.density&&(d.density=t.density),t.columns&&(d.columns=t.columns),t.accent&&(d.accent=t.accent),t.accentStyle&&(d.accentStyle=t.accentStyle),t.glow&&(d.glow=!0),t.glowColour&&(d.glowColour=t.glowColour),t.shadow&&(d.shadow=t.shadow),t.shadowColour&&(d.shadowColour=t.shadowColour)),s[t.name]=d}),s}function be(e,n){const s=typeof e=="string"?document.querySelector(e):e;s&&(n||[]).forEach(t=>{if(t.type!=="date"||!t.name)return;const o=s.querySelector(`[name="${t.name}"]`);o&&o.type!=="date"&&(o.type="date")})}export const formEditorView={templateUrl:"/admin/js/templates/form-editor.html",async onMount(e){v=[],q=null,j=null;const n=window.location.hash.match(/\/forms\/edit\/([^/?#]+)/);q=n?n[1]:null;let s=null;const t=E.loader(e.get(0),{type:"dots"});if(q)try{s=await B(`/forms/${q}`),v=s.fields||[],j=s.actions?.collection??null}catch{E.toast("Could not load form.",{type:"error"})}G={};try{const a=await B("/projects").catch(()=>[]),p=e.find("#field-project").get(0);p&&(Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.name||c.slug,p.appendChild(u)})}catch{}if(t.destroy(),s?e.find("#editor-title").get(0).textContent=`Edit: ${s.title}`:e.find("#editor-title").get(0).textContent="New Form",q||e.find("#field-title").get(0).addEventListener("input",function(){e.find("#field-slug").val(ne(this.value))}),E.tabs(e.find("#editor-tabs").get(0)),s){e.find("#field-title").val(s.title),e.find("#field-slug").val(s.slug),e.find("#field-description").val(s.description||""),e.find("#field-bundled").prop("checked",!!s.bundled),G=s.meta||{},e.find("#field-project").val(s.meta?.project||"");const a=s.settings||{};e.find("#setting-submit-text").val(a.submitText||"Submit"),e.find("#setting-success-message").val(a.successMessage||""),e.find("#setting-layout").val(a.layout||"stacked"),e.find("#setting-columns").val(a.columns||2),e.find("#setting-submit-span").val(a.submitSpan||""),e.find("#columns-group").get(0).style.display=a.layout==="grid"?"":"none",e.find("#setting-honeypot").prop("checked",a.honeypot!==!1),e.find("#setting-rate-limit").val(a.rateLimitPerMinute||3),e.find("#setting-success-redirect").val(a.successRedirect||"");const p=s.actions?.email||{};e.find("#action-email-enabled").prop("checked",p.enabled||!1),e.find("#action-email-recipients").val(p.recipients||""),e.find("#action-email-subject-prefix").val(p.subjectPrefix||"");const c=s.actions?.webhook||{};e.find("#action-webhook-enabled").prop("checked",c.enabled||!1),e.find("#action-webhook-url").val(c.url||""),e.find("#action-webhook-method").val(c.method||"POST")}const o=s?.settings?.actionSlug||"";try{const a=await B("/actions").catch(()=>[]),p=e.find("#action-cms-slug").get(0);if((Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.title||c.slug,c.slug===o&&(u.selected=!0),p.appendChild(u)}),!a.length){const c=document.createElement("option");c.value="",c.textContent="No actions available",c.disabled=!0,p.appendChild(c)}}catch{}e.find("#setting-layout").get(0)?.addEventListener("change",function(){const a=this.value==="grid";e.find("#columns-group").get(0).style.display=a?"":"none",document.querySelectorAll(".fb-grid-row").forEach(p=>{p.style.display=a?"flex":"none"})}),$(e);const l=e.find("#add-element-menu").get(0);e.find("#add-element-btn").get(0).addEventListener("click",a=>{a.stopPropagation(),l.style.display=l.style.display==="none"?"":"none"}),P&&document.removeEventListener("click",P),P=()=>{l&&(l.style.display="none")},document.addEventListener("click",P),e.find("#add-field-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),L();const a=v.length;v.push({name:`field_${a+1}`,type:"string",label:"New Field",required:!1,placeholder:""}),$(e);const p=e.find("#fields-list").get(0)?.lastElementChild;if(p){const c=p.querySelector(".fb-field-body");c&&(c.style.display="")}}),e.find("#add-spacer-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),L(),v.push({type:"spacer"}),$(e)}),e.find("#add-page-break-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),L();const a=v.filter(p=>p.type==="page-break").length+2;v.push({type:"page-break",label:`Step ${a}`,description:""}),$(e)}),e.find("#save-form-btn").get(0).addEventListener("click",async()=>{const a=fe(e);if(!a.title){E.toast("Please enter a form title.",{type:"error"});return}try{q?(await B(`/forms/${q}`,{method:"PUT",body:JSON.stringify(a)}),E.toast("Form saved.",{type:"success"})):(q=(await B("/forms",{method:"POST",body:JSON.stringify(a)})).slug,R.navigate(`/forms/edit/${q}`),E.toast("Form created.",{type:"success"}))}catch(p){E.toast(p.message||"Failed to save form.",{type:"error"})}}),D=()=>{const a=fe(e),p=e.find("#preview-container").get(0);if(!p)return;const c=e.find("#preview-test-result").get(0),u=e.find("#preview-test-badge").get(0);c&&(c.style.display="none",c.textContent=""),u&&(u.style.display=q?"":"none"),e.find("#preview-card").get(0).style.display="",p.textContent="";const f=document.createElement("div");f.id="fb-preview-form",p.appendChild(f);const g=q?async h=>{c&&(c.style.display="none",c.textContent="");try{const m=await fetch(`/api/forms/submit/${q}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)}),y=await m.json();if(!m.ok)throw new Error(y.error||"Submission failed.");c&&(c.textContent=y.message||a.settings?.successMessage||"Submitted successfully.",c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-success) 12%, transparent);color:var(--dm-success,#22c55e);"),E.toast("Test submission stored.",{type:"success"})}catch(m){c&&(c.textContent=m.message,c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-danger) 12%, transparent);color:var(--dm-danger,#ef4444);"),E.toast(m.message,{type:"error"})}return!1}:()=>!1,b=a.fields.some(h=>h.type==="page-break");if(typeof F<"u"){const h=a.settings?.columns||2,m=a.settings?.layout||"stacked";if(b&&F.wizard){const y=Pe(a.fields).map(x=>({title:x.title,description:x.description,fields:he(x.fields,h)}));F.wizard("#fb-preview-form",{schema:{steps:y},onSubmit:g}),be("#fb-preview-form",a.fields),Z(f,a.fields)}else if(F.render){const y=he(a.fields,h),x={};if(a.fields.forEach(C=>{if(!(!C.name||C.type==="page-break"||C.type==="spacer")&&(C.type==="select"||C.type==="multiselect")&&C.required){const T=(C.options||[])[0];T&&(x[C.name]=typeof T=="object"?T.value:T)}}),F.render("#fb-preview-form",y,x,{submitText:a.settings?.submitText||"Submit",layout:m,columns:h,onSubmit:g}),m==="grid"&&a.settings?.submitSpan==="full"){const C=document.querySelector("#fb-preview-form .form-buttons");C&&C.classList.add("col-span-full")}be("#fb-preview-form",a.fields),Z(f,a.fields)}window.FormLogicEngine&&a.fields.some(y=>y.logic)&&requestAnimationFrame(()=>{new window.FormLogicEngine.FormLogicRuntime({fields:a.fields},f).init()})}else{const h=document.createElement("p");h.textContent=`${a.fields.filter(m=>m.type!=="page-break").length} field(s): ${a.fields.filter(m=>m.type!=="page-break").map(m=>m.label).join(", ")}`,h.style.cssText="color:var(--dm-text-muted);font-style:italic;",f.appendChild(h)}},D();const i=e.find("#editor-tabs").get(0),d=e.find("#preview-card").get(0),r=a=>{d&&d.contains(a.target)||Y()};i&&(i.addEventListener("input",r),i.addEventListener("change",r))}};
7
+ maybe:Maybe`,o.value=(e||[]).map(l=>{const s=typeof l=="string"?l:l.value??"",d=typeof l=="string"?l:l.label??s;return s===d?s:`${s}:${d}`}).join(`
8
+ `),o.style.fontFamily="monospace",i.appendChild(t),i.appendChild(o),i}function fe(e){const n=e.find("#field-project").val()||"";return L(),{title:e.find("#field-title").val().trim(),slug:e.find("#field-slug").val().trim(),description:e.find("#field-description").val().trim(),...e.find("#field-bundled").is(":checked")?{bundled:!0}:{},meta:{...J||{},project:n||null},fields:v,settings:{submitText:e.find("#setting-submit-text").val().trim()||"Submit",successMessage:e.find("#setting-success-message").val().trim()||"Thank you.",layout:e.find("#setting-layout").val()||"stacked",columns:parseInt(e.find("#setting-columns").val(),10)||2,submitSpan:e.find("#setting-submit-span").val()||"",honeypot:e.find("#setting-honeypot").prop("checked"),rateLimitPerMinute:parseInt(e.find("#setting-rate-limit").val(),10)||3,successRedirect:e.find("#setting-success-redirect").val().trim()||null,actionSlug:e.find("#action-cms-slug").val()||null},actions:{email:{enabled:e.find("#action-email-enabled").prop("checked"),recipients:e.find("#action-email-recipients").val().trim(),subjectPrefix:e.find("#action-email-subject-prefix").val().trim()},webhook:{enabled:e.find("#action-webhook-enabled").prop("checked"),url:e.find("#action-webhook-url").val().trim(),method:e.find("#action-webhook-method").val()},...P!==null&&{collection:P}}}}function Me(e){const n=[];let i=[],t="Step 1",o="";return e.forEach(l=>{l.type==="page-break"?(n.push({title:t,description:o,fields:i}),i=[],t=l.label||`Step ${n.length+1}`,o=l.description||""):l.type!=="spacer"&&i.push(l)}),(i.length||n.length===0)&&n.push({title:t,description:o,fields:i}),n}function he(e,n){const i={};return e.forEach(t=>{if(t.type==="page-break"||t.type==="spacer")return;const o={...t.formConfig||{}};o.span==="full"&&n&&(o.span=n);const l=t.type==="chooser"||!!(t.variant&&["select","radio","checkbox-group"].includes(t.type)),d={type:t.type==="checkbox"?"boolean":t.type==="date"||t.type==="icon"||t.type==="image"?"string":l?"chooser":t.type,label:t.label,required:t.required,options:t.options,formConfig:{...t.placeholder&&{placeholder:t.placeholder},...t.helper&&{helperText:t.helper},...t.tooltip&&{tooltip:t.tooltip},...o}};l&&(t.variant&&(d.variant=t.variant),(t.multiple||t.type==="checkbox-group")&&(d.multiple=!0),t.density&&(d.density=t.density),t.columns&&(d.columns=t.columns),t.accent&&(d.accent=t.accent),t.accentStyle&&(d.accentStyle=t.accentStyle),t.glow&&(d.glow=!0),t.glowColour&&(d.glowColour=t.glowColour),t.shadow&&(d.shadow=t.shadow),t.shadowColour&&(d.shadowColour=t.shadowColour)),i[t.name]=d}),i}function be(e,n){const i=typeof e=="string"?document.querySelector(e):e;i&&(n||[]).forEach(t=>{if(t.type!=="date"||!t.name)return;const o=i.querySelector(`[name="${t.name}"]`);o&&o.type!=="date"&&(o.type="date")})}export const formEditorView={templateUrl:"/admin/js/templates/form-editor.html",async onMount(e){v=[],q=null,P=null;const n=window.location.hash.match(/\/forms\/edit\/([^/?#]+)/);q=n?n[1]:null;let i=null;const t=E.loader(e.get(0),{type:"dots"});if(q)try{i=await A(`/forms/${q}`),v=i.fields||[],P=i.actions?.collection??null}catch{E.toast("Could not load form.",{type:"error"})}J={};try{const a=await A("/projects").catch(()=>[]),p=e.find("#field-project").get(0);p&&(Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.name||c.slug,p.appendChild(u)})}catch{}if(t.destroy(),i?e.find("#editor-title").get(0).textContent=`Edit: ${i.title}`:e.find("#editor-title").get(0).textContent="New Form",q||e.find("#field-title").get(0).addEventListener("input",function(){e.find("#field-slug").val(ne(this.value))}),E.tabs(e.find("#editor-tabs").get(0)),i){e.find("#field-title").val(i.title),e.find("#field-slug").val(i.slug),e.find("#field-description").val(i.description||""),e.find("#field-bundled").prop("checked",!!i.bundled),J=i.meta||{},e.find("#field-project").val(i.meta?.project||"");const a=i.settings||{};e.find("#setting-submit-text").val(a.submitText||"Submit"),e.find("#setting-success-message").val(a.successMessage||""),e.find("#setting-layout").val(a.layout||"stacked"),e.find("#setting-columns").val(a.columns||2),e.find("#setting-submit-span").val(a.submitSpan||""),e.find("#columns-group").get(0).style.display=a.layout==="grid"?"":"none",e.find("#setting-honeypot").prop("checked",a.honeypot!==!1),e.find("#setting-rate-limit").val(a.rateLimitPerMinute||3),e.find("#setting-success-redirect").val(a.successRedirect||"");const p=i.actions?.email||{};e.find("#action-email-enabled").prop("checked",p.enabled||!1),e.find("#action-email-recipients").val(p.recipients||""),e.find("#action-email-subject-prefix").val(p.subjectPrefix||"");const c=i.actions?.webhook||{};e.find("#action-webhook-enabled").prop("checked",c.enabled||!1),e.find("#action-webhook-url").val(c.url||""),e.find("#action-webhook-method").val(c.method||"POST")}const o=i?.settings?.actionSlug||"";try{const a=await A("/actions").catch(()=>[]),p=e.find("#action-cms-slug").get(0);if((Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.title||c.slug,c.slug===o&&(u.selected=!0),p.appendChild(u)}),!a.length){const c=document.createElement("option");c.value="",c.textContent="No actions available",c.disabled=!0,p.appendChild(c)}}catch{}e.find("#setting-layout").get(0)?.addEventListener("change",function(){const a=this.value==="grid";e.find("#columns-group").get(0).style.display=a?"":"none",document.querySelectorAll(".fb-grid-row").forEach(p=>{p.style.display=a?"flex":"none"})}),$(e);const l=e.find("#add-element-menu").get(0);e.find("#add-element-btn").get(0).addEventListener("click",a=>{a.stopPropagation(),l.style.display=l.style.display==="none"?"":"none"}),M&&document.removeEventListener("click",M),M=()=>{l&&(l.style.display="none")},document.addEventListener("click",M),e.find("#add-field-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),L();const a=v.length;v.push({name:`field_${a+1}`,type:"string",label:"New Field",required:!1,placeholder:""}),$(e);const p=e.find("#fields-list").get(0)?.lastElementChild;if(p){const c=p.querySelector(".fb-field-body");c&&(c.style.display="")}}),e.find("#add-spacer-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),L(),v.push({type:"spacer"}),$(e)}),e.find("#add-page-break-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),L();const a=v.filter(p=>p.type==="page-break").length+2;v.push({type:"page-break",label:`Step ${a}`,description:""}),$(e)}),e.find("#save-form-btn").get(0).addEventListener("click",async()=>{const a=fe(e);if(!a.title){E.toast("Please enter a form title.",{type:"error"});return}try{q?(await A(`/forms/${q}`,{method:"PUT",body:JSON.stringify(a)}),E.toast("Form saved.",{type:"success"})):(q=(await A("/forms",{method:"POST",body:JSON.stringify(a)})).slug,R.navigate(`/forms/edit/${q}`),E.toast("Form created.",{type:"success"}))}catch(p){E.toast(p.message||"Failed to save form.",{type:"error"})}}),D=()=>{const a=fe(e),p=e.find("#preview-container").get(0);if(!p)return;const c=e.find("#preview-test-result").get(0),u=e.find("#preview-test-badge").get(0);c&&(c.style.display="none",c.textContent=""),u&&(u.style.display=q?"":"none"),e.find("#preview-card").get(0).style.display="",p.textContent="";const f=document.createElement("div");f.id="fb-preview-form",p.appendChild(f);const g=q?async h=>{c&&(c.style.display="none",c.textContent="");try{const m=await fetch(`/api/forms/submit/${q}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)}),y=await m.json();if(!m.ok)throw new Error(y.error||"Submission failed.");c&&(c.textContent=y.message||a.settings?.successMessage||"Submitted successfully.",c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-success) 12%, transparent);color:var(--dm-success,#22c55e);"),E.toast("Test submission stored.",{type:"success"})}catch(m){c&&(c.textContent=m.message,c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-danger) 12%, transparent);color:var(--dm-danger,#ef4444);"),E.toast(m.message,{type:"error"})}return!1}:()=>!1,b=a.fields.some(h=>h.type==="page-break");if(typeof F<"u"){const h=a.settings?.columns||2,m=a.settings?.layout||"stacked";if(b&&F.wizard){const y=Me(a.fields).map(x=>({title:x.title,description:x.description,fields:he(x.fields,h)}));F.wizard("#fb-preview-form",{schema:{steps:y},onSubmit:g}),be("#fb-preview-form",a.fields),Z(f,a.fields)}else if(F.render){const y=he(a.fields,h),x={};if(a.fields.forEach(C=>{if(!(!C.name||C.type==="page-break"||C.type==="spacer")&&(C.type==="select"||C.type==="multiselect")&&C.required){const T=(C.options||[])[0];T&&(x[C.name]=typeof T=="object"?T.value:T)}}),F.render("#fb-preview-form",y,x,{submitText:a.settings?.submitText||"Submit",layout:m,columns:h,onSubmit:g}),m==="grid"&&a.settings?.submitSpan==="full"){const C=document.querySelector("#fb-preview-form .form-buttons");C&&C.classList.add("col-span-full")}be("#fb-preview-form",a.fields),Z(f,a.fields)}window.FormLogicEngine&&a.fields.some(y=>y.logic)&&requestAnimationFrame(()=>{new window.FormLogicEngine.FormLogicRuntime({fields:a.fields},f).init()})}else{const h=document.createElement("p");h.textContent=`${a.fields.filter(m=>m.type!=="page-break").length} field(s): ${a.fields.filter(m=>m.type!=="page-break").map(m=>m.label).join(", ")}`,h.style.cssText="color:var(--dm-text-muted);font-style:italic;",f.appendChild(h)}},D();const s=e.find("#editor-tabs").get(0),d=e.find("#preview-card").get(0),r=a=>{d&&d.contains(a.target)||Q()};s&&(s.addEventListener("input",r),s.addEventListener("change",r))}};
@@ -1,23 +1,23 @@
1
- import{api as x}from"../api.js";let k=1;const v=n=>String(n||"").replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;");function S(n){const a=[];return(n||[]).forEach(l=>{const o=k++;a.push({_id:o,text:l.text||"",url:l.url||"",icon:l.icon||"",hidden:l.hidden||!1,bundled:l.bundled||!1,parentId:null}),(l.items||l.children||[]).forEach(e=>{a.push({_id:k++,text:e.text||"",url:e.url||"",icon:e.icon||"",hidden:e.hidden||!1,bundled:e.bundled||!1,parentId:o})})}),a}function B(n){return n.filter(a=>a.parentId===null).map(a=>{const l=n.filter(e=>e.parentId===a._id).map(e=>({text:e.text,url:e.url,...e.icon&&{icon:e.icon},...e.hidden&&{hidden:!0},...e.bundled&&{bundled:!0}})),o={text:a.text,url:a.url,...a.icon&&{icon:a.icon},...a.hidden&&{hidden:!0},...a.bundled&&{bundled:!0}};return l.length&&(o.items=l),o})}function F(n){const a=[];return n.filter(l=>l.parentId===null).forEach(l=>{a.push(l),n.filter(o=>o.parentId===l._id).forEach(o=>a.push(o))}),a}export const navigationView={templateUrl:"/admin/js/templates/navigation.html",async onMount(n){let[a,l]=await Promise.all([x.navigation.get().catch(()=>({brand:{},items:[]})),x.settings.get().catch(()=>({}))]),o=S(a.items),e=(l.footer?.links||[]).map(d=>({text:d.text||"",url:d.url||"",...d.hidden&&{hidden:!0}}));const u=()=>{n.find("#nav-items-list .nav-item-row").each(function(){const i=parseInt($(this).data("id"),10),t=o.find(c=>c._id===i);if(!t)return;t.text=$(this).find(".item-text").val(),t.url=$(this).find(".item-url").val(),t.icon=$(this).find(".item-icon").val(),t.hidden=$(this).find(".btn-toggle-hidden").attr("data-hidden")==="true",t.bundled=$(this).find(".btn-toggle-bundled").attr("data-bundled")==="true";const s=$(this).find(".item-parent").val();t.parentId=s?parseInt(s,10):null});const d=new Set(o.filter(i=>i.parentId!==null).map(i=>i._id));o.forEach(i=>{i.parentId!==null&&d.has(i.parentId)&&(i.parentId=null)})},p=()=>{const d=n.find("#nav-items-list").empty(),i=o.filter(t=>t.parentId===null);F(o).forEach(t=>{const s=t.parentId!==null,c=t.hidden===!0,g='<option value="">\u2014 top-level \u2014</option>'+i.filter(f=>f._id!==t._id).map(f=>`<option value="${f._id}"${f._id===t.parentId?" selected":""}>${v(f.text)||"(untitled)"}</option>`).join("");d.append(`
2
- <div class="nav-item-row${s?" nav-item-row--child":""}${c?" nav-item-row--hidden":""}" data-id="${t._id}">
3
- <span class="nav-col-indent">${s?"\u21B3":""}</span>
4
- <input type="text" class="form-input item-text nav-col-main" value="${v(t.text)}" placeholder="Label">
5
- <input type="text" class="form-input item-url nav-col-main" value="${v(t.url)}" placeholder="/url">
6
- <input type="text" class="form-input item-icon nav-col-icon" value="${v(t.icon)}" placeholder="icon">
1
+ import{api as x}from"../api.js";let I=1;const u=t=>String(t||"").replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;");function S(t){const d=[];return(t||[]).forEach(l=>{const o=I++;d.push({_id:o,text:l.text||"",url:l.url||"",icon:l.icon||"",hidden:l.hidden||!1,bundled:l.bundled||!1,parentId:null}),(l.items||l.children||[]).forEach(a=>{d.push({_id:I++,text:a.text||"",url:a.url||"",icon:a.icon||"",hidden:a.hidden||!1,bundled:a.bundled||!1,parentId:o})})}),d}function F(t){return t.filter(d=>d.parentId===null).map(d=>{const l=t.filter(a=>a.parentId===d._id).map(a=>({text:a.text,url:a.url,...a.icon&&{icon:a.icon},...a.hidden&&{hidden:!0},...a.bundled&&{bundled:!0}})),o={text:d.text,url:d.url,...d.icon&&{icon:d.icon},...d.hidden&&{hidden:!0},...d.bundled&&{bundled:!0}};return l.length&&(o.items=l),o})}function A(t){const d=[];return t.filter(l=>l.parentId===null).forEach(l=>{d.push(l),t.filter(o=>o.parentId===l._id).forEach(o=>d.push(o))}),d}export const navigationView={templateUrl:"/admin/js/templates/navigation.html",async onMount(t){let[d,l]=await Promise.all([x.navigation.get().catch(()=>({brand:{},items:[]})),x.settings.get().catch(()=>({}))]),o=S(d.items),a=(l.footer?.links||[]).map(e=>({text:e.text||"",url:e.url||"",...e.hidden&&{hidden:!0}}));const m=()=>{t.find("#nav-items-list .nav-item-row").each(function(){const i=parseInt($(this).data("id"),10),n=o.find(f=>f._id===i);if(!n)return;n.text=$(this).find(".item-text").val(),n.url=$(this).find(".item-url").val(),n.icon=$(this).find(".item-icon").val(),n.hidden=$(this).find(".btn-toggle-hidden").attr("data-hidden")==="true",n.bundled=$(this).find(".btn-toggle-bundled").attr("data-bundled")==="true";const r=$(this).find(".item-parent").val();n.parentId=r?parseInt(r,10):null});const e=new Set(o.filter(i=>i.parentId!==null).map(i=>i._id));o.forEach(i=>{i.parentId!==null&&e.has(i.parentId)&&(i.parentId=null)})},p=()=>{const e=t.find("#nav-items-list").empty(),i=o.filter(n=>n.parentId===null);A(o).forEach(n=>{const r=n.parentId!==null,f=n.hidden===!0,g='<option value="">\u2014 top-level \u2014</option>'+i.filter(c=>c._id!==n._id).map(c=>`<option value="${c._id}"${c._id===n.parentId?" selected":""}>${u(c.text)||"(untitled)"}</option>`).join("");e.append(`
2
+ <div class="nav-item-row${r?" nav-item-row--child":""}${f?" nav-item-row--hidden":""}" data-id="${n._id}">
3
+ <span class="nav-col-indent">${r?"\u21B3":""}</span>
4
+ <input type="text" class="form-input item-text nav-col-main" value="${u(n.text)}" placeholder="Label">
5
+ <input type="text" class="form-input item-url nav-col-main" value="${u(n.url)}" placeholder="/url">
6
+ <input type="text" class="form-input item-icon nav-col-icon" value="${u(n.icon)}" placeholder="icon">
7
7
  <select class="form-select item-parent nav-col-parent">${g}</select>
8
8
  <span class="nav-col-action">
9
- <button class="btn btn-sm btn-ghost btn-toggle-bundled${t.bundled?" active":""}" data-id="${t._id}" data-bundled="${!!t.bundled}" data-tooltip="${t.bundled?"Unbundle":"Bundle (seed on install)"}"><span data-icon="package"></span></button>
10
- <button class="btn btn-sm btn-ghost btn-toggle-hidden${c?" active":""}" data-id="${t._id}" data-hidden="${c}" data-tooltip="${c?"Show":"Hide"}"><span data-icon="eye-off"></span></button>
11
- <button class="btn btn-sm btn-ghost btn-remove-item" data-id="${t._id}" data-tooltip="Remove"><span data-icon="trash"></span></button>
9
+ <button class="btn btn-sm btn-ghost btn-toggle-bundled${n.bundled?" active":""}" data-id="${n._id}" data-bundled="${!!n.bundled}" data-tooltip="${n.bundled?"Unbundle":"Bundle (seed on install)"}"><span data-icon="package"></span></button>
10
+ <button class="btn btn-sm btn-ghost btn-toggle-hidden${f?" active":""}" data-id="${n._id}" data-hidden="${f}" data-tooltip="${f?"Show":"Hide"}"><span data-icon="eye-off"></span></button>
11
+ <button class="btn btn-sm btn-ghost btn-remove-item" data-id="${n._id}" data-tooltip="Remove"><span data-icon="trash"></span></button>
12
12
  </span>
13
13
  </div>
14
- `)}),Domma.icons.scan("#nav-items-list"),document.querySelectorAll("#nav-items-list [data-tooltip]").forEach(t=>{E.tooltip(t,{content:t.getAttribute("data-tooltip"),position:"top"})})},m=()=>{const d=n.find("#footer-links-list").empty();e.forEach((i,t)=>{const s=i.hidden===!0;d.append(`
15
- <div class="nav-item-row${s?" nav-item-row--hidden":""}" data-footer-idx="${t}">
16
- <input type="text" class="form-input footer-link-text nav-col-main" value="${v(i.text)}" placeholder="Label">
17
- <input type="text" class="form-input footer-link-url nav-col-main" value="${v(i.url)}" placeholder="/url">
14
+ `)}),Domma.icons.scan("#nav-items-list"),document.querySelectorAll("#nav-items-list [data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})})},v=()=>{const e=t.find("#footer-links-list").empty();a.forEach((i,n)=>{const r=i.hidden===!0;e.append(`
15
+ <div class="nav-item-row${r?" nav-item-row--hidden":""}" data-footer-idx="${n}">
16
+ <input type="text" class="form-input footer-link-text nav-col-main" value="${u(i.text)}" placeholder="Label">
17
+ <input type="text" class="form-input footer-link-url nav-col-main" value="${u(i.url)}" placeholder="/url">
18
18
  <span class="nav-col-action">
19
- <button class="btn btn-sm btn-ghost btn-toggle-hidden${s?" active":""}" data-idx="${t}" data-hidden="${s}" data-tooltip="${s?"Show":"Hide"}"><span data-icon="eye-off"></span></button>
20
- <button class="btn btn-sm btn-ghost btn-remove-footer" data-idx="${t}" data-tooltip="Remove"><span data-icon="trash"></span></button>
19
+ <button class="btn btn-sm btn-ghost btn-toggle-hidden${r?" active":""}" data-idx="${n}" data-hidden="${r}" data-tooltip="${r?"Show":"Hide"}"><span data-icon="eye-off"></span></button>
20
+ <button class="btn btn-sm btn-ghost btn-remove-footer" data-idx="${n}" data-tooltip="Remove"><span data-icon="trash"></span></button>
21
21
  </span>
22
22
  </div>
23
- `)}),Domma.icons.scan("#footer-links-list"),document.querySelectorAll("#footer-links-list [data-tooltip]").forEach(i=>{E.tooltip(i,{content:i.getAttribute("data-tooltip"),position:"top"})})},h=()=>{e=[],n.find("#footer-links-list .nav-item-row").each(function(){const d=$(this).find(".btn-toggle-hidden").attr("data-hidden")==="true",i={text:$(this).find(".footer-link-text").val().trim(),url:$(this).find(".footer-link-url").val().trim()};d&&(i.hidden=!0),e.push(i)})};n.find("#add-footer-link").on("click",()=>{h(),e.push({text:"",url:"",hidden:!1}),m()}),n.off("click",".btn-remove-footer").on("click",".btn-remove-footer",function(){h();const d=parseInt($(this).data("idx"),10);e.splice(d,1),m()}),n.find("#field-brand-text").val(a.brand?.text||""),n.find("#field-brand-url").val(a.brand?.url||"/"),n.find("#field-brand-icon").val(a.brand?.icon||""),n.find("#field-nav-variant").val(a.variant||"dark"),n.find("#field-brand-tagline").val(a.brand?.tagline||""),n.find("#field-brand-logo").val(a.brand?.logo||""),n.find("#field-nav-position").val(a.position||"sticky"),n.find("#field-brand-size").val(a.brand?.size||"md"),n.find("#field-nav-font-family").val(a.style?.fontFamily||""),n.find("#field-nav-font-size").val(a.style?.fontSize||""),n.find("#field-nav-font-weight").val(a.style?.fontWeight||""),n.find("#field-nav-letter-spacing").val(a.style?.letterSpacing||""),n.find("#field-nav-icon-size").val(a.style?.iconSize||""),n.find("#field-admin-brand-title").val(l.adminBrand?.title||""),n.find("#field-admin-brand-icon").val(l.adminBrand?.icon||""),n.find("#field-admin-brand-logo").val(l.adminBrand?.logo||""),p(),m(),E.tabs(n.find("#nav-tabs").get(0)),n.find("#add-nav-item").on("click",()=>{u(),o.push({_id:k++,text:"",url:"",icon:"",hidden:!1,parentId:null}),p()}),n.off("click",".btn-remove-item").on("click",".btn-remove-item",function(){u();const d=parseInt($(this).data("id"),10);o=o.filter(i=>i._id!==d&&i.parentId!==d),p()}),n.off("click","#nav-items-list .btn-toggle-bundled").on("click","#nav-items-list .btn-toggle-bundled",function(d){d.stopPropagation(),u();const i=parseInt($(this).data("id"),10),t=o.find(s=>s._id===i);t&&(t.bundled=!t.bundled),p()}),n.off("click","#nav-items-list .btn-toggle-hidden").on("click","#nav-items-list .btn-toggle-hidden",function(d){d.stopPropagation(),u();const i=parseInt($(this).data("id"),10),t=o.find(s=>s._id===i);t&&(t.hidden=!t.hidden),p()}),n.off("click","#footer-links-list .btn-toggle-hidden").on("click","#footer-links-list .btn-toggle-hidden",function(d){d.stopPropagation(),h();const i=parseInt($(this).data("idx"),10);e[i]&&(e[i].hidden=!e[i].hidden),m()}),n.off("change",".item-parent").on("change",".item-parent",function(){u(),p()}),n.find("#save-nav-btn").on("click",async()=>{u(),h();const d=B(o.map(r=>({...r,text:r.text.trim(),url:r.url.trim(),icon:r.icon.trim()}))).filter(r=>r.text||r.url),i=n.find("#field-brand-icon").val().trim(),t=n.find("#field-brand-tagline").val().trim(),s=n.find("#field-brand-logo").val().trim(),c=n.find("#field-brand-size").val(),g={brand:{text:n.find("#field-brand-text").val().trim(),url:n.find("#field-brand-url").val().trim()||"/",...s&&{logo:s},...i&&!s&&{icon:i},...t&&{tagline:t},...c!=="md"&&{size:c}},items:d,variant:n.find("#field-nav-variant").val(),position:n.find("#field-nav-position").val()||"sticky",style:{...n.find("#field-nav-font-family").val()&&{fontFamily:n.find("#field-nav-font-family").val()},...n.find("#field-nav-font-size").val()&&{fontSize:n.find("#field-nav-font-size").val()},...n.find("#field-nav-font-weight").val()&&{fontWeight:n.find("#field-nav-font-weight").val()},...n.find("#field-nav-letter-spacing").val()&&{letterSpacing:n.find("#field-nav-letter-spacing").val()},...n.find("#field-nav-icon-size").val()&&{iconSize:n.find("#field-nav-icon-size").val()}}},f=e.filter(r=>r.text||r.url);try{await x.navigation.save(g),a=g,o=S(a.items),p(),E.toast("Navigation saved.",{type:"success"})}catch(r){console.error("[navigation] save failed:",r),E.toast("Failed to save navigation.",{type:"error"});return}const y=n.find("#field-admin-brand-logo").val().trim(),I=n.find("#field-admin-brand-icon").val().trim(),_=n.find("#field-admin-brand-title").val().trim(),b={..._&&{title:_},...y&&{logo:y},...!y&&I&&{icon:I}};try{await x.settings.save({adminBrand:b,footer:{links:f}}),l={...l,adminBrand:b},e=f,m();const r=b.title||"CMS Admin",A=b.icon||"layout",w=b.logo||"",z=$("#admin-topbar .topbar-brand");w?z.html(`<img src="${w}" class="topbar-brand-logo" alt="${r}"><span class="topbar-brand-text">${r}</span>`):z.html(`<span data-icon="${A}"></span><span class="topbar-brand-text">${r}</span>`),Domma.icons.scan("#admin-topbar .topbar-brand")}catch(r){console.error("[navigation] admin brand / footer save failed:",r),E.toast(`Admin brand save failed: ${r.message||r}`,{type:"error"})}})}};
23
+ `)}),Domma.icons.scan("#footer-links-list"),document.querySelectorAll("#footer-links-list [data-tooltip]").forEach(i=>{E.tooltip(i,{content:i.getAttribute("data-tooltip"),position:"top"})})},h=()=>{a=[],t.find("#footer-links-list .nav-item-row").each(function(){const e=$(this).find(".btn-toggle-hidden").attr("data-hidden")==="true",i={text:$(this).find(".footer-link-text").val().trim(),url:$(this).find(".footer-link-url").val().trim()};e&&(i.hidden=!0),a.push(i)})};t.find("#add-footer-link").on("click",()=>{h(),a.push({text:"",url:"",hidden:!1}),v()}),t.off("click",".btn-remove-footer").on("click",".btn-remove-footer",function(){h();const e=parseInt($(this).data("idx"),10);a.splice(e,1),v()}),t.find("#field-brand-text").val(d.brand?.text||""),t.find("#field-brand-url").val(d.brand?.url||"/"),t.find("#field-brand-icon").val(d.brand?.icon||""),t.find("#field-nav-variant").val(d.variant||"dark"),t.find("#field-brand-tagline").val(d.brand?.tagline||""),t.find("#field-brand-logo").val(d.brand?.logo||""),t.find("#field-nav-position").val(d.position||"sticky"),t.find("#field-brand-size").val(d.brand?.size||"md"),t.find("#field-nav-font-family").val(d.style?.fontFamily||""),t.find("#field-nav-font-size").val(d.style?.fontSize||""),t.find("#field-nav-font-weight").val(d.style?.fontWeight||""),t.find("#field-nav-letter-spacing").val(d.style?.letterSpacing||""),t.find("#field-nav-icon-size").val(d.style?.iconSize||""),t.find("#field-admin-brand-title").val(l.adminBrand?.title||""),t.find("#field-admin-brand-icon").val(l.adminBrand?.icon||""),t.find("#field-admin-brand-logo").val(l.adminBrand?.logo||""),p(),v(),E.tabs(t.find("#nav-tabs").get(0)),t.find("#add-nav-item").on("click",()=>{m(),o.push({_id:I++,text:"",url:"",icon:"",hidden:!1,parentId:null}),p()}),t.off("click",".btn-remove-item").on("click",".btn-remove-item",function(){m();const e=parseInt($(this).data("id"),10);o=o.filter(i=>i._id!==e&&i.parentId!==e),p()}),t.off("click","#nav-items-list .btn-toggle-bundled").on("click","#nav-items-list .btn-toggle-bundled",function(e){e.stopPropagation(),m();const i=parseInt($(this).data("id"),10),n=o.find(r=>r._id===i);n&&(n.bundled=!n.bundled),p()}),t.off("click","#nav-items-list .btn-toggle-hidden").on("click","#nav-items-list .btn-toggle-hidden",function(e){e.stopPropagation(),m();const i=parseInt($(this).data("id"),10),n=o.find(r=>r._id===i);n&&(n.hidden=!n.hidden),p()}),t.off("click","#footer-links-list .btn-toggle-hidden").on("click","#footer-links-list .btn-toggle-hidden",function(e){e.stopPropagation(),h();const i=parseInt($(this).data("idx"),10);a[i]&&(a[i].hidden=!a[i].hidden),v()}),t.off("change",".item-parent").on("change",".item-parent",function(){m(),p()}),t.find("#save-nav-btn").on("click",async()=>{m(),h();const e=F(o.map(s=>({...s,text:s.text.trim(),url:s.url.trim(),icon:s.icon.trim()}))).filter(s=>s.text||s.url),i=t.find("#field-brand-icon").val().trim(),n=t.find("#field-brand-tagline").val().trim(),r=t.find("#field-brand-logo").val().trim(),f=t.find("#field-brand-size").val(),g={brand:{text:t.find("#field-brand-text").val().trim(),url:t.find("#field-brand-url").val().trim()||"/",...r&&{logo:r},...i&&!r&&{icon:i},...n&&{tagline:n},...f!=="md"&&{size:f}},items:e,variant:t.find("#field-nav-variant").val(),position:t.find("#field-nav-position").val()||"sticky",style:{...t.find("#field-nav-font-family").val()&&{fontFamily:t.find("#field-nav-font-family").val()},...t.find("#field-nav-font-size").val()&&{fontSize:t.find("#field-nav-font-size").val()},...t.find("#field-nav-font-weight").val()&&{fontWeight:t.find("#field-nav-font-weight").val()},...t.find("#field-nav-letter-spacing").val()&&{letterSpacing:t.find("#field-nav-letter-spacing").val()},...t.find("#field-nav-icon-size").val()&&{iconSize:t.find("#field-nav-icon-size").val()}}},c=a.filter(s=>s.text||s.url);try{await x.navigation.save(g),d=g,o=S(d.items),p(),E.toast("Navigation saved.",{type:"success"})}catch(s){console.error("[navigation] save failed:",s),E.toast("Failed to save navigation.",{type:"error"});return}const y=t.find("#field-admin-brand-logo").val().trim(),k=t.find("#field-admin-brand-icon").val().trim(),_=t.find("#field-admin-brand-title").val().trim(),b={..._&&{title:_},...y&&{logo:y},...!y&&k&&{icon:k}};try{await x.settings.save({adminBrand:b,footer:{links:c}}),l={...l,adminBrand:b},a=c,v();const s=b.title||"CMS Admin",B=b.icon||"layout",w=b.logo||"",z=$("#admin-topbar .topbar-brand");w?z.html(`<img src="${w}" class="topbar-brand-logo" alt="${s}"><span class="topbar-brand-text">${s}</span>`):z.html(`<span data-icon="${B}"></span><span class="topbar-brand-text">${s}</span>`),Domma.icons.scan("#admin-topbar .topbar-brand")}catch(s){console.error("[navigation] admin brand / footer save failed:",s),E.toast(`Admin brand save failed: ${s.message||s}`,{type:"error"})}})}};