From 8e51b28583af075b5385efb8d154e41d6f723cb0 Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Sat, 5 Sep 2026 13:19:45 +0530 Subject: [PATCH] fix(email-renderer): export builder rows as valid MJML columns --- packages/email-renderer/package.json | 2 +- packages/email-renderer/src/blocks.ts | 9 +++++++-- packages/email-renderer/test/email.test.ts | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/email-renderer/package.json b/packages/email-renderer/package.json index 4d4d5c0a..5c7cca90 100644 --- a/packages/email-renderer/package.json +++ b/packages/email-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/email-renderer", - "version": "0.1.16", + "version": "0.1.17", "type": "module", "description": "WRNexus block email renderers with HTML, text, AMP Email, and MJML interoperability.", "exports": { diff --git a/packages/email-renderer/src/blocks.ts b/packages/email-renderer/src/blocks.ts index d6dbe76d..232cbb1b 100644 --- a/packages/email-renderer/src/blocks.ts +++ b/packages/email-renderer/src/blocks.ts @@ -158,8 +158,13 @@ export const sectionBlock = defineBlock({ `
${slots.content}
`, node, ), - mjml: ({ node, slots }) => - `${slots.content}`, + mjml: ({ node, slots }) => { + const children = node.slots.content ?? []; + const body = children.length === 1 && children[0]?.type === "layout.columns" + ? slots.content + : `${slots.content}`; + return `${body}`; + }, }, textRenderer: ({ slots }) => `${slots.content}\n`, } satisfies BlockDefinition); diff --git a/packages/email-renderer/test/email.test.ts b/packages/email-renderer/test/email.test.ts index 96deba54..ddbad1da 100644 --- a/packages/email-renderer/test/email.test.ts +++ b/packages/email-renderer/test/email.test.ts @@ -57,6 +57,20 @@ const document: BlockDocument = { }; describe("email renderer", () => { + test("builder column rows export without nesting mj-column inside mj-column", async () => { + for (const count of [1,2,3,4]) { + const draft=structuredClone(document); + const content=draft.root.slots.content[0]!.slots.content; + draft.root.slots.content[0]!.slots.content=[{id:"columns",type:"layout.columns",version:1,props:{},styles:{},slots:{columns:Array.from({length:count},(_,index)=>({id:`column-${index}`,type:"layout.column",version:1,props:{width:`${100/count}%`},styles:{},slots:{content:index===0?content:[]}}))}}]; + const result=await renderEmail(draft,{mjml:true}); + expect(result.ok).toBe(true); + if(!result.ok)continue; + const mjml=result.value.exports!.mjml!; + expect(mjml.match(/ { const draft = structuredClone(document); draft.root.props.logoUrl = "https://example.com/logo.png";