@lit-pigeon/core 0.1.1 → 0.2.0
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.
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +111 -0
- package/dist/index.js +154 -116
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const B=require("immer"),j=require("nanoid");class ${constructor(t){this._steps=[],this._selection=null,this._selectionSet=!1,this._meta=new Map,this._doc=t}get steps(){return this._steps}get selection(){return this._selection}get selectionSet(){return this._selectionSet}get meta(){return this._meta}get doc(){return this._doc}addStep(t){return this._doc=t.apply(this._doc),this._steps.push(t),this}setSelection(t){return this._selection=t,this._selectionSet=!0,this}setMeta(t,e){return this._meta.set(t,e),this}getMeta(t){return this._meta.get(t)}}function m(o,t,e,n){return{type:o,path:t,apply(r){return B.produce(r,e)},invert(r){return m(`${o}:invert`,t,n,e)}}}function w(){return j.nanoid(10)}function g(o=0){return{top:o,right:o,bottom:o,left:o}}function z(){return{content:"<p>Enter your text here</p>",padding:g(10),lineHeight:"1.5",textAlign:"left"}}function q(){return{src:"",alt:"",width:"auto",padding:g(10),alignment:"center"}}function N(){return{content:"<p>Click me</p>",href:"#",backgroundColor:"#3b82f6",textColor:"#ffffff",borderRadius:4,padding:g(10),innerPadding:{top:12,right:24,bottom:12,left:24},fontSize:16,fontWeight:"600",alignment:"center",fullWidth:!1}}function U(){return{borderColor:"#e2e8f0",borderWidth:1,borderStyle:"solid",padding:g(10),width:"100%"}}function F(){return{height:20}}function K(){return{icons:[],iconSize:32,spacing:8,alignment:"center",padding:g(10)}}function G(){return{content:"",padding:g(0)}}function Y(){return{backgroundUrl:"",backgroundPosition:"center center",mode:"fluid-height",width:600,height:400,verticalAlign:"middle",padding:g(0),innerPadding:g(20),backgroundColor:"#ffffff",content:'<p style="color:#ffffff;font-size:24px;">Hero Title</p>'}}function X(){return{links:[{href:"#",text:"Home"},{href:"#",text:"About"},{href:"#",text:"Contact"}],hamburger:"hamburger",alignment:"center",padding:g(10),linkColor:"#000000",linkFontSize:14,linkPadding:"10px 15px"}}const M={text:z,image:q,button:N,divider:U,spacer:F,social:K,html:G,hero:Y,navbar:X};function h(o){const t=M[o];if(!t)throw new Error(`Unknown block type: ${o}`);return t()}let I=null;function Z(o){I=o}function J(o,t){const e=M[o];if(e)return{id:w(),type:o,values:{...e(),...t}};const n=I==null?void 0:I(o);if(n)return{id:w(),type:o,values:{...structuredClone(n),...t}};throw new Error(`Unknown block type: ${o}`)}function T(o=[]){return{id:w(),type:"column",attributes:{padding:g(0),verticalAlign:"top"},blocks:o}}function Q(o,t){const e=o??[T()],n=t??e.map(()=>Math.floor(12/e.length));return{id:w(),type:"row",attributes:{padding:g(0),fullWidth:!1},columns:e,columnRatios:n,locked:!1}}function H(o="Untitled"){const t=new Date().toISOString();return{version:"1.0",metadata:{name:o,createdAt:t,updatedAt:t},body:{attributes:{width:600,backgroundColor:"#f4f4f5",fontFamily:"Arial, Helvetica, sans-serif",contentAlignment:"center"},rows:[]}}}class S{constructor(t,e,n,r){this.doc=t,this.selection=e,this.plugins=n,this._pluginList=r}static create(t={}){const e=t.doc??H(),n=t.plugins??[],r=new Map,s=new S(e,null,r,n);for(const i of n)i.init&&r.set(i.name,i.init(s));return s}createTransaction(){return new $(this.doc)}apply(t){let e=t.doc;const n=t.selectionSet?t.selection:this.selection,r=new Map(this.plugins);for(const i of this._pluginList)if(i.apply){const l=r.get(i.name);r.set(i.name,i.apply(t,l))}t.steps.length>0&&!t.getMeta("skipTimestamp")&&(e=B.produce(e,i=>{i.metadata.updatedAt=new Date().toISOString()}));const s=new S(e,n,r,this._pluginList);for(const i of this._pluginList)i.onStateChange&&i.onStateChange(s,this);return s}getPluginState(t){return this.plugins.get(t)}}function v(o,t,e){return{type:"block",rowId:o,columnId:t,blockId:e}}function A(o){return{type:"row",rowId:o}}function tt(o,t){return{type:"column",rowId:o,columnId:t}}function et(){return{type:"body"}}function ot(o,t){return o===t?!0:!o||!t?!1:o.type===t.type&&o.rowId===t.rowId&&o.columnId===t.columnId&&o.blockId===t.blockId}function k(o,t,e){const n=o.body.rows.findIndex(s=>s.id===t);if(n===-1)return null;const r=o.body.rows[n].columns.findIndex(s=>s.id===e);return r===-1?null:{rowIndex:n,columnIndex:r}}function nt(o,t,e,n){return(r,s)=>{const i=k(r.doc,o,t);if(!i)return!1;const l=r.doc.body.rows[i.rowIndex].columns[i.columnIndex],c=n??l.blocks.length;if(s){const a=r.createTransaction(),u=m("insertBlock",`body.rows[${i.rowIndex}].columns[${i.columnIndex}].blocks`,d=>{d.body.rows[i.rowIndex].columns[i.columnIndex].blocks.splice(c,0,e)},d=>{d.body.rows[i.rowIndex].columns[i.columnIndex].blocks.splice(c,1)});a.addStep(u),a.setSelection(v(o,t,e.id)),s(a)}return!0}}function rt(o,t,e){return(n,r)=>{const s=k(n.doc,o,t);if(!s)return!1;const i=n.doc.body.rows[s.rowIndex].columns[s.columnIndex],l=i.blocks.findIndex(c=>c.id===e);if(l===-1)return!1;if(r){const c=i.blocks[l],a=n.createTransaction(),u=m("deleteBlock",`body.rows[${s.rowIndex}].columns[${s.columnIndex}].blocks`,d=>{d.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(l,1)},d=>{d.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(l,0,c)});a.addStep(u),a.setSelection(null),r(a)}return!0}}function st(o,t,e,n){return(r,s)=>{const i=k(r.doc,o,t);if(!i)return!1;const l=r.doc.body.rows[i.rowIndex].columns[i.columnIndex],c=l.blocks.findIndex(a=>a.id===e);if(c===-1)return!1;if(s){const a=l.blocks[c],u=r.createTransaction(),d=m("updateBlock",`body.rows[${i.rowIndex}].columns[${i.columnIndex}].blocks[${c}]`,p=>{const b=p.body.rows[i.rowIndex].columns[i.columnIndex].blocks[c];Object.assign(b.values,n)},p=>{p.body.rows[i.rowIndex].columns[i.columnIndex].blocks[c]=a});u.addStep(d),s(u)}return!0}}function it(o,t,e,n,r,s){return(i,l)=>{const c=k(i.doc,o,t);if(!c)return!1;const u=i.doc.body.rows[c.rowIndex].columns[c.columnIndex].blocks.findIndex(p=>p.id===e);if(u===-1)return!1;const d=k(i.doc,n,r);if(!d)return!1;if(l){const p=i.createTransaction(),b=m("moveBlock","body.rows",y=>{const[R]=y.body.rows[c.rowIndex].columns[c.columnIndex].blocks.splice(u,1);y.body.rows[d.rowIndex].columns[d.columnIndex].blocks.splice(s,0,R)},y=>{const[R]=y.body.rows[d.rowIndex].columns[d.columnIndex].blocks.splice(s,1);y.body.rows[c.rowIndex].columns[c.columnIndex].blocks.splice(u,0,R)});p.addStep(b),p.setSelection(v(n,r,e)),l(p)}return!0}}function lt(o,t,e){return(n,r)=>{const s=k(n.doc,o,t);if(!s)return!1;const i=n.doc.body.rows[s.rowIndex].columns[s.columnIndex],l=i.blocks.findIndex(c=>c.id===e);if(l===-1)return!1;if(r){const c=i.blocks[l],a=w(),u=structuredClone(c);u.id=a;const d=l+1,p=n.createTransaction(),b=m("duplicateBlock",`body.rows[${s.rowIndex}].columns[${s.columnIndex}].blocks`,y=>{y.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(d,0,u)},y=>{y.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(d,1)});p.addStep(b),p.setSelection(v(o,t,a)),r(p)}return!0}}function ct(o,t){return(e,n)=>{const r=t??e.doc.body.rows.length;if(n){const s=e.createTransaction(),i=m("insertRow","body.rows",l=>{l.body.rows.splice(r,0,o)},l=>{l.body.rows.splice(r,1)});s.addStep(i),s.setSelection(A(o.id)),n(s)}return!0}}function at(o){return(t,e)=>{const n=t.doc.body.rows.findIndex(r=>r.id===o);if(n===-1)return!1;if(e){const r=structuredClone(t.doc.body.rows[n]),s=t.createTransaction(),i=m("deleteRow","body.rows",l=>{l.body.rows.splice(n,1)},l=>{l.body.rows.splice(n,0,r)});s.addStep(i),s.setSelection(null),e(s)}return!0}}function dt(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(s=>s.id===o);if(r===-1||r===t)return!1;if(n){const s=e.createTransaction(),i=m("moveRow","body.rows",l=>{const[c]=l.body.rows.splice(r,1);l.body.rows.splice(t,0,c)},l=>{const[c]=l.body.rows.splice(t,1);l.body.rows.splice(r,0,c)});s.addStep(i),s.setSelection(A(o)),n(s)}return!0}}function ut(o){return(t,e)=>{const n=t.doc.body.rows.findIndex(r=>r.id===o);if(n===-1)return!1;if(e){const r=t.doc.body.rows[n],s=structuredClone(r);s.id=w(),s.columns.forEach(a=>{a.id=w(),a.blocks.forEach(u=>{u.id=w()})});const i=n+1,l=t.createTransaction(),c=m("duplicateRow","body.rows",a=>{a.body.rows.splice(i,0,s)},a=>{a.body.rows.splice(i,1)});l.addStep(c),l.setSelection(A(s.id)),e(l)}return!0}}function ft(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(s=>s.id===o);if(r===-1)return!1;if(n){const s={...e.doc.body.rows[r].attributes},i=e.createTransaction(),l=m("updateRowAttributes",`body.rows[${r}].attributes`,c=>{Object.assign(c.body.rows[r].attributes,t)},c=>{c.body.rows[r].attributes=s});i.addStep(l),n(i)}return!0}}function pt(o){return(t,e)=>{const n=t.doc.body.rows.findIndex(s=>s.id===o);if(n===-1)return!1;const r=t.doc.body.rows[n];if(r.locked||r.columns.length>=4)return!1;if(e){const s=T(),i=r.columns.length+1,l=D(i),c=[...r.columnRatios],a=t.createTransaction(),u=m("addColumn",`body.rows[${n}]`,d=>{d.body.rows[n].columns.push(s),d.body.rows[n].columnRatios=l},d=>{d.body.rows[n].columns.pop(),d.body.rows[n].columnRatios=c});a.addStep(u),e(a)}return!0}}function mt(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(l=>l.id===o);if(r===-1)return!1;const s=e.doc.body.rows[r];if(s.locked||s.columns.length<=1)return!1;const i=s.columns.findIndex(l=>l.id===t);if(i===-1)return!1;if(n){const l=structuredClone(s.columns[i]),c=[...s.columnRatios],a=s.columns.length-1,u=D(a),d=e.createTransaction(),p=m("removeColumn",`body.rows[${r}]`,b=>{b.body.rows[r].columns.splice(i,1),b.body.rows[r].columnRatios=u},b=>{b.body.rows[r].columns.splice(i,0,l),b.body.rows[r].columnRatios=c});d.addStep(p),n(d)}return!0}}function gt(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(l=>l.id===o);if(r===-1)return!1;const s=e.doc.body.rows[r];if(t.length!==s.columns.length||t.reduce((l,c)=>l+c,0)!==12)return!1;if(n){const l=[...s.columnRatios],c=e.createTransaction(),a=m("resizeColumns",`body.rows[${r}].columnRatios`,u=>{u.body.rows[r].columnRatios=t},u=>{u.body.rows[r].columnRatios=l});c.addStep(a),n(c)}return!0}}function D(o){const t=Math.floor(12/o),e=12-t*o,n=new Array(o).fill(t);for(let r=0;r<e;r++)n[r]+=1;return n}const bt=["text","image","button","divider","spacer","social","html","hero","navbar"];function W(o){const t=[];if(!o||typeof o!="object")return t.push({path:"",message:"Document must be an object"}),t;const e=o;if(e.version!=="1.0"&&t.push({path:"version",message:'Version must be "1.0"'}),!e.metadata||typeof e.metadata!="object"?t.push({path:"metadata",message:"Metadata is required"}):typeof e.metadata.name!="string"&&t.push({path:"metadata.name",message:"Name must be a string"}),!e.body||typeof e.body!="object")return t.push({path:"body",message:"Body is required"}),t;const n=e.body;return(!n.attributes||typeof n.attributes!="object")&&t.push({path:"body.attributes",message:"Body attributes are required"}),Array.isArray(n.rows)?(n.rows.forEach((r,s)=>{t.push(...ht(r,`body.rows[${s}]`))}),t):(t.push({path:"body.rows",message:"Rows must be an array"}),t)}function ht(o,t){const e=[];return o.id||e.push({path:`${t}.id`,message:"Row must have an id"}),o.type!=="row"&&e.push({path:`${t}.type`,message:'Row type must be "row"'}),Array.isArray(o.columns)?(Array.isArray(o.columnRatios)?o.columnRatios.length!==o.columns.length&&e.push({path:`${t}.columnRatios`,message:"Column ratios length must match columns length"}):e.push({path:`${t}.columnRatios`,message:"Column ratios must be an array"}),o.columns.forEach((n,r)=>{e.push(...yt(n,`${t}.columns[${r}]`))}),e):(e.push({path:`${t}.columns`,message:"Columns must be an array"}),e)}function yt(o,t){const e=[];return o.id||e.push({path:`${t}.id`,message:"Column must have an id"}),Array.isArray(o.blocks)?(o.blocks.forEach((n,r)=>{e.push(...wt(n,`${t}.blocks[${r}]`))}),e):(e.push({path:`${t}.blocks`,message:"Blocks must be an array"}),e)}function wt(o,t){const e=[];return o.id||e.push({path:`${t}.id`,message:"Block must have an id"}),bt.includes(o.type)||e.push({path:`${t}.type`,message:`Invalid block type: ${o.type}`}),(!o.values||typeof o.values!="object")&&e.push({path:`${t}.values`,message:"Block must have values"}),e}function kt(o){return W(o).length===0}const x=new Map,xt=[{type:"text",label:"Text",icon:"text",defaultValues:h("text")},{type:"image",label:"Image",icon:"image",defaultValues:h("image")},{type:"button",label:"Button",icon:"button",defaultValues:h("button")},{type:"divider",label:"Divider",icon:"divider",defaultValues:h("divider")},{type:"spacer",label:"Spacer",icon:"spacer",defaultValues:h("spacer")},{type:"social",label:"Social",icon:"social",defaultValues:h("social")},{type:"html",label:"HTML",icon:"html",defaultValues:h("html")},{type:"hero",label:"Hero",icon:"hero",defaultValues:h("hero")},{type:"navbar",label:"Navbar",icon:"navbar",defaultValues:h("navbar")}];function It(){for(const o of xt)x.set(o.type,o);Z(o=>{var t;return(t=x.get(o))==null?void 0:t.defaultValues})}function P(o){x.set(o.type,o)}function St(o){return x.get(o)}function vt(){return Array.from(x.values())}function At(o){return x.has(o)}It();const Ct=100;function Rt(){return{undoStack:[],redoStack:[]}}function _t(o,t){const e=[...o.undoStack,t];return e.length>Ct&&e.shift(),{undoStack:e,redoStack:[]}}function Tt(o){if(o.undoStack.length===0)return{history:o,entry:null};const t=[...o.undoStack],e=t.pop(),n=[...o.redoStack,e];return{history:{undoStack:t,redoStack:n},entry:e}}function Bt(o){if(o.redoStack.length===0)return{history:o,entry:null};const t=[...o.redoStack],e=t.pop();return{history:{undoStack:[...o.undoStack,e],redoStack:t},entry:e}}function V(o){return o.undoStack.length>0}function E(o){return o.redoStack.length>0}const C="history";function $t(){return{name:C,init(){return Rt()},apply(o,t){const e=t;if(o.meta.get("isUndo")||o.meta.get("isRedo"))return o.meta.get("newHistory")??e;if(o.steps.length===0||o.meta.get("skipHistory"))return e;const n={steps:[...o.steps],doc:o.doc,timestamp:Date.now()};return _t(e,n)}}}function Mt(o,t){const e=o.plugins.get(C);if(!e||!V(e))return!1;if(t){const{history:n,entry:r}=Tt(e);if(!r)return!1;const s=o.createTransaction();for(let i=r.steps.length-1;i>=0;i--){const l=r.steps[i].invert(s.doc);s.addStep(l)}s.setMeta("isUndo",!0),s.setMeta("newHistory",n),s.setMeta("skipTimestamp",!0),t(s)}return!0}function Ht(o,t){const e=o.plugins.get(C);if(!e||!E(e))return!1;if(t){const{history:n,entry:r}=Bt(e);if(!r)return!1;const s=o.createTransaction();for(const i of r.steps)s.addStep(i);s.setMeta("isRedo",!0),s.setMeta("newHistory",n),s.setMeta("skipTimestamp",!0),t(s)}return!0}class Dt{constructor(){this._plugins=new Map}register(t){if(this._plugins.has(t.name))throw new Error(`Plugin "${t.name}" is already registered`);if(this._plugins.set(t.name,t),t.blocks)for(const e of t.blocks)P(e)}unregister(t){this._plugins.delete(t)}get(t){return this._plugins.get(t)}getAll(){return Array.from(this._plugins.values())}getCommands(){const t={};for(const e of this._plugins.values())e.commands&&Object.assign(t,e.commands);return t}has(t){return this._plugins.has(t)}}function _(o,t){if(o===t)return!0;if(o==null||t==null||typeof o!=typeof t)return!1;if(Array.isArray(o))return!Array.isArray(t)||o.length!==t.length?!1:o.every((e,n)=>_(e,t[n]));if(typeof o=="object"){const e=Object.keys(o),n=Object.keys(t);return e.length!==n.length?!1:e.every(r=>_(o[r],t[r]))}return!1}const f="2026-05-26T10:00:00.000Z",Wt={id:"starter-welcome",name:"Welcome",description:"A clean welcome email with a hero, intro paragraph, and call-to-action.",category:"welcome",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Welcome",previewText:"We're glad you're here.",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#f5f7fb",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-hero",type:"row",locked:!1,attributes:{padding:{top:0,right:0,bottom:0,left:0},fullWidth:!0},columnRatios:[12],columns:[{id:"c-hero",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-hero",type:"hero",values:{backgroundUrl:"https://placehold.co/600x280/0f172a/ffffff?text=Welcome",backgroundPosition:"center center",mode:"fixed-height",width:600,height:280,verticalAlign:"middle",padding:{top:0,right:0,bottom:0,left:0},innerPadding:{top:40,right:40,bottom:40,left:40},backgroundColor:"#0f172a",content:'<h1 style="color:#ffffff;font-size:32px;margin:0;">Welcome, {{firstName}}</h1>'}}]}]},{id:"r-intro",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:32,right:24,bottom:8,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-intro",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-intro",type:"text",values:{content:"<p>Thanks for joining — we've put together a quick guide to help you get the most out of your account.</p>",padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.6",textAlign:"left"}}]}]},{id:"r-cta",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:16,right:24,bottom:32,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-cta",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-cta",type:"button",values:{content:"<p>Get started</p>",href:"https://example.com/start",backgroundColor:"#3b82f6",textColor:"#ffffff",borderRadius:6,padding:{top:8,right:8,bottom:8,left:8},innerPadding:{top:12,right:24,bottom:12,left:24},fontSize:16,fontWeight:"600",alignment:"center",fullWidth:!1}}]}]}]}}},Pt={id:"starter-newsletter",name:"Newsletter",description:"A simple 3-section newsletter — headline + body + footer.",category:"newsletter",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Newsletter",previewText:"This month's updates",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#ffffff",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-head",type:"row",locked:!1,attributes:{padding:{top:24,right:24,bottom:8,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-head",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-head",type:"text",values:{content:'<h1 style="font-size:24px;margin:0;">This month at Acme</h1>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.3",textAlign:"left"}}]}]},{id:"r-body",type:"row",locked:!1,attributes:{padding:{top:8,right:24,bottom:24,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-body",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-body",type:"text",values:{content:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sodales, mauris vel rhoncus sodales, eros lectus rutrum lectus.</p><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>",padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.6",textAlign:"left"}}]}]},{id:"r-foot",type:"row",locked:!1,attributes:{backgroundColor:"#f5f7fb",padding:{top:16,right:24,bottom:16,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-foot",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-foot",type:"text",values:{content:'<p style="color:#64748b;font-size:12px;">© Acme · <a href="https://example.com/unsubscribe">Unsubscribe</a></p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"center"}}]}]}]}}},Vt={id:"starter-transactional",name:"Transactional (order confirmation)",description:"Order confirmation pattern with summary and a primary button.",category:"transactional",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Order confirmation",previewText:"Order {{orderNumber}} is on its way.",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#ffffff",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-h",type:"row",locked:!1,attributes:{padding:{top:32,right:24,bottom:8,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-h",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-h",type:"text",values:{content:'<h1 style="font-size:24px;margin:0 0 8px;">Thanks for your order, {{firstName}}</h1><p style="margin:0;">Order <strong>{{orderNumber}}</strong> is on its way.</p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"left"}}]}]},{id:"r-summary",type:"row",locked:!1,attributes:{backgroundColor:"#f8fafc",padding:{top:16,right:24,bottom:16,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-summary",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-summary",type:"text",values:{content:'<p style="margin:0 0 8px;"><strong>Summary</strong></p><p style="margin:0;">{{itemCount}} item(s) · {{total}}</p><p style="margin:8px 0 0;color:#64748b;font-size:12px;">Estimated delivery: {{deliveryDate}}</p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"left"}}]}]},{id:"r-cta",type:"row",locked:!1,attributes:{padding:{top:24,right:24,bottom:24,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-cta",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-cta",type:"button",values:{content:"<p>View order</p>",href:"https://example.com/orders/{{orderNumber}}",backgroundColor:"#0f172a",textColor:"#ffffff",borderRadius:6,padding:{top:0,right:0,bottom:0,left:0},innerPadding:{top:12,right:24,bottom:12,left:24},fontSize:16,fontWeight:"600",alignment:"left",fullWidth:!1}}]}]}]}}},Et={id:"starter-promo",name:"Promo / Sale",description:"Two-column product grid with a primary CTA and a social-link footer.",category:"promo",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Spring sale",previewText:"Two days only — 30% off.",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#fdf6ee",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-hero",type:"row",locked:!1,attributes:{padding:{top:0,right:0,bottom:0,left:0},fullWidth:!0},columnRatios:[12],columns:[{id:"c-hero",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"middle"},blocks:[{id:"b-hero",type:"hero",values:{backgroundUrl:"https://placehold.co/600x240/e76f51/ffffff?text=30%25+off",backgroundPosition:"center center",mode:"fluid-height",width:600,height:240,verticalAlign:"middle",padding:{top:0,right:0,bottom:0,left:0},innerPadding:{top:32,right:32,bottom:32,left:32},backgroundColor:"#e76f51",content:'<h1 style="color:#ffffff;font-size:36px;margin:0 0 8px;">30% off, this weekend only</h1><p style="color:#ffffff;font-size:16px;margin:0;">Code <strong>SPRING30</strong> at checkout.</p>'}}]}]},{id:"r-grid",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:24,right:16,bottom:24,left:16},fullWidth:!1},columnRatios:[6,6],columns:[{id:"c-l",type:"column",attributes:{padding:{top:0,right:8,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-l-img",type:"image",values:{src:"https://placehold.co/280x200",alt:"Linen shirt",width:"auto",href:"https://example.com/p/shirt",padding:{top:0,right:0,bottom:8,left:0},alignment:"center",borderRadius:6}},{id:"b-l-txt",type:"text",values:{content:'<p style="text-align:center;margin:0;"><strong>Linen shirt</strong><br><span style="color:#64748b;">$48 · was $69</span></p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"center"}}]},{id:"c-r",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:8},verticalAlign:"top"},blocks:[{id:"b-r-img",type:"image",values:{src:"https://placehold.co/280x200",alt:"Wool jumper",width:"auto",href:"https://example.com/p/jumper",padding:{top:0,right:0,bottom:8,left:0},alignment:"center",borderRadius:6}},{id:"b-r-txt",type:"text",values:{content:'<p style="text-align:center;margin:0;"><strong>Wool jumper</strong><br><span style="color:#64748b;">$84 · was $120</span></p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"center"}}]}]},{id:"r-cta",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:8,right:16,bottom:24,left:16},fullWidth:!1},columnRatios:[12],columns:[{id:"c-cta",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-cta",type:"button",values:{content:"<p>Shop the sale</p>",href:"https://example.com/sale",backgroundColor:"#0f172a",textColor:"#ffffff",borderRadius:6,padding:{top:8,right:0,bottom:8,left:0},innerPadding:{top:14,right:28,bottom:14,left:28},fontSize:16,fontWeight:"600",alignment:"center",fullWidth:!0}}]}]}]}}},O=Object.freeze([Wt,Pt,Vt,Et]);function L(){return O.map(o=>structuredClone(o))}function Ot(o){const t=O.find(e=>e.id===o);return t?structuredClone(t):null}class Lt{constructor(t={}){if(this._byId=new Map,t.includeStarters!==!1)for(const e of L())this._byId.set(e.id,e);if(t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(){return Array.from(this._byId.values()).map(t=>structuredClone(t))}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("Template.id is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}}class jt{constructor(t={}){if(this._byId=new Map,t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(){return Array.from(this._byId.values()).map(t=>structuredClone(t))}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("BrandKit.id is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}}class zt{constructor(t={}){if(this._byId=new Map,t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(t={}){let n=Array.from(this._byId.values()).map(i=>structuredClone(i)).filter(i=>qt(i,t));n.sort((i,l)=>i.updatedAt<l.updatedAt?1:i.updatedAt>l.updatedAt?-1:0);const r=t.offset??0,s=t.limit;return n=n.slice(r,s!==void 0?r+s:void 0),n}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("Asset.id is required");if(!t.src)throw new Error("Asset.src is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),e.folder||(e.folder="/"),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}async listFolders(){const t=new Set;for(const e of this._byId.values())t.add(e.folder||"/");return Array.from(t).sort()}}function qt(o,t){if(t.folder&&(o.folder||"/")!==t.folder)return!1;if(t.tags&&t.tags.length>0){const e=new Set(o.tags??[]);if(!t.tags.every(n=>e.has(n)))return!1}if(t.search){const e=t.search.toLowerCase();if(![o.name,o.alt??"",...o.tags??[]].join(" ").toLowerCase().includes(e))return!1}return!0}exports.EditorState=S;exports.HISTORY_PLUGIN_NAME=C;exports.InMemoryAssetStorage=zt;exports.InMemoryBrandKitStorage=jt;exports.InMemoryTemplateStorage=Lt;exports.PluginRegistry=Dt;exports.Transaction=$;exports.addColumn=pt;exports.canRedo=E;exports.canUndo=V;exports.createBlock=J;exports.createBlockSelection=v;exports.createBodySelection=et;exports.createColumn=T;exports.createColumnSelection=tt;exports.createDefaultDocument=H;exports.createDocStep=m;exports.createHistoryPlugin=$t;exports.createRow=Q;exports.createRowSelection=A;exports.deepEqual=_;exports.defaultSpacing=g;exports.deleteBlock=rt;exports.deleteRow=at;exports.duplicateBlock=lt;exports.duplicateRow=ut;exports.generateId=w;exports.getAllBlockDefinitions=vt;exports.getBlockDefinition=St;exports.getDefaultValues=h;exports.getStarterTemplate=Ot;exports.getStarterTemplates=L;exports.insertBlock=nt;exports.insertRow=ct;exports.isKnownBlockType=At;exports.isValidDocument=kt;exports.moveBlock=it;exports.moveRow=dt;exports.redo=Ht;exports.registerBlock=P;exports.removeColumn=mt;exports.resizeColumns=gt;exports.selectionsEqual=ot;exports.undo=Mt;exports.updateBlock=st;exports.updateRowAttributes=ft;exports.validateDocument=W;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const B=require("immer"),N=require("nanoid");class M{constructor(t){this._steps=[],this._selection=null,this._selectionSet=!1,this._meta=new Map,this._doc=t}get steps(){return this._steps}get selection(){return this._selection}get selectionSet(){return this._selectionSet}get meta(){return this._meta}get doc(){return this._doc}addStep(t){return this._doc=t.apply(this._doc),this._steps.push(t),this}setSelection(t){return this._selection=t,this._selectionSet=!0,this}setMeta(t,e){return this._meta.set(t,e),this}getMeta(t){return this._meta.get(t)}}function m(o,t,e,n){return{type:o,path:t,apply(r){return B.produce(r,e)},invert(r){return m(`${o}:invert`,t,n,e)}}}function g(){return N.nanoid(10)}function b(o=0){return{top:o,right:o,bottom:o,left:o}}function j(){return{content:"<p>Enter your text here</p>",padding:b(10),lineHeight:"1.5",textAlign:"left"}}function z(){return{src:"",alt:"",width:"auto",padding:b(10),alignment:"center"}}function q(){return{content:"<p>Click me</p>",href:"#",backgroundColor:"#3b82f6",textColor:"#ffffff",borderRadius:4,padding:b(10),innerPadding:{top:12,right:24,bottom:12,left:24},fontSize:16,fontWeight:"600",alignment:"center",fullWidth:!1}}function U(){return{borderColor:"#e2e8f0",borderWidth:1,borderStyle:"solid",padding:b(10),width:"100%"}}function F(){return{height:20}}function K(){return{icons:[],iconSize:32,spacing:8,alignment:"center",padding:b(10)}}function Y(){return{content:"",padding:b(0)}}function G(){return{backgroundUrl:"",backgroundPosition:"center center",mode:"fluid-height",width:600,height:400,verticalAlign:"middle",padding:b(0),innerPadding:b(20),backgroundColor:"#ffffff",content:'<p style="color:#ffffff;font-size:24px;">Hero Title</p>'}}function X(){return{links:[{href:"#",text:"Home"},{href:"#",text:"About"},{href:"#",text:"Contact"}],hamburger:"hamburger",alignment:"center",padding:b(10),linkColor:"#000000",linkFontSize:14,linkPadding:"10px 15px"}}const $={text:j,image:z,button:q,divider:U,spacer:F,social:K,html:Y,hero:G,navbar:X};function y(o){const t=$[o];if(!t)throw new Error(`Unknown block type: ${o}`);return t()}let I=null;function Z(o){I=o}function J(o,t){const e=$[o];if(e)return{id:g(),type:o,values:{...e(),...t}};const n=I==null?void 0:I(o);if(n)return{id:g(),type:o,values:{...structuredClone(n),...t}};throw new Error(`Unknown block type: ${o}`)}function T(o=[]){return{id:g(),type:"column",attributes:{padding:b(0),verticalAlign:"top"},blocks:o}}function Q(o,t){const e=o??[T()],n=t??e.map(()=>Math.floor(12/e.length));return{id:g(),type:"row",attributes:{padding:b(0),fullWidth:!1},columns:e,columnRatios:n,locked:!1}}function E(o="Untitled"){const t=new Date().toISOString();return{version:"1.0",metadata:{name:o,createdAt:t,updatedAt:t},body:{attributes:{width:600,backgroundColor:"#f4f4f5",fontFamily:"Arial, Helvetica, sans-serif",contentAlignment:"center"},rows:[]}}}class S{constructor(t,e,n,r){this.doc=t,this.selection=e,this.plugins=n,this._pluginList=r}static create(t={}){const e=t.doc??E(),n=t.plugins??[],r=new Map,s=new S(e,null,r,n);for(const i of n)i.init&&r.set(i.name,i.init(s));return s}createTransaction(){return new M(this.doc)}apply(t){let e=t.doc;const n=t.selectionSet?t.selection:this.selection,r=new Map(this.plugins);for(const i of this._pluginList)if(i.apply){const l=r.get(i.name);r.set(i.name,i.apply(t,l))}t.steps.length>0&&!t.getMeta("skipTimestamp")&&(e=B.produce(e,i=>{i.metadata.updatedAt=new Date().toISOString()}));const s=new S(e,n,r,this._pluginList);for(const i of this._pluginList)i.onStateChange&&i.onStateChange(s,this);return s}getPluginState(t){return this.plugins.get(t)}}function v(o,t,e){return{type:"block",rowId:o,columnId:t,blockId:e}}function A(o){return{type:"row",rowId:o}}function tt(o,t){return{type:"column",rowId:o,columnId:t}}function et(){return{type:"body"}}function ot(o,t){return o===t?!0:!o||!t?!1:o.type===t.type&&o.rowId===t.rowId&&o.columnId===t.columnId&&o.blockId===t.blockId}function k(o,t,e){const n=o.body.rows.findIndex(s=>s.id===t);if(n===-1)return null;const r=o.body.rows[n].columns.findIndex(s=>s.id===e);return r===-1?null:{rowIndex:n,columnIndex:r}}function nt(o,t,e,n){return(r,s)=>{const i=k(r.doc,o,t);if(!i)return!1;const l=r.doc.body.rows[i.rowIndex].columns[i.columnIndex],a=n??l.blocks.length;if(s){const c=r.createTransaction(),u=m("insertBlock",`body.rows[${i.rowIndex}].columns[${i.columnIndex}].blocks`,d=>{d.body.rows[i.rowIndex].columns[i.columnIndex].blocks.splice(a,0,e)},d=>{d.body.rows[i.rowIndex].columns[i.columnIndex].blocks.splice(a,1)});c.addStep(u),c.setSelection(v(o,t,e.id)),s(c)}return!0}}function rt(o,t,e){return(n,r)=>{const s=k(n.doc,o,t);if(!s)return!1;const i=n.doc.body.rows[s.rowIndex].columns[s.columnIndex],l=i.blocks.findIndex(a=>a.id===e);if(l===-1)return!1;if(r){const a=i.blocks[l],c=n.createTransaction(),u=m("deleteBlock",`body.rows[${s.rowIndex}].columns[${s.columnIndex}].blocks`,d=>{d.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(l,1)},d=>{d.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(l,0,a)});c.addStep(u),c.setSelection(null),r(c)}return!0}}function st(o,t,e,n){return(r,s)=>{const i=k(r.doc,o,t);if(!i)return!1;const l=r.doc.body.rows[i.rowIndex].columns[i.columnIndex],a=l.blocks.findIndex(c=>c.id===e);if(a===-1)return!1;if(s){const c=l.blocks[a],u=r.createTransaction(),d=m("updateBlock",`body.rows[${i.rowIndex}].columns[${i.columnIndex}].blocks[${a}]`,p=>{const h=p.body.rows[i.rowIndex].columns[i.columnIndex].blocks[a];Object.assign(h.values,n)},p=>{p.body.rows[i.rowIndex].columns[i.columnIndex].blocks[a]=c});u.addStep(d),s(u)}return!0}}function it(o,t,e,n,r,s){return(i,l)=>{const a=k(i.doc,o,t);if(!a)return!1;const u=i.doc.body.rows[a.rowIndex].columns[a.columnIndex].blocks.findIndex(p=>p.id===e);if(u===-1)return!1;const d=k(i.doc,n,r);if(!d)return!1;if(l){const p=i.createTransaction(),h=m("moveBlock","body.rows",w=>{const[R]=w.body.rows[a.rowIndex].columns[a.columnIndex].blocks.splice(u,1);w.body.rows[d.rowIndex].columns[d.columnIndex].blocks.splice(s,0,R)},w=>{const[R]=w.body.rows[d.rowIndex].columns[d.columnIndex].blocks.splice(s,1);w.body.rows[a.rowIndex].columns[a.columnIndex].blocks.splice(u,0,R)});p.addStep(h),p.setSelection(v(n,r,e)),l(p)}return!0}}function lt(o,t,e){return(n,r)=>{const s=k(n.doc,o,t);if(!s)return!1;const i=n.doc.body.rows[s.rowIndex].columns[s.columnIndex],l=i.blocks.findIndex(a=>a.id===e);if(l===-1)return!1;if(r){const a=i.blocks[l],c=g(),u=structuredClone(a);u.id=c;const d=l+1,p=n.createTransaction(),h=m("duplicateBlock",`body.rows[${s.rowIndex}].columns[${s.columnIndex}].blocks`,w=>{w.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(d,0,u)},w=>{w.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(d,1)});p.addStep(h),p.setSelection(v(o,t,c)),r(p)}return!0}}function at(o,t){return(e,n)=>{const r=t??e.doc.body.rows.length;if(n){const s=e.createTransaction(),i=m("insertRow","body.rows",l=>{l.body.rows.splice(r,0,o)},l=>{l.body.rows.splice(r,1)});s.addStep(i),s.setSelection(A(o.id)),n(s)}return!0}}function ct(o){return(t,e)=>{const n=t.doc.body.rows.findIndex(r=>r.id===o);if(n===-1)return!1;if(e){const r=structuredClone(t.doc.body.rows[n]),s=t.createTransaction(),i=m("deleteRow","body.rows",l=>{l.body.rows.splice(n,1)},l=>{l.body.rows.splice(n,0,r)});s.addStep(i),s.setSelection(null),e(s)}return!0}}function dt(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(s=>s.id===o);if(r===-1||r===t)return!1;if(n){const s=e.createTransaction(),i=m("moveRow","body.rows",l=>{const[a]=l.body.rows.splice(r,1);l.body.rows.splice(t,0,a)},l=>{const[a]=l.body.rows.splice(t,1);l.body.rows.splice(r,0,a)});s.addStep(i),s.setSelection(A(o)),n(s)}return!0}}function ut(o){return(t,e)=>{const n=t.doc.body.rows.findIndex(r=>r.id===o);if(n===-1)return!1;if(e){const r=t.doc.body.rows[n],s=structuredClone(r);s.id=g(),s.columns.forEach(c=>{c.id=g(),c.blocks.forEach(u=>{u.id=g()})});const i=n+1,l=t.createTransaction(),a=m("duplicateRow","body.rows",c=>{c.body.rows.splice(i,0,s)},c=>{c.body.rows.splice(i,1)});l.addStep(a),l.setSelection(A(s.id)),e(l)}return!0}}function ft(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(s=>s.id===o);if(r===-1)return!1;if(n){const s={...e.doc.body.rows[r].attributes},i=e.createTransaction(),l=m("updateRowAttributes",`body.rows[${r}].attributes`,a=>{Object.assign(a.body.rows[r].attributes,t)},a=>{a.body.rows[r].attributes=s});i.addStep(l),n(i)}return!0}}function pt(o){return(t,e)=>{const n=t.doc.body.rows.findIndex(s=>s.id===o);if(n===-1)return!1;const r=t.doc.body.rows[n];if(r.locked||r.columns.length>=4)return!1;if(e){const s=T(),i=r.columns.length+1,l=H(i),a=[...r.columnRatios],c=t.createTransaction(),u=m("addColumn",`body.rows[${n}]`,d=>{d.body.rows[n].columns.push(s),d.body.rows[n].columnRatios=l},d=>{d.body.rows[n].columns.pop(),d.body.rows[n].columnRatios=a});c.addStep(u),e(c)}return!0}}function mt(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(l=>l.id===o);if(r===-1)return!1;const s=e.doc.body.rows[r];if(s.locked||s.columns.length<=1)return!1;const i=s.columns.findIndex(l=>l.id===t);if(i===-1)return!1;if(n){const l=structuredClone(s.columns[i]),a=[...s.columnRatios],c=s.columns.length-1,u=H(c),d=e.createTransaction(),p=m("removeColumn",`body.rows[${r}]`,h=>{h.body.rows[r].columns.splice(i,1),h.body.rows[r].columnRatios=u},h=>{h.body.rows[r].columns.splice(i,0,l),h.body.rows[r].columnRatios=a});d.addStep(p),n(d)}return!0}}function gt(o,t){return(e,n)=>{const r=e.doc.body.rows.findIndex(l=>l.id===o);if(r===-1)return!1;const s=e.doc.body.rows[r];if(t.length!==s.columns.length||t.reduce((l,a)=>l+a,0)!==12)return!1;if(n){const l=[...s.columnRatios],a=e.createTransaction(),c=m("resizeColumns",`body.rows[${r}].columnRatios`,u=>{u.body.rows[r].columnRatios=t},u=>{u.body.rows[r].columnRatios=l});a.addStep(c),n(a)}return!0}}function H(o){const t=Math.floor(12/o),e=12-t*o,n=new Array(o).fill(t);for(let r=0;r<e;r++)n[r]+=1;return n}const bt=["text","image","button","divider","spacer","social","html","hero","navbar"];function W(o){const t=[];if(!o||typeof o!="object")return t.push({path:"",message:"Document must be an object"}),t;const e=o;if(e.version!=="1.0"&&t.push({path:"version",message:'Version must be "1.0"'}),!e.metadata||typeof e.metadata!="object"?t.push({path:"metadata",message:"Metadata is required"}):typeof e.metadata.name!="string"&&t.push({path:"metadata.name",message:"Name must be a string"}),!e.body||typeof e.body!="object")return t.push({path:"body",message:"Body is required"}),t;const n=e.body;return(!n.attributes||typeof n.attributes!="object")&&t.push({path:"body.attributes",message:"Body attributes are required"}),Array.isArray(n.rows)?(n.rows.forEach((r,s)=>{t.push(...ht(r,`body.rows[${s}]`))}),t):(t.push({path:"body.rows",message:"Rows must be an array"}),t)}function ht(o,t){const e=[];return o.id||e.push({path:`${t}.id`,message:"Row must have an id"}),o.type!=="row"&&e.push({path:`${t}.type`,message:'Row type must be "row"'}),Array.isArray(o.columns)?(Array.isArray(o.columnRatios)?o.columnRatios.length!==o.columns.length&&e.push({path:`${t}.columnRatios`,message:"Column ratios length must match columns length"}):e.push({path:`${t}.columnRatios`,message:"Column ratios must be an array"}),o.columns.forEach((n,r)=>{e.push(...yt(n,`${t}.columns[${r}]`))}),e):(e.push({path:`${t}.columns`,message:"Columns must be an array"}),e)}function yt(o,t){const e=[];return o.id||e.push({path:`${t}.id`,message:"Column must have an id"}),Array.isArray(o.blocks)?(o.blocks.forEach((n,r)=>{e.push(...wt(n,`${t}.blocks[${r}]`))}),e):(e.push({path:`${t}.blocks`,message:"Blocks must be an array"}),e)}function wt(o,t){const e=[];return o.id||e.push({path:`${t}.id`,message:"Block must have an id"}),bt.includes(o.type)||e.push({path:`${t}.type`,message:`Invalid block type: ${o.type}`}),(!o.values||typeof o.values!="object")&&e.push({path:`${t}.values`,message:"Block must have values"}),e}function kt(o){return W(o).length===0}const x=new Map,xt=[{type:"text",label:"Text",icon:"text",defaultValues:y("text")},{type:"image",label:"Image",icon:"image",defaultValues:y("image")},{type:"button",label:"Button",icon:"button",defaultValues:y("button")},{type:"divider",label:"Divider",icon:"divider",defaultValues:y("divider")},{type:"spacer",label:"Spacer",icon:"spacer",defaultValues:y("spacer")},{type:"social",label:"Social",icon:"social",defaultValues:y("social")},{type:"html",label:"HTML",icon:"html",defaultValues:y("html")},{type:"hero",label:"Hero",icon:"hero",defaultValues:y("hero")},{type:"navbar",label:"Navbar",icon:"navbar",defaultValues:y("navbar")}];function It(){for(const o of xt)x.set(o.type,o);Z(o=>{var t;return(t=x.get(o))==null?void 0:t.defaultValues})}function D(o){x.set(o.type,o)}function St(o){return x.get(o)}function vt(){return Array.from(x.values())}function At(o){return x.has(o)}It();const Ct=100;function Rt(){return{undoStack:[],redoStack:[]}}function _t(o,t){const e=[...o.undoStack,t];return e.length>Ct&&e.shift(),{undoStack:e,redoStack:[]}}function Tt(o){if(o.undoStack.length===0)return{history:o,entry:null};const t=[...o.undoStack],e=t.pop(),n=[...o.redoStack,e];return{history:{undoStack:t,redoStack:n},entry:e}}function Bt(o){if(o.redoStack.length===0)return{history:o,entry:null};const t=[...o.redoStack],e=t.pop();return{history:{undoStack:[...o.undoStack,e],redoStack:t},entry:e}}function P(o){return o.undoStack.length>0}function V(o){return o.redoStack.length>0}const C="history";function Mt(){return{name:C,init(){return Rt()},apply(o,t){const e=t;if(o.meta.get("isUndo")||o.meta.get("isRedo"))return o.meta.get("newHistory")??e;if(o.steps.length===0||o.meta.get("skipHistory"))return e;const n={steps:[...o.steps],doc:o.doc,timestamp:Date.now()};return _t(e,n)}}}function $t(o,t){const e=o.plugins.get(C);if(!e||!P(e))return!1;if(t){const{history:n,entry:r}=Tt(e);if(!r)return!1;const s=o.createTransaction();for(let i=r.steps.length-1;i>=0;i--){const l=r.steps[i].invert(s.doc);s.addStep(l)}s.setMeta("isUndo",!0),s.setMeta("newHistory",n),s.setMeta("skipTimestamp",!0),t(s)}return!0}function Et(o,t){const e=o.plugins.get(C);if(!e||!V(e))return!1;if(t){const{history:n,entry:r}=Bt(e);if(!r)return!1;const s=o.createTransaction();for(const i of r.steps)s.addStep(i);s.setMeta("isRedo",!0),s.setMeta("newHistory",n),s.setMeta("skipTimestamp",!0),t(s)}return!0}class Ht{constructor(){this._plugins=new Map}register(t){if(this._plugins.has(t.name))throw new Error(`Plugin "${t.name}" is already registered`);if(this._plugins.set(t.name,t),t.blocks)for(const e of t.blocks)D(e)}unregister(t){this._plugins.delete(t)}get(t){return this._plugins.get(t)}getAll(){return Array.from(this._plugins.values())}getCommands(){const t={};for(const e of this._plugins.values())e.commands&&Object.assign(t,e.commands);return t}has(t){return this._plugins.has(t)}}function _(o,t){if(o===t)return!0;if(o==null||t==null||typeof o!=typeof t)return!1;if(Array.isArray(o))return!Array.isArray(t)||o.length!==t.length?!1:o.every((e,n)=>_(e,t[n]));if(typeof o=="object"){const e=Object.keys(o),n=Object.keys(t);return e.length!==n.length?!1:e.every(r=>_(o[r],t[r]))}return!1}const f="2026-05-26T10:00:00.000Z",Wt={id:"starter-welcome",name:"Welcome",description:"A clean welcome email with a hero, intro paragraph, and call-to-action.",category:"welcome",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Welcome",previewText:"We're glad you're here.",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#f5f7fb",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-hero",type:"row",locked:!1,attributes:{padding:{top:0,right:0,bottom:0,left:0},fullWidth:!0},columnRatios:[12],columns:[{id:"c-hero",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-hero",type:"hero",values:{backgroundUrl:"https://placehold.co/600x280/0f172a/ffffff?text=Welcome",backgroundPosition:"center center",mode:"fixed-height",width:600,height:280,verticalAlign:"middle",padding:{top:0,right:0,bottom:0,left:0},innerPadding:{top:40,right:40,bottom:40,left:40},backgroundColor:"#0f172a",content:'<h1 style="color:#ffffff;font-size:32px;margin:0;">Welcome, {{firstName}}</h1>'}}]}]},{id:"r-intro",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:32,right:24,bottom:8,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-intro",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-intro",type:"text",values:{content:"<p>Thanks for joining — we've put together a quick guide to help you get the most out of your account.</p>",padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.6",textAlign:"left"}}]}]},{id:"r-cta",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:16,right:24,bottom:32,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-cta",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-cta",type:"button",values:{content:"<p>Get started</p>",href:"https://example.com/start",backgroundColor:"#3b82f6",textColor:"#ffffff",borderRadius:6,padding:{top:8,right:8,bottom:8,left:8},innerPadding:{top:12,right:24,bottom:12,left:24},fontSize:16,fontWeight:"600",alignment:"center",fullWidth:!1}}]}]}]}}},Dt={id:"starter-newsletter",name:"Newsletter",description:"A simple 3-section newsletter — headline + body + footer.",category:"newsletter",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Newsletter",previewText:"This month's updates",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#ffffff",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-head",type:"row",locked:!1,attributes:{padding:{top:24,right:24,bottom:8,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-head",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-head",type:"text",values:{content:'<h1 style="font-size:24px;margin:0;">This month at Acme</h1>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.3",textAlign:"left"}}]}]},{id:"r-body",type:"row",locked:!1,attributes:{padding:{top:8,right:24,bottom:24,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-body",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-body",type:"text",values:{content:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sodales, mauris vel rhoncus sodales, eros lectus rutrum lectus.</p><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>",padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.6",textAlign:"left"}}]}]},{id:"r-foot",type:"row",locked:!1,attributes:{backgroundColor:"#f5f7fb",padding:{top:16,right:24,bottom:16,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-foot",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-foot",type:"text",values:{content:'<p style="color:#64748b;font-size:12px;">© Acme · <a href="https://example.com/unsubscribe">Unsubscribe</a></p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"center"}}]}]}]}}},Pt={id:"starter-transactional",name:"Transactional (order confirmation)",description:"Order confirmation pattern with summary and a primary button.",category:"transactional",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Order confirmation",previewText:"Order {{orderNumber}} is on its way.",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#ffffff",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-h",type:"row",locked:!1,attributes:{padding:{top:32,right:24,bottom:8,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-h",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-h",type:"text",values:{content:'<h1 style="font-size:24px;margin:0 0 8px;">Thanks for your order, {{firstName}}</h1><p style="margin:0;">Order <strong>{{orderNumber}}</strong> is on its way.</p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"left"}}]}]},{id:"r-summary",type:"row",locked:!1,attributes:{backgroundColor:"#f8fafc",padding:{top:16,right:24,bottom:16,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-summary",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-summary",type:"text",values:{content:'<p style="margin:0 0 8px;"><strong>Summary</strong></p><p style="margin:0;">{{itemCount}} item(s) · {{total}}</p><p style="margin:8px 0 0;color:#64748b;font-size:12px;">Estimated delivery: {{deliveryDate}}</p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"left"}}]}]},{id:"r-cta",type:"row",locked:!1,attributes:{padding:{top:24,right:24,bottom:24,left:24},fullWidth:!1},columnRatios:[12],columns:[{id:"c-cta",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-cta",type:"button",values:{content:"<p>View order</p>",href:"https://example.com/orders/{{orderNumber}}",backgroundColor:"#0f172a",textColor:"#ffffff",borderRadius:6,padding:{top:0,right:0,bottom:0,left:0},innerPadding:{top:12,right:24,bottom:12,left:24},fontSize:16,fontWeight:"600",alignment:"left",fullWidth:!1}}]}]}]}}},Vt={id:"starter-promo",name:"Promo / Sale",description:"Two-column product grid with a primary CTA and a social-link footer.",category:"promo",createdAt:f,updatedAt:f,document:{version:"1.0",metadata:{name:"Spring sale",previewText:"Two days only — 30% off.",createdAt:f,updatedAt:f},body:{attributes:{width:600,backgroundColor:"#fdf6ee",fontFamily:"Inter, sans-serif",contentAlignment:"center"},rows:[{id:"r-hero",type:"row",locked:!1,attributes:{padding:{top:0,right:0,bottom:0,left:0},fullWidth:!0},columnRatios:[12],columns:[{id:"c-hero",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"middle"},blocks:[{id:"b-hero",type:"hero",values:{backgroundUrl:"https://placehold.co/600x240/e76f51/ffffff?text=30%25+off",backgroundPosition:"center center",mode:"fluid-height",width:600,height:240,verticalAlign:"middle",padding:{top:0,right:0,bottom:0,left:0},innerPadding:{top:32,right:32,bottom:32,left:32},backgroundColor:"#e76f51",content:'<h1 style="color:#ffffff;font-size:36px;margin:0 0 8px;">30% off, this weekend only</h1><p style="color:#ffffff;font-size:16px;margin:0;">Code <strong>SPRING30</strong> at checkout.</p>'}}]}]},{id:"r-grid",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:24,right:16,bottom:24,left:16},fullWidth:!1},columnRatios:[6,6],columns:[{id:"c-l",type:"column",attributes:{padding:{top:0,right:8,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-l-img",type:"image",values:{src:"https://placehold.co/280x200",alt:"Linen shirt",width:"auto",href:"https://example.com/p/shirt",padding:{top:0,right:0,bottom:8,left:0},alignment:"center",borderRadius:6}},{id:"b-l-txt",type:"text",values:{content:'<p style="text-align:center;margin:0;"><strong>Linen shirt</strong><br><span style="color:#64748b;">$48 · was $69</span></p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"center"}}]},{id:"c-r",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:8},verticalAlign:"top"},blocks:[{id:"b-r-img",type:"image",values:{src:"https://placehold.co/280x200",alt:"Wool jumper",width:"auto",href:"https://example.com/p/jumper",padding:{top:0,right:0,bottom:8,left:0},alignment:"center",borderRadius:6}},{id:"b-r-txt",type:"text",values:{content:'<p style="text-align:center;margin:0;"><strong>Wool jumper</strong><br><span style="color:#64748b;">$84 · was $120</span></p>',padding:{top:0,right:0,bottom:0,left:0},lineHeight:"1.5",textAlign:"center"}}]}]},{id:"r-cta",type:"row",locked:!1,attributes:{backgroundColor:"#ffffff",padding:{top:8,right:16,bottom:24,left:16},fullWidth:!1},columnRatios:[12],columns:[{id:"c-cta",type:"column",attributes:{padding:{top:0,right:0,bottom:0,left:0},verticalAlign:"top"},blocks:[{id:"b-cta",type:"button",values:{content:"<p>Shop the sale</p>",href:"https://example.com/sale",backgroundColor:"#0f172a",textColor:"#ffffff",borderRadius:6,padding:{top:8,right:0,bottom:8,left:0},innerPadding:{top:14,right:28,bottom:14,left:28},fontSize:16,fontWeight:"600",alignment:"center",fullWidth:!0}}]}]}]}}},L=Object.freeze([Wt,Dt,Pt,Vt]);function O(){return L.map(o=>structuredClone(o))}function Lt(o){const t=L.find(e=>e.id===o);return t?structuredClone(t):null}class Ot{constructor(t={}){if(this._byId=new Map,t.includeStarters!==!1)for(const e of O())this._byId.set(e.id,e);if(t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(){return Array.from(this._byId.values()).map(t=>structuredClone(t))}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("Template.id is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}}class Nt{constructor(t={}){if(this._byId=new Map,t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(){return Array.from(this._byId.values()).map(t=>structuredClone(t))}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("BrandKit.id is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}}class jt{constructor(t={}){if(this._byId=new Map,t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(t={}){let n=Array.from(this._byId.values()).map(i=>structuredClone(i)).filter(i=>zt(i,t));n.sort((i,l)=>i.updatedAt<l.updatedAt?1:i.updatedAt>l.updatedAt?-1:0);const r=t.offset??0,s=t.limit;return n=n.slice(r,s!==void 0?r+s:void 0),n}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("Asset.id is required");if(!t.src)throw new Error("Asset.src is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),e.folder||(e.folder="/"),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}async listFolders(){const t=new Set;for(const e of this._byId.values())t.add(e.folder||"/");return Array.from(t).sort()}}function zt(o,t){if(t.folder&&(o.folder||"/")!==t.folder)return!1;if(t.tags&&t.tags.length>0){const e=new Set(o.tags??[]);if(!t.tags.every(n=>e.has(n)))return!1}if(t.search){const e=t.search.toLowerCase();if(![o.name,o.alt??"",...o.tags??[]].join(" ").toLowerCase().includes(e))return!1}return!0}class qt{constructor(t={}){if(this._byId=new Map,t.seed)for(const e of t.seed)this._byId.set(e.id,e)}async list(){return Array.from(this._byId.values()).map(t=>structuredClone(t))}async get(t){const e=this._byId.get(t);return e?structuredClone(e):null}async save(t){if(!t.id)throw new Error("LibraryEntry.id is required");const e=structuredClone(t);e.updatedAt=new Date().toISOString(),this._byId.has(e.id)||(e.createdAt=e.updatedAt),this._byId.set(e.id,e)}async delete(t){this._byId.delete(t)}}function Ut(o){const t=structuredClone(o);return t.id=g(),t.columns.forEach(e=>{e.id=g(),e.blocks.forEach(n=>{n.id=g()})}),t}const Ft=[{id:"unsubscribe",label:"Unsubscribe",href:"{{unsubscribe_url}}"},{id:"view-in-browser",label:"View in browser",href:"{{view_in_browser_url}}"},{id:"email",label:"Email address",prompt:"email"},{id:"phone",label:"Phone number",prompt:"tel"}];exports.EditorState=S;exports.HISTORY_PLUGIN_NAME=C;exports.InMemoryAssetStorage=jt;exports.InMemoryBrandKitStorage=Nt;exports.InMemoryRowLibraryStorage=qt;exports.InMemoryTemplateStorage=Ot;exports.PluginRegistry=Ht;exports.SYSTEM_LINK_TYPES=Ft;exports.Transaction=M;exports.addColumn=pt;exports.canRedo=V;exports.canUndo=P;exports.cloneRowWithNewIds=Ut;exports.createBlock=J;exports.createBlockSelection=v;exports.createBodySelection=et;exports.createColumn=T;exports.createColumnSelection=tt;exports.createDefaultDocument=E;exports.createDocStep=m;exports.createHistoryPlugin=Mt;exports.createRow=Q;exports.createRowSelection=A;exports.deepEqual=_;exports.defaultSpacing=b;exports.deleteBlock=rt;exports.deleteRow=ct;exports.duplicateBlock=lt;exports.duplicateRow=ut;exports.generateId=g;exports.getAllBlockDefinitions=vt;exports.getBlockDefinition=St;exports.getDefaultValues=y;exports.getStarterTemplate=Lt;exports.getStarterTemplates=O;exports.insertBlock=nt;exports.insertRow=at;exports.isKnownBlockType=At;exports.isValidDocument=kt;exports.moveBlock=it;exports.moveRow=dt;exports.redo=Et;exports.registerBlock=D;exports.removeColumn=mt;exports.resizeColumns=gt;exports.selectionsEqual=ot;exports.undo=$t;exports.updateBlock=st;exports.updateRowAttributes=ft;exports.validateDocument=W;
|
package/dist/index.d.ts
CHANGED
|
@@ -186,6 +186,13 @@ export declare function canRedo(history: HistoryState): boolean;
|
|
|
186
186
|
|
|
187
187
|
export declare function canUndo(history: HistoryState): boolean;
|
|
188
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Deep-clone a row and assign fresh ids to the row, every column, and every
|
|
191
|
+
* block. Used when inserting a saved library row so it never collides with
|
|
192
|
+
* existing node ids. (Same id-regeneration the `duplicateRow` command performs.)
|
|
193
|
+
*/
|
|
194
|
+
export declare function cloneRowWithNewIds(row: RowNode): RowNode;
|
|
195
|
+
|
|
189
196
|
export declare interface ColumnNode {
|
|
190
197
|
id: string;
|
|
191
198
|
type: 'column';
|
|
@@ -280,6 +287,31 @@ export declare interface EditorConfig {
|
|
|
280
287
|
* directly; a `BrandKitStorage` is resolved lazily on demand.
|
|
281
288
|
*/
|
|
282
289
|
brandKit?: BrandKit | BrandKitStorage;
|
|
290
|
+
/**
|
|
291
|
+
* Optional host-registered fonts. They appear as options in the editor font
|
|
292
|
+
* picker and, when a `url` is set, are emitted by the renderer as `<mj-font>`
|
|
293
|
+
* so email clients load them. Family stacks should include email-safe
|
|
294
|
+
* fallbacks.
|
|
295
|
+
*/
|
|
296
|
+
fontConfig?: FontDefinition[];
|
|
297
|
+
/**
|
|
298
|
+
* Optional persistence for the user's saved-rows library. When unset, the
|
|
299
|
+
* editor falls back to an in-memory store so the "Saved" palette tab works
|
|
300
|
+
* in-session. A filesystem implementation ships in `@lit-pigeon/mcp-server`.
|
|
301
|
+
*/
|
|
302
|
+
rowLibrary?: RowLibraryStorage;
|
|
303
|
+
/**
|
|
304
|
+
* Optional host-registered link types (label + href template) shown in the
|
|
305
|
+
* link editor and button panel alongside the built-in system links
|
|
306
|
+
* (`SYSTEM_LINK_TYPES`). The host/SSR resolves any `{{…}}` templates at send.
|
|
307
|
+
*/
|
|
308
|
+
linkTypes?: LinkType[];
|
|
309
|
+
/** Active locale code (e.g. 'fr', 'ar'). Defaults to 'en'. */
|
|
310
|
+
locale?: string;
|
|
311
|
+
/** Host-supplied per-locale catalogs, merged over the built-in `en` baseline. */
|
|
312
|
+
messages?: Record<string, Record<string, string>>;
|
|
313
|
+
/** Explicit text direction. When unset, derived from `locale`. */
|
|
314
|
+
dir?: 'ltr' | 'rtl';
|
|
283
315
|
}
|
|
284
316
|
|
|
285
317
|
export declare class EditorState {
|
|
@@ -301,6 +333,19 @@ export declare interface EditorStateSnapshot {
|
|
|
301
333
|
createTransaction(): TransactionSnapshot;
|
|
302
334
|
}
|
|
303
335
|
|
|
336
|
+
/**
|
|
337
|
+
* A web/brand font a host registers so it appears in the editor font picker
|
|
338
|
+
* and (when `url` is set) is emitted by the renderer as `<mj-font>`.
|
|
339
|
+
*/
|
|
340
|
+
export declare interface FontDefinition {
|
|
341
|
+
/** Display name shown in the font picker. */
|
|
342
|
+
name: string;
|
|
343
|
+
/** CSS font-family stack, including email-safe fallbacks (e.g. "Inter, Arial, sans-serif"). */
|
|
344
|
+
family: string;
|
|
345
|
+
/** Optional stylesheet URL that loads the web font (e.g. a Google Fonts CSS link). */
|
|
346
|
+
url?: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
304
349
|
export declare function generateId(): string;
|
|
305
350
|
|
|
306
351
|
export declare function getAllBlockDefinitions(): BlockDefinition[];
|
|
@@ -404,6 +449,25 @@ export declare interface InMemoryBrandKitStorageOptions {
|
|
|
404
449
|
seed?: BrandKit[];
|
|
405
450
|
}
|
|
406
451
|
|
|
452
|
+
/**
|
|
453
|
+
* Default `RowLibraryStorage` — `Map`-backed, per-process. Mirrors
|
|
454
|
+
* `InMemoryTemplateStorage`: deep-clones on read so callers can't poison the
|
|
455
|
+
* store by mutating returned objects.
|
|
456
|
+
*/
|
|
457
|
+
export declare class InMemoryRowLibraryStorage implements RowLibraryStorage {
|
|
458
|
+
private readonly _byId;
|
|
459
|
+
constructor(opts?: InMemoryRowLibraryStorageOptions);
|
|
460
|
+
list(): Promise<LibraryEntry[]>;
|
|
461
|
+
get(id: string): Promise<LibraryEntry | null>;
|
|
462
|
+
save(entry: LibraryEntry): Promise<void>;
|
|
463
|
+
delete(id: string): Promise<void>;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export declare interface InMemoryRowLibraryStorageOptions {
|
|
467
|
+
/** Entries to seed the store with on construction. */
|
|
468
|
+
seed?: LibraryEntry[];
|
|
469
|
+
}
|
|
470
|
+
|
|
407
471
|
/**
|
|
408
472
|
* Default `TemplateStorage` implementation — backs templates in a `Map`
|
|
409
473
|
* inside a single process. Suitable for the editor's default config, the
|
|
@@ -436,6 +500,33 @@ export declare function isKnownBlockType(type: string): type is BlockType;
|
|
|
436
500
|
|
|
437
501
|
export declare function isValidDocument(doc: unknown): doc is PigeonDocument;
|
|
438
502
|
|
|
503
|
+
/** A user-saved reusable row. */
|
|
504
|
+
export declare interface LibraryEntry {
|
|
505
|
+
/** Stable, URL-safe slug; doubles as filename when persisted. */
|
|
506
|
+
id: string;
|
|
507
|
+
/** Display name shown in the Saved tab. */
|
|
508
|
+
name: string;
|
|
509
|
+
/** What the entry holds. Only 'row' is supported now. */
|
|
510
|
+
kind: 'row';
|
|
511
|
+
/** The saved row (with its columns/blocks). */
|
|
512
|
+
node: RowNode;
|
|
513
|
+
/** ISO-8601 timestamps. */
|
|
514
|
+
createdAt: string;
|
|
515
|
+
updatedAt: string;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/** A selectable "special link" surfaced in the link editor and button panel. */
|
|
519
|
+
export declare interface LinkType {
|
|
520
|
+
/** Stable id (also the picker option value). */
|
|
521
|
+
id: string;
|
|
522
|
+
/** Label shown in the picker. */
|
|
523
|
+
label: string;
|
|
524
|
+
/** Href inserted on select (e.g. "{{unsubscribe_url}}"). Omitted for guided types. */
|
|
525
|
+
href?: string;
|
|
526
|
+
/** When set, the picker prompts for a value and builds `mailto:`/`tel:`. */
|
|
527
|
+
prompt?: 'email' | 'tel';
|
|
528
|
+
}
|
|
529
|
+
|
|
439
530
|
export declare interface MergeTag {
|
|
440
531
|
name: string;
|
|
441
532
|
label: string;
|
|
@@ -581,6 +672,11 @@ export declare interface RenderOptions {
|
|
|
581
672
|
* Set to false to opt out (useful for testing the bare renderer output).
|
|
582
673
|
*/
|
|
583
674
|
outlookWorkarounds?: boolean;
|
|
675
|
+
/**
|
|
676
|
+
* Web fonts to emit as `<mj-font>` in the document head. Each font with a
|
|
677
|
+
* `url` produces one stylesheet link; URL-less fonts are ignored.
|
|
678
|
+
*/
|
|
679
|
+
fonts?: FontDefinition[];
|
|
584
680
|
}
|
|
585
681
|
|
|
586
682
|
export declare interface RenderResult {
|
|
@@ -590,6 +686,14 @@ export declare interface RenderResult {
|
|
|
590
686
|
|
|
591
687
|
export declare function resizeColumns(rowId: string, ratios: number[]): Command;
|
|
592
688
|
|
|
689
|
+
/** Pluggable persistence for the row library. Mirrors {@link TemplateStorage}. */
|
|
690
|
+
export declare interface RowLibraryStorage {
|
|
691
|
+
list(): Promise<LibraryEntry[]>;
|
|
692
|
+
get(id: string): Promise<LibraryEntry | null>;
|
|
693
|
+
save(entry: LibraryEntry): Promise<void>;
|
|
694
|
+
delete(id: string): Promise<void>;
|
|
695
|
+
}
|
|
696
|
+
|
|
593
697
|
export declare interface RowNode {
|
|
594
698
|
id: string;
|
|
595
699
|
type: 'row';
|
|
@@ -662,6 +766,13 @@ export declare interface Step {
|
|
|
662
766
|
invert(doc: PigeonDocument): Step;
|
|
663
767
|
}
|
|
664
768
|
|
|
769
|
+
/**
|
|
770
|
+
* Built-in system link types. `unsubscribe`/`view-in-browser` emit fixed
|
|
771
|
+
* `{{…}}` placeholder hrefs (conventional ESP tokens, resolved by the host at
|
|
772
|
+
* send time); `email`/`phone` prompt for a value and build `mailto:`/`tel:`.
|
|
773
|
+
*/
|
|
774
|
+
export declare const SYSTEM_LINK_TYPES: LinkType[];
|
|
775
|
+
|
|
665
776
|
export declare interface Template {
|
|
666
777
|
/** Stable, URL-safe slug. Doubles as filename when persisted. */
|
|
667
778
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { produce as T } from "immer";
|
|
2
|
-
import { nanoid as
|
|
3
|
-
class
|
|
2
|
+
import { nanoid as H } from "nanoid";
|
|
3
|
+
class E {
|
|
4
4
|
constructor(t) {
|
|
5
5
|
this._steps = [], this._selection = null, this._selectionSet = !1, this._meta = /* @__PURE__ */ new Map(), this._doc = t;
|
|
6
6
|
}
|
|
@@ -44,37 +44,37 @@ function m(o, t, e, n) {
|
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
return
|
|
47
|
+
function g() {
|
|
48
|
+
return H(10);
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function h(o = 0) {
|
|
51
51
|
return { top: o, right: o, bottom: o, left: o };
|
|
52
52
|
}
|
|
53
|
-
function
|
|
53
|
+
function V() {
|
|
54
54
|
return {
|
|
55
55
|
content: "<p>Enter your text here</p>",
|
|
56
|
-
padding:
|
|
56
|
+
padding: h(10),
|
|
57
57
|
lineHeight: "1.5",
|
|
58
58
|
textAlign: "left"
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
function
|
|
61
|
+
function P() {
|
|
62
62
|
return {
|
|
63
63
|
src: "",
|
|
64
64
|
alt: "",
|
|
65
65
|
width: "auto",
|
|
66
|
-
padding:
|
|
66
|
+
padding: h(10),
|
|
67
67
|
alignment: "center"
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
function
|
|
70
|
+
function D() {
|
|
71
71
|
return {
|
|
72
72
|
content: "<p>Click me</p>",
|
|
73
73
|
href: "#",
|
|
74
74
|
backgroundColor: "#3b82f6",
|
|
75
75
|
textColor: "#ffffff",
|
|
76
76
|
borderRadius: 4,
|
|
77
|
-
padding:
|
|
77
|
+
padding: h(10),
|
|
78
78
|
innerPadding: { top: 12, right: 24, bottom: 12, left: 24 },
|
|
79
79
|
fontSize: 16,
|
|
80
80
|
fontWeight: "600",
|
|
@@ -87,7 +87,7 @@ function L() {
|
|
|
87
87
|
borderColor: "#e2e8f0",
|
|
88
88
|
borderWidth: 1,
|
|
89
89
|
borderStyle: "solid",
|
|
90
|
-
padding:
|
|
90
|
+
padding: h(10),
|
|
91
91
|
width: "100%"
|
|
92
92
|
};
|
|
93
93
|
}
|
|
@@ -100,13 +100,13 @@ function j() {
|
|
|
100
100
|
iconSize: 32,
|
|
101
101
|
spacing: 8,
|
|
102
102
|
alignment: "center",
|
|
103
|
-
padding:
|
|
103
|
+
padding: h(10)
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
function z() {
|
|
107
107
|
return {
|
|
108
108
|
content: "",
|
|
109
|
-
padding:
|
|
109
|
+
padding: h(0)
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
function N() {
|
|
@@ -117,8 +117,8 @@ function N() {
|
|
|
117
117
|
width: 600,
|
|
118
118
|
height: 400,
|
|
119
119
|
verticalAlign: "middle",
|
|
120
|
-
padding:
|
|
121
|
-
innerPadding:
|
|
120
|
+
padding: h(0),
|
|
121
|
+
innerPadding: h(20),
|
|
122
122
|
backgroundColor: "#ffffff",
|
|
123
123
|
content: '<p style="color:#ffffff;font-size:24px;">Hero Title</p>'
|
|
124
124
|
};
|
|
@@ -132,16 +132,16 @@ function q() {
|
|
|
132
132
|
],
|
|
133
133
|
hamburger: "hamburger",
|
|
134
134
|
alignment: "center",
|
|
135
|
-
padding:
|
|
135
|
+
padding: h(10),
|
|
136
136
|
linkColor: "#000000",
|
|
137
137
|
linkFontSize: 14,
|
|
138
138
|
linkPadding: "10px 15px"
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
const $ = {
|
|
142
|
-
text:
|
|
143
|
-
image:
|
|
144
|
-
button:
|
|
142
|
+
text: V,
|
|
143
|
+
image: P,
|
|
144
|
+
button: D,
|
|
145
145
|
divider: L,
|
|
146
146
|
spacer: O,
|
|
147
147
|
social: j,
|
|
@@ -149,7 +149,7 @@ const $ = {
|
|
|
149
149
|
hero: N,
|
|
150
150
|
navbar: q
|
|
151
151
|
};
|
|
152
|
-
function
|
|
152
|
+
function w(o) {
|
|
153
153
|
const t = $[o];
|
|
154
154
|
if (!t)
|
|
155
155
|
throw new Error(`Unknown block type: ${o}`);
|
|
@@ -159,18 +159,18 @@ let I = null;
|
|
|
159
159
|
function U(o) {
|
|
160
160
|
I = o;
|
|
161
161
|
}
|
|
162
|
-
function
|
|
162
|
+
function gt(o, t) {
|
|
163
163
|
const e = $[o];
|
|
164
164
|
if (e)
|
|
165
165
|
return {
|
|
166
|
-
id:
|
|
166
|
+
id: g(),
|
|
167
167
|
type: o,
|
|
168
168
|
values: { ...e(), ...t }
|
|
169
169
|
};
|
|
170
170
|
const n = I == null ? void 0 : I(o);
|
|
171
171
|
if (n)
|
|
172
172
|
return {
|
|
173
|
-
id:
|
|
173
|
+
id: g(),
|
|
174
174
|
type: o,
|
|
175
175
|
values: { ...structuredClone(n), ...t }
|
|
176
176
|
};
|
|
@@ -178,10 +178,10 @@ function bt(o, t) {
|
|
|
178
178
|
}
|
|
179
179
|
function B(o = []) {
|
|
180
180
|
return {
|
|
181
|
-
id:
|
|
181
|
+
id: g(),
|
|
182
182
|
type: "column",
|
|
183
183
|
attributes: {
|
|
184
|
-
padding:
|
|
184
|
+
padding: h(0),
|
|
185
185
|
verticalAlign: "top"
|
|
186
186
|
},
|
|
187
187
|
blocks: o
|
|
@@ -190,10 +190,10 @@ function B(o = []) {
|
|
|
190
190
|
function ht(o, t) {
|
|
191
191
|
const e = o ?? [B()], n = t ?? e.map(() => Math.floor(12 / e.length));
|
|
192
192
|
return {
|
|
193
|
-
id:
|
|
193
|
+
id: g(),
|
|
194
194
|
type: "row",
|
|
195
195
|
attributes: {
|
|
196
|
-
padding:
|
|
196
|
+
padding: h(0),
|
|
197
197
|
fullWidth: !1
|
|
198
198
|
},
|
|
199
199
|
columns: e,
|
|
@@ -221,18 +221,18 @@ function F(o = "Untitled") {
|
|
|
221
221
|
}
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
|
-
class
|
|
224
|
+
class S {
|
|
225
225
|
constructor(t, e, n, r) {
|
|
226
226
|
this.doc = t, this.selection = e, this.plugins = n, this._pluginList = r;
|
|
227
227
|
}
|
|
228
228
|
static create(t = {}) {
|
|
229
|
-
const e = t.doc ?? F(), n = t.plugins ?? [], r = /* @__PURE__ */ new Map(), s = new
|
|
229
|
+
const e = t.doc ?? F(), n = t.plugins ?? [], r = /* @__PURE__ */ new Map(), s = new S(e, null, r, n);
|
|
230
230
|
for (const i of n)
|
|
231
231
|
i.init && r.set(i.name, i.init(s));
|
|
232
232
|
return s;
|
|
233
233
|
}
|
|
234
234
|
createTransaction() {
|
|
235
|
-
return new
|
|
235
|
+
return new E(this.doc);
|
|
236
236
|
}
|
|
237
237
|
apply(t) {
|
|
238
238
|
let e = t.doc;
|
|
@@ -245,7 +245,7 @@ class A {
|
|
|
245
245
|
t.steps.length > 0 && !t.getMeta("skipTimestamp") && (e = T(e, (i) => {
|
|
246
246
|
i.metadata.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
247
247
|
}));
|
|
248
|
-
const s = new
|
|
248
|
+
const s = new S(e, n, r, this._pluginList);
|
|
249
249
|
for (const i of this._pluginList)
|
|
250
250
|
i.onStateChange && i.onStateChange(s, this);
|
|
251
251
|
return s;
|
|
@@ -254,7 +254,7 @@ class A {
|
|
|
254
254
|
return this.plugins.get(t);
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
|
-
function
|
|
257
|
+
function A(o, t, e) {
|
|
258
258
|
return { type: "block", rowId: o, columnId: t, blockId: e };
|
|
259
259
|
}
|
|
260
260
|
function C(o) {
|
|
@@ -291,7 +291,7 @@ function xt(o, t, e, n) {
|
|
|
291
291
|
d.body.rows[i.rowIndex].columns[i.columnIndex].blocks.splice(c, 1);
|
|
292
292
|
}
|
|
293
293
|
);
|
|
294
|
-
a.addStep(u), a.setSelection(
|
|
294
|
+
a.addStep(u), a.setSelection(A(o, t, e.id)), s(a);
|
|
295
295
|
}
|
|
296
296
|
return !0;
|
|
297
297
|
};
|
|
@@ -333,8 +333,8 @@ function vt(o, t, e, n) {
|
|
|
333
333
|
"updateBlock",
|
|
334
334
|
`body.rows[${i.rowIndex}].columns[${i.columnIndex}].blocks[${c}]`,
|
|
335
335
|
(p) => {
|
|
336
|
-
const
|
|
337
|
-
Object.assign(
|
|
336
|
+
const b = p.body.rows[i.rowIndex].columns[i.columnIndex].blocks[c];
|
|
337
|
+
Object.assign(b.values, n);
|
|
338
338
|
},
|
|
339
339
|
(p) => {
|
|
340
340
|
p.body.rows[i.rowIndex].columns[i.columnIndex].blocks[c] = a;
|
|
@@ -345,7 +345,7 @@ function vt(o, t, e, n) {
|
|
|
345
345
|
return !0;
|
|
346
346
|
};
|
|
347
347
|
}
|
|
348
|
-
function
|
|
348
|
+
function St(o, t, e, n, r, s) {
|
|
349
349
|
return (i, l) => {
|
|
350
350
|
const c = k(i.doc, o, t);
|
|
351
351
|
if (!c) return !1;
|
|
@@ -354,43 +354,43 @@ function At(o, t, e, n, r, s) {
|
|
|
354
354
|
const d = k(i.doc, n, r);
|
|
355
355
|
if (!d) return !1;
|
|
356
356
|
if (l) {
|
|
357
|
-
const p = i.createTransaction(),
|
|
357
|
+
const p = i.createTransaction(), b = m(
|
|
358
358
|
"moveBlock",
|
|
359
359
|
"body.rows",
|
|
360
|
-
(
|
|
361
|
-
const [v] =
|
|
362
|
-
|
|
360
|
+
(y) => {
|
|
361
|
+
const [v] = y.body.rows[c.rowIndex].columns[c.columnIndex].blocks.splice(u, 1);
|
|
362
|
+
y.body.rows[d.rowIndex].columns[d.columnIndex].blocks.splice(s, 0, v);
|
|
363
363
|
},
|
|
364
|
-
(
|
|
365
|
-
const [v] =
|
|
366
|
-
|
|
364
|
+
(y) => {
|
|
365
|
+
const [v] = y.body.rows[d.rowIndex].columns[d.columnIndex].blocks.splice(s, 1);
|
|
366
|
+
y.body.rows[c.rowIndex].columns[c.columnIndex].blocks.splice(u, 0, v);
|
|
367
367
|
}
|
|
368
368
|
);
|
|
369
|
-
p.addStep(
|
|
369
|
+
p.addStep(b), p.setSelection(A(n, r, e)), l(p);
|
|
370
370
|
}
|
|
371
371
|
return !0;
|
|
372
372
|
};
|
|
373
373
|
}
|
|
374
|
-
function
|
|
374
|
+
function At(o, t, e) {
|
|
375
375
|
return (n, r) => {
|
|
376
376
|
const s = k(n.doc, o, t);
|
|
377
377
|
if (!s) return !1;
|
|
378
378
|
const i = n.doc.body.rows[s.rowIndex].columns[s.columnIndex], l = i.blocks.findIndex((c) => c.id === e);
|
|
379
379
|
if (l === -1) return !1;
|
|
380
380
|
if (r) {
|
|
381
|
-
const c = i.blocks[l], a =
|
|
381
|
+
const c = i.blocks[l], a = g(), u = structuredClone(c);
|
|
382
382
|
u.id = a;
|
|
383
|
-
const d = l + 1, p = n.createTransaction(),
|
|
383
|
+
const d = l + 1, p = n.createTransaction(), b = m(
|
|
384
384
|
"duplicateBlock",
|
|
385
385
|
`body.rows[${s.rowIndex}].columns[${s.columnIndex}].blocks`,
|
|
386
|
-
(
|
|
387
|
-
|
|
386
|
+
(y) => {
|
|
387
|
+
y.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(d, 0, u);
|
|
388
388
|
},
|
|
389
|
-
(
|
|
390
|
-
|
|
389
|
+
(y) => {
|
|
390
|
+
y.body.rows[s.rowIndex].columns[s.columnIndex].blocks.splice(d, 1);
|
|
391
391
|
}
|
|
392
392
|
);
|
|
393
|
-
p.addStep(
|
|
393
|
+
p.addStep(b), p.setSelection(A(o, t, a)), r(p);
|
|
394
394
|
}
|
|
395
395
|
return !0;
|
|
396
396
|
};
|
|
@@ -414,7 +414,7 @@ function Ct(o, t) {
|
|
|
414
414
|
return !0;
|
|
415
415
|
};
|
|
416
416
|
}
|
|
417
|
-
function
|
|
417
|
+
function _t(o) {
|
|
418
418
|
return (t, e) => {
|
|
419
419
|
const n = t.doc.body.rows.findIndex((r) => r.id === o);
|
|
420
420
|
if (n === -1) return !1;
|
|
@@ -434,7 +434,7 @@ function Rt(o) {
|
|
|
434
434
|
return !0;
|
|
435
435
|
};
|
|
436
436
|
}
|
|
437
|
-
function
|
|
437
|
+
function Rt(o, t) {
|
|
438
438
|
return (e, n) => {
|
|
439
439
|
const r = e.doc.body.rows.findIndex((s) => s.id === o);
|
|
440
440
|
if (r === -1 || r === t) return !1;
|
|
@@ -462,9 +462,9 @@ function Tt(o) {
|
|
|
462
462
|
if (n === -1) return !1;
|
|
463
463
|
if (e) {
|
|
464
464
|
const r = t.doc.body.rows[n], s = structuredClone(r);
|
|
465
|
-
s.id =
|
|
466
|
-
a.id =
|
|
467
|
-
u.id =
|
|
465
|
+
s.id = g(), s.columns.forEach((a) => {
|
|
466
|
+
a.id = g(), a.blocks.forEach((u) => {
|
|
467
|
+
u.id = g();
|
|
468
468
|
});
|
|
469
469
|
});
|
|
470
470
|
const i = n + 1, l = t.createTransaction(), c = m(
|
|
@@ -509,7 +509,7 @@ function Bt(o) {
|
|
|
509
509
|
const r = t.doc.body.rows[n];
|
|
510
510
|
if (r.locked || r.columns.length >= 4) return !1;
|
|
511
511
|
if (e) {
|
|
512
|
-
const s = B(), i = r.columns.length + 1, l =
|
|
512
|
+
const s = B(), i = r.columns.length + 1, l = M(i), c = [...r.columnRatios], a = t.createTransaction(), u = m(
|
|
513
513
|
"addColumn",
|
|
514
514
|
`body.rows[${n}]`,
|
|
515
515
|
(d) => {
|
|
@@ -524,7 +524,7 @@ function Bt(o) {
|
|
|
524
524
|
return !0;
|
|
525
525
|
};
|
|
526
526
|
}
|
|
527
|
-
function
|
|
527
|
+
function Mt(o, t) {
|
|
528
528
|
return (e, n) => {
|
|
529
529
|
const r = e.doc.body.rows.findIndex((l) => l.id === o);
|
|
530
530
|
if (r === -1) return !1;
|
|
@@ -533,14 +533,14 @@ function Ht(o, t) {
|
|
|
533
533
|
const i = s.columns.findIndex((l) => l.id === t);
|
|
534
534
|
if (i === -1) return !1;
|
|
535
535
|
if (n) {
|
|
536
|
-
const l = structuredClone(s.columns[i]), c = [...s.columnRatios], a = s.columns.length - 1, u =
|
|
536
|
+
const l = structuredClone(s.columns[i]), c = [...s.columnRatios], a = s.columns.length - 1, u = M(a), d = e.createTransaction(), p = m(
|
|
537
537
|
"removeColumn",
|
|
538
538
|
`body.rows[${r}]`,
|
|
539
|
-
(
|
|
540
|
-
|
|
539
|
+
(b) => {
|
|
540
|
+
b.body.rows[r].columns.splice(i, 1), b.body.rows[r].columnRatios = u;
|
|
541
541
|
},
|
|
542
|
-
(
|
|
543
|
-
|
|
542
|
+
(b) => {
|
|
543
|
+
b.body.rows[r].columns.splice(i, 0, l), b.body.rows[r].columnRatios = c;
|
|
544
544
|
}
|
|
545
545
|
);
|
|
546
546
|
d.addStep(p), n(d);
|
|
@@ -548,7 +548,7 @@ function Ht(o, t) {
|
|
|
548
548
|
return !0;
|
|
549
549
|
};
|
|
550
550
|
}
|
|
551
|
-
function
|
|
551
|
+
function Wt(o, t) {
|
|
552
552
|
return (e, n) => {
|
|
553
553
|
const r = e.doc.body.rows.findIndex((l) => l.id === o);
|
|
554
554
|
if (r === -1) return !1;
|
|
@@ -570,14 +570,14 @@ function Mt(o, t) {
|
|
|
570
570
|
return !0;
|
|
571
571
|
};
|
|
572
572
|
}
|
|
573
|
-
function
|
|
573
|
+
function M(o) {
|
|
574
574
|
const t = Math.floor(12 / o), e = 12 - t * o, n = new Array(o).fill(t);
|
|
575
575
|
for (let r = 0; r < e; r++)
|
|
576
576
|
n[r] += 1;
|
|
577
577
|
return n;
|
|
578
578
|
}
|
|
579
579
|
const K = ["text", "image", "button", "divider", "spacer", "social", "html", "hero", "navbar"];
|
|
580
|
-
function
|
|
580
|
+
function Y(o) {
|
|
581
581
|
const t = [];
|
|
582
582
|
if (!o || typeof o != "object")
|
|
583
583
|
return t.push({ path: "", message: "Document must be an object" }), t;
|
|
@@ -586,10 +586,10 @@ function G(o) {
|
|
|
586
586
|
return t.push({ path: "body", message: "Body is required" }), t;
|
|
587
587
|
const n = e.body;
|
|
588
588
|
return (!n.attributes || typeof n.attributes != "object") && t.push({ path: "body.attributes", message: "Body attributes are required" }), Array.isArray(n.rows) ? (n.rows.forEach((r, s) => {
|
|
589
|
-
t.push(...
|
|
589
|
+
t.push(...G(r, `body.rows[${s}]`));
|
|
590
590
|
}), t) : (t.push({ path: "body.rows", message: "Rows must be an array" }), t);
|
|
591
591
|
}
|
|
592
|
-
function
|
|
592
|
+
function G(o, t) {
|
|
593
593
|
const e = [];
|
|
594
594
|
return o.id || e.push({ path: `${t}.id`, message: "Row must have an id" }), o.type !== "row" && e.push({ path: `${t}.type`, message: 'Row type must be "row"' }), Array.isArray(o.columns) ? (Array.isArray(o.columnRatios) ? o.columnRatios.length !== o.columns.length && e.push({
|
|
595
595
|
path: `${t}.columnRatios`,
|
|
@@ -608,63 +608,63 @@ function Z(o, t) {
|
|
|
608
608
|
const e = [];
|
|
609
609
|
return o.id || e.push({ path: `${t}.id`, message: "Block must have an id" }), K.includes(o.type) || e.push({ path: `${t}.type`, message: `Invalid block type: ${o.type}` }), (!o.values || typeof o.values != "object") && e.push({ path: `${t}.values`, message: "Block must have values" }), e;
|
|
610
610
|
}
|
|
611
|
-
function
|
|
612
|
-
return
|
|
611
|
+
function Ht(o) {
|
|
612
|
+
return Y(o).length === 0;
|
|
613
613
|
}
|
|
614
614
|
const x = /* @__PURE__ */ new Map(), J = [
|
|
615
615
|
{
|
|
616
616
|
type: "text",
|
|
617
617
|
label: "Text",
|
|
618
618
|
icon: "text",
|
|
619
|
-
defaultValues:
|
|
619
|
+
defaultValues: w("text")
|
|
620
620
|
},
|
|
621
621
|
{
|
|
622
622
|
type: "image",
|
|
623
623
|
label: "Image",
|
|
624
624
|
icon: "image",
|
|
625
|
-
defaultValues:
|
|
625
|
+
defaultValues: w("image")
|
|
626
626
|
},
|
|
627
627
|
{
|
|
628
628
|
type: "button",
|
|
629
629
|
label: "Button",
|
|
630
630
|
icon: "button",
|
|
631
|
-
defaultValues:
|
|
631
|
+
defaultValues: w("button")
|
|
632
632
|
},
|
|
633
633
|
{
|
|
634
634
|
type: "divider",
|
|
635
635
|
label: "Divider",
|
|
636
636
|
icon: "divider",
|
|
637
|
-
defaultValues:
|
|
637
|
+
defaultValues: w("divider")
|
|
638
638
|
},
|
|
639
639
|
{
|
|
640
640
|
type: "spacer",
|
|
641
641
|
label: "Spacer",
|
|
642
642
|
icon: "spacer",
|
|
643
|
-
defaultValues:
|
|
643
|
+
defaultValues: w("spacer")
|
|
644
644
|
},
|
|
645
645
|
{
|
|
646
646
|
type: "social",
|
|
647
647
|
label: "Social",
|
|
648
648
|
icon: "social",
|
|
649
|
-
defaultValues:
|
|
649
|
+
defaultValues: w("social")
|
|
650
650
|
},
|
|
651
651
|
{
|
|
652
652
|
type: "html",
|
|
653
653
|
label: "HTML",
|
|
654
654
|
icon: "html",
|
|
655
|
-
defaultValues:
|
|
655
|
+
defaultValues: w("html")
|
|
656
656
|
},
|
|
657
657
|
{
|
|
658
658
|
type: "hero",
|
|
659
659
|
label: "Hero",
|
|
660
660
|
icon: "hero",
|
|
661
|
-
defaultValues:
|
|
661
|
+
defaultValues: w("hero")
|
|
662
662
|
},
|
|
663
663
|
{
|
|
664
664
|
type: "navbar",
|
|
665
665
|
label: "Navbar",
|
|
666
666
|
icon: "navbar",
|
|
667
|
-
defaultValues:
|
|
667
|
+
defaultValues: w("navbar")
|
|
668
668
|
}
|
|
669
669
|
];
|
|
670
670
|
function Q() {
|
|
@@ -678,13 +678,13 @@ function Q() {
|
|
|
678
678
|
function tt(o) {
|
|
679
679
|
x.set(o.type, o);
|
|
680
680
|
}
|
|
681
|
-
function
|
|
681
|
+
function Et(o) {
|
|
682
682
|
return x.get(o);
|
|
683
683
|
}
|
|
684
|
-
function
|
|
684
|
+
function Vt() {
|
|
685
685
|
return Array.from(x.values());
|
|
686
686
|
}
|
|
687
|
-
function
|
|
687
|
+
function Pt(o) {
|
|
688
688
|
return x.has(o);
|
|
689
689
|
}
|
|
690
690
|
Q();
|
|
@@ -727,10 +727,10 @@ function it(o) {
|
|
|
727
727
|
function lt(o) {
|
|
728
728
|
return o.redoStack.length > 0;
|
|
729
729
|
}
|
|
730
|
-
const
|
|
731
|
-
function
|
|
730
|
+
const _ = "history";
|
|
731
|
+
function Dt() {
|
|
732
732
|
return {
|
|
733
|
-
name:
|
|
733
|
+
name: _,
|
|
734
734
|
init() {
|
|
735
735
|
return ot();
|
|
736
736
|
},
|
|
@@ -750,7 +750,7 @@ function Et() {
|
|
|
750
750
|
};
|
|
751
751
|
}
|
|
752
752
|
function Lt(o, t) {
|
|
753
|
-
const e = o.plugins.get(
|
|
753
|
+
const e = o.plugins.get(_);
|
|
754
754
|
if (!e || !it(e)) return !1;
|
|
755
755
|
if (t) {
|
|
756
756
|
const { history: n, entry: r } = rt(e);
|
|
@@ -765,7 +765,7 @@ function Lt(o, t) {
|
|
|
765
765
|
return !0;
|
|
766
766
|
}
|
|
767
767
|
function Ot(o, t) {
|
|
768
|
-
const e = o.plugins.get(
|
|
768
|
+
const e = o.plugins.get(_);
|
|
769
769
|
if (!e || !lt(e)) return !1;
|
|
770
770
|
if (t) {
|
|
771
771
|
const { history: n, entry: r } = st(e);
|
|
@@ -807,15 +807,15 @@ class jt {
|
|
|
807
807
|
return this._plugins.has(t);
|
|
808
808
|
}
|
|
809
809
|
}
|
|
810
|
-
function
|
|
810
|
+
function R(o, t) {
|
|
811
811
|
if (o === t) return !0;
|
|
812
812
|
if (o == null || t == null || typeof o != typeof t) return !1;
|
|
813
813
|
if (Array.isArray(o))
|
|
814
|
-
return !Array.isArray(t) || o.length !== t.length ? !1 : o.every((e, n) =>
|
|
814
|
+
return !Array.isArray(t) || o.length !== t.length ? !1 : o.every((e, n) => R(e, t[n]));
|
|
815
815
|
if (typeof o == "object") {
|
|
816
816
|
const e = Object.keys(o), n = Object.keys(t);
|
|
817
817
|
return e.length !== n.length ? !1 : e.every(
|
|
818
|
-
(r) =>
|
|
818
|
+
(r) => R(
|
|
819
819
|
o[r],
|
|
820
820
|
t[r]
|
|
821
821
|
)
|
|
@@ -1236,12 +1236,12 @@ const f = "2026-05-26T10:00:00.000Z", ct = {
|
|
|
1236
1236
|
]
|
|
1237
1237
|
}
|
|
1238
1238
|
}
|
|
1239
|
-
},
|
|
1239
|
+
}, W = Object.freeze([ct, at, dt, ut]);
|
|
1240
1240
|
function ft() {
|
|
1241
|
-
return
|
|
1241
|
+
return W.map((o) => structuredClone(o));
|
|
1242
1242
|
}
|
|
1243
1243
|
function zt(o) {
|
|
1244
|
-
const t =
|
|
1244
|
+
const t = W.find((e) => e.id === o);
|
|
1245
1245
|
return t ? structuredClone(t) : null;
|
|
1246
1246
|
}
|
|
1247
1247
|
class Nt {
|
|
@@ -1331,52 +1331,90 @@ function pt(o, t) {
|
|
|
1331
1331
|
}
|
|
1332
1332
|
return !0;
|
|
1333
1333
|
}
|
|
1334
|
+
class Ft {
|
|
1335
|
+
constructor(t = {}) {
|
|
1336
|
+
if (this._byId = /* @__PURE__ */ new Map(), t.seed)
|
|
1337
|
+
for (const e of t.seed) this._byId.set(e.id, e);
|
|
1338
|
+
}
|
|
1339
|
+
async list() {
|
|
1340
|
+
return Array.from(this._byId.values()).map((t) => structuredClone(t));
|
|
1341
|
+
}
|
|
1342
|
+
async get(t) {
|
|
1343
|
+
const e = this._byId.get(t);
|
|
1344
|
+
return e ? structuredClone(e) : null;
|
|
1345
|
+
}
|
|
1346
|
+
async save(t) {
|
|
1347
|
+
if (!t.id) throw new Error("LibraryEntry.id is required");
|
|
1348
|
+
const e = structuredClone(t);
|
|
1349
|
+
e.updatedAt = (/* @__PURE__ */ new Date()).toISOString(), this._byId.has(e.id) || (e.createdAt = e.updatedAt), this._byId.set(e.id, e);
|
|
1350
|
+
}
|
|
1351
|
+
async delete(t) {
|
|
1352
|
+
this._byId.delete(t);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
function Kt(o) {
|
|
1356
|
+
const t = structuredClone(o);
|
|
1357
|
+
return t.id = g(), t.columns.forEach((e) => {
|
|
1358
|
+
e.id = g(), e.blocks.forEach((n) => {
|
|
1359
|
+
n.id = g();
|
|
1360
|
+
});
|
|
1361
|
+
}), t;
|
|
1362
|
+
}
|
|
1363
|
+
const Yt = [
|
|
1364
|
+
{ id: "unsubscribe", label: "Unsubscribe", href: "{{unsubscribe_url}}" },
|
|
1365
|
+
{ id: "view-in-browser", label: "View in browser", href: "{{view_in_browser_url}}" },
|
|
1366
|
+
{ id: "email", label: "Email address", prompt: "email" },
|
|
1367
|
+
{ id: "phone", label: "Phone number", prompt: "tel" }
|
|
1368
|
+
];
|
|
1334
1369
|
export {
|
|
1335
|
-
|
|
1336
|
-
|
|
1370
|
+
S as EditorState,
|
|
1371
|
+
_ as HISTORY_PLUGIN_NAME,
|
|
1337
1372
|
Ut as InMemoryAssetStorage,
|
|
1338
1373
|
qt as InMemoryBrandKitStorage,
|
|
1374
|
+
Ft as InMemoryRowLibraryStorage,
|
|
1339
1375
|
Nt as InMemoryTemplateStorage,
|
|
1340
1376
|
jt as PluginRegistry,
|
|
1341
|
-
|
|
1377
|
+
Yt as SYSTEM_LINK_TYPES,
|
|
1378
|
+
E as Transaction,
|
|
1342
1379
|
Bt as addColumn,
|
|
1343
1380
|
lt as canRedo,
|
|
1344
1381
|
it as canUndo,
|
|
1345
|
-
|
|
1346
|
-
|
|
1382
|
+
Kt as cloneRowWithNewIds,
|
|
1383
|
+
gt as createBlock,
|
|
1384
|
+
A as createBlockSelection,
|
|
1347
1385
|
wt as createBodySelection,
|
|
1348
1386
|
B as createColumn,
|
|
1349
1387
|
yt as createColumnSelection,
|
|
1350
1388
|
F as createDefaultDocument,
|
|
1351
1389
|
m as createDocStep,
|
|
1352
|
-
|
|
1390
|
+
Dt as createHistoryPlugin,
|
|
1353
1391
|
ht as createRow,
|
|
1354
1392
|
C as createRowSelection,
|
|
1355
|
-
|
|
1356
|
-
|
|
1393
|
+
R as deepEqual,
|
|
1394
|
+
h as defaultSpacing,
|
|
1357
1395
|
It as deleteBlock,
|
|
1358
|
-
|
|
1359
|
-
|
|
1396
|
+
_t as deleteRow,
|
|
1397
|
+
At as duplicateBlock,
|
|
1360
1398
|
Tt as duplicateRow,
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1399
|
+
g as generateId,
|
|
1400
|
+
Vt as getAllBlockDefinitions,
|
|
1401
|
+
Et as getBlockDefinition,
|
|
1402
|
+
w as getDefaultValues,
|
|
1365
1403
|
zt as getStarterTemplate,
|
|
1366
1404
|
ft as getStarterTemplates,
|
|
1367
1405
|
xt as insertBlock,
|
|
1368
1406
|
Ct as insertRow,
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1407
|
+
Pt as isKnownBlockType,
|
|
1408
|
+
Ht as isValidDocument,
|
|
1409
|
+
St as moveBlock,
|
|
1410
|
+
Rt as moveRow,
|
|
1373
1411
|
Ot as redo,
|
|
1374
1412
|
tt as registerBlock,
|
|
1375
|
-
|
|
1376
|
-
|
|
1413
|
+
Mt as removeColumn,
|
|
1414
|
+
Wt as resizeColumns,
|
|
1377
1415
|
kt as selectionsEqual,
|
|
1378
1416
|
Lt as undo,
|
|
1379
1417
|
vt as updateBlock,
|
|
1380
1418
|
$t as updateRowAttributes,
|
|
1381
|
-
|
|
1419
|
+
Y as validateDocument
|
|
1382
1420
|
};
|