# email-layout _(no submodules)_ ## Purpose `EmailLayout` is the root VNode every email template wraps its body in. It emits a 100%-width `` 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 `
`'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 `preview` prop 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 ```ts 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: ```ts 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 `
` (not a `` or `
`) 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.