# 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.