3.8 KiB
email-button
(no submodules)
Purpose
EmailButton is the canonical call-to-action surface in an email body —
a table-wrapped <a> with variant-driven theme colours and three preset
sizes. The table wrapper is non-optional: Outlook on Windows uses a
Word-derived rendering engine that historically ignores padding on
inline anchors, so the only reliable way to ship a visually-correct CTA
into Outlook desktop is a <table> containing a centred <td> containing
the styled <a>.
The component centralises the variant + size recipe so callers don't
duplicate it at every CTA site, and validates variant/size against
the published enums at call time — typos turn into a typed
EmailTemplatesError(INVALID_OPTIONS) instead of a silently-malformed
button.
Features
- Three variants —
primary,secondary,outline— each pulling colours from the active theme. - Three sizes —
sm,md,lg— each driving distinct padding + font-size. fullWidthtoggle emitswidth: 100%on both the wrapping<table>and the<a>so the CTA spans its container.alignprop emitted as the table'salignattribute.- Validation: unknown variant or size raises
EmailTemplatesError(INVALID_OPTIONS)and bumps an OTel counter taggedreason="invalid_button_variant"or"invalid_button_size". - Safe link defaults (
target="_blank",rel="noopener noreferrer").
Usage: Basic
import { EmailButton } from "@suaveplan/email-templates/components";
import { renderVNode } from "@suaveplan/email-templates/vnode";
renderVNode(EmailButton({
href: "https://app.example.test/get-started",
children: "Get Started",
}));
Usage: Advanced
A full-width secondary CTA with custom letter-spacing:
import { EmailButton } from "@suaveplan/email-templates/components";
import { renderVNode } from "@suaveplan/email-templates/vnode";
renderVNode(EmailButton({
href: "https://app.example.test/upgrade",
children: "Upgrade Now",
variant: "secondary",
size: "lg",
fullWidth: true,
style: { "letter-spacing": "0.5px" },
}));
API Reference
| Prop | Type | Description |
|---|---|---|
href |
string |
CTA target URL. |
children |
string |
Button label (string only — keeps the table cell-tight). |
theme |
EmailTheme? |
Theme override. |
variant |
"primary" | "secondary" | "outline" |
Defaults to primary. |
size |
"sm" | "md" | "lg" |
Defaults to md. |
fullWidth |
boolean? |
Defaults to false. |
align |
"left" | "center" | "right" |
Outer table align; defaults to "center". |
style |
StyleObject? |
Additional anchor-level inline styles. |
Implementation Notes
The variant style returns three keys (background-color, color,
border) plus the size returns two (padding, font-size); a switch
on the variant tag emits the right triple. Validation uses a Set
lookup — branch coverage is satisfied by one true-case test plus one
false-case test per validator.
The box-sizing: border-box declaration on the anchor ensures the
2 px border doesn't push the button over its intended outside width when
fullWidth: true. Without that declaration Outlook would render the
button slightly wider than its container in the outline variant where
the border weight matters most.