Initial Commit
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# email-layout
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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 `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 `<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.
|
||||
Reference in New Issue
Block a user