3.1 KiB
email-layout
(no submodules)
Purpose
EmailLayout is the root VNode every email template wraps its body in. It
emits a 100%-width <table> with a themed muted background, an inner
max-width table centred horizontally, and an optional invisible preview-text
block that surfaces a snippet in the recipient's inbox-list view (Gmail,
Apple Mail, etc.) without appearing in the rendered body.
The table-in-table structure is the canonical email-layout idiom: full-width
clients (Outlook on desktop) honour the inner <table>'s pixel max-width
where most CSS would be stripped, while modern clients honour both and the
result looks identical.
Features
- Table-in-table structure with
role="presentation"so screen readers treat the markup as layout, not tabular data. - Optional
previewprop rendering an invisible snippet (display:none; max-height:0; overflow:hidden) the inbox list samples. - Themed background, font-family, font-size, line-height, and foreground colour applied to the outer table; themed border, border-radius, and max-width applied to the inner table.
- Children rendered into the inner content cell at
padding: theme.spacing.lg.
Usage: Basic
import { EmailLayout } from "@suaveplan/email-templates/components";
import { h, renderVNode } from "@suaveplan/email-templates/vnode";
renderVNode(EmailLayout({
children: h("p", {}, "Hi Jane"),
}));
Usage: Advanced
Pass a custom theme and preview text for inbox-list snippet:
import { EmailLayout } from "@suaveplan/email-templates/components";
import { h, renderVNode } from "@suaveplan/email-templates/vnode";
import { createTheme } from "@suaveplan/email-templates/theme";
const theme = createTheme({ colors: { muted: "#0f172a", primary: "#22d3ee" } });
renderVNode(EmailLayout({
theme,
preview: "Your invoice for January",
children: h("p", {}, "Body content"),
}));
API Reference
| Prop | Type | Description |
|---|---|---|
children |
EmailChildren? |
Body nodes rendered into the inner cell. |
theme |
EmailTheme? |
Theme override; defaults to defaultTheme. |
preview |
string? |
Hidden preview text for inbox-list snippet. |
style |
StyleObject? |
Reserved for future use; current renderer ignores. |
Implementation Notes
The preview block emits a <div> (not a <span> or <table>) because
historically Outlook 2007 mis-handled display:none on inline elements
inside tables. The empty-preview branch is exercised by the omits the preview block test to keep the conditional fully covered.
maxWidth lives on the inner table, not the outer one — the outer
table spans the viewport's full width to paint the muted background
edge-to-edge. The inner table's max-width: 600px is the standard
email-design recommendation; Apple's HIG suggests this number to ensure
single-column readability across watch / phone / mail-app contexts.