Constrain email table sizing around intrinsic image widths
Quality / quality (ubuntu-latest) (push) Failing after 1s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-09-05 18:05:16 +05:30
1 parent b0fca36bca
commit 3da88510df
3 files changed
+4 -2

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@wrnexus/email-renderer", "name": "@wrnexus/email-renderer",
"version": "0.1.35", "version": "0.1.36",
"type": "module", "type": "module",
"description": "WRNexus block email renderers with HTML, text, AMP Email, and MJML interoperability.", "description": "WRNexus block email renderers with HTML, text, AMP Email, and MJML interoperability.",
"exports": { "exports": {
+1 -1
View File
@@ -159,7 +159,7 @@ export const emailDocumentBlock = defineBlock({
}), }),
renderers: { renderers: {
emailHtml: ({ node, slots }) => emailHtml: ({ node, slots }) =>
`<table data-block-id="${html(node.id)}" role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;background:${html(attrs(node).background ?? "#f3f4f6")};color:${html(attrs(node).textColor ?? "#111827")};font-family:${html(attrs(node).fontFamily ?? "Arial, sans-serif")};"><tr><td align="center">${attrs(node).logoUrl ? `<img src="${html(attrs(node).logoUrl)}" alt="${html(attrs(node).logoAlt)}" style="display:block;height:auto;max-width:200px;padding:20px;" />` : ""}<table role="presentation" class="wrn-email" width="${html(attrs(node).width)}" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;max-width:100%;width:${html(attrs(node).width)}px;background:${html(attrs(node).contentBackground ?? "#ffffff")};color:${html(attrs(node).textColor ?? "#111827")};font-family:${html(attrs(node).fontFamily ?? "Arial, sans-serif")};">${slots.content}</table></td></tr></table>`, `<table data-block-id="${html(node.id)}" role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;table-layout:fixed;background:${html(attrs(node).background ?? "#f3f4f6")};color:${html(attrs(node).textColor ?? "#111827")};font-family:${html(attrs(node).fontFamily ?? "Arial, sans-serif")};"><tr><td align="center">${attrs(node).logoUrl ? `<img src="${html(attrs(node).logoUrl)}" alt="${html(attrs(node).logoAlt)}" style="display:block;height:auto;max-width:200px;padding:20px;" />` : ""}<table role="presentation" class="wrn-email" width="${html(attrs(node).width)}" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;table-layout:fixed;max-width:100%;width:${html(attrs(node).width)}px;background:${html(attrs(node).contentBackground ?? "#ffffff")};color:${html(attrs(node).textColor ?? "#111827")};font-family:${html(attrs(node).fontFamily ?? "Arial, sans-serif")};">${slots.content}</table></td></tr></table>`,
ampEmail: ({ node, slots }) => ampEmail: ({ node, slots }) =>
`<table role="presentation" width="100%" class="email-bg"><tr><td align="center">${attrs(node).logoUrl ? `<amp-img class="marketing-image" src="${html(attrs(node).logoUrl)}" alt="${html(attrs(node).logoAlt)}" width="200" height="64" layout="fixed"></amp-img>` : ""}<table role="presentation" width="${html(attrs(node).width)}" class="email-body">${slots.content}</table></td></tr></table>`, `<table role="presentation" width="100%" class="email-bg"><tr><td align="center">${attrs(node).logoUrl ? `<amp-img class="marketing-image" src="${html(attrs(node).logoUrl)}" alt="${html(attrs(node).logoAlt)}" width="200" height="64" layout="fixed"></amp-img>` : ""}<table role="presentation" width="${html(attrs(node).width)}" class="email-body">${slots.content}</table></td></tr></table>`,
mjml: ({ node, slots, context }) => mjml: ({ node, slots, context }) =>
@@ -17,6 +17,8 @@ test("meaningful image alt and explicit dimensions survive MJML round trip", asy
const rendered = await renderEmail(documentFor(false), { mjml: true }); const rendered = await renderEmail(documentFor(false), { mjml: true });
if (!rendered.ok) throw new Error("Render failed"); if (!rendered.ok) throw new Error("Render failed");
expect(rendered.value.parts.text.content).toContain("Accessible & descriptive"); expect(rendered.value.parts.text.content).toContain("Accessible & descriptive");
expect(rendered.value.parts.html.content.match(/table-layout:fixed/g)).toHaveLength(2);
expect(rendered.value.parts.html.content).toContain("max-width:100%;width:600px");
expect(rendered.value.exports!.mjml).toContain('width="320px" height="180px"'); expect(rendered.value.exports!.mjml).toContain('width="320px" height="180px"');
let id = 0; let id = 0;
const imported = importMjml(rendered.value.exports!.mjml!, { id: () => `n${++id}` }); const imported = importMjml(rendered.value.exports!.mjml!, { id: () => `n${++id}` });