Content Components
Content components live inside <Column> (which lives inside <Row>, which lives inside a root wrapper). They're the actual visible blocks: text, buttons, images, dividers, and so on.
Every content component supports a semantic flat-prop API (e.g., fontSize="14px") and a values escape hatch when you need full control:
// flat (recommended)
<Heading headingType="h1" fontSize="24px" color="#111111">Welcome</Heading>
// values — full control
<Heading values={{ headingType: 'h1', fontSize: '24px', color: '#111111' }}>
Welcome
</Heading>
<Heading>
<Heading
headingType="h1"
fontSize="24px"
fontWeight={700}
fontFamily={{ label: 'Arial', value: 'arial,helvetica,sans-serif' }}
color="#111111"
textAlign="left"
lineHeight="120%"
>
Welcome
</Heading>
| Prop | Type | Default |
|---|---|---|
headingType | "h1" | "h2" | "h3" | "h4" | "h1" |
text | string | "Heading" (or use children) |
fontSize | string | "22px" |
fontWeight | number | 400 |
fontFamily | { label: string, value: string } | — |
color | string | "#000000" |
textAlign | "left" | "center" | "right" | "justify" | "left" |
lineHeight | string | "140%" |
<Heading> also accepts a level prop as a shorthand for headingType (<Heading level="h1">). It works at runtime — internally aliased to the same field — but isn't on HeadingProps, so strict TypeScript rejects it. Use headingType in typed code.
<Paragraph>
Content via children (rich React) or the html prop (rich HTML string):
// children — supports rich React
<Paragraph fontSize="14px">Hello <strong>world</strong></Paragraph>
// html prop — inline tags only: <b>, <i>, <u>, <s>, <a>, <code>
<Paragraph html="Hello <b>bold</b> and <a href='#'>link</a>" fontSize="14px" />
| Prop | Type | Default |
|---|---|---|
html | string | — |
children | ReactNode | — |
fontSize | string | "14px" |
color | string | "#000000" |
textAlign | "left" | "center" | "right" | "justify" | "left" |
lineHeight | string | "140%" |
fontFamily | { label: string, value: string } | — |
Some internal source examples write <Paragraph text="…" /> for parity with <Heading> and <Button>. That form is accepted at runtime (the value is converted to textJson), but ParagraphProps doesn't include text, so TypeScript will reject it. Use html or children.
<Button>
<Button
href="https://example.com"
backgroundColor="#0879A1"
color="#ffffff"
hoverBackgroundColor="#065c79"
fontSize="14px"
fontWeight={500}
padding="12px 24px"
borderRadius="6px"
textAlign="center"
>
Get Started
</Button>
| Prop | Type | Default |
|---|---|---|
text | string | "Button" (or use children) |
href | string | Href | — |
backgroundColor | string | "#0879A1" |
color | string | "#FFFFFF" |
hoverBackgroundColor | string | "#0879A1" (same as base — set explicitly for a visible hover) |
hoverColor | string | "#FFFFFF" (same as base) |
fontSize | string | "14px" |
fontWeight | number | 400 |
fontFamily | { label: string, value: string } | — |
lineHeight | string | "120%" |
padding | string | "10px 20px" |
borderRadius | string | "4px" |
textAlign | "left" | "center" | "right" | "center" |
href accepts a plain string (auto-wrapped) or { name: "web", values: { href, target } } if you need target control.
A note on textAlign: only <Heading> and <Paragraph> actually justify the rendered output (text-align: justify). <Button>, <Image>, and <Divider> accept the value at the type level but it has no visible effect, so their tables list only the three values that take effect.
Controlling button width
Button width is controlled by the size value (default { autoWidth: true, width: "100%" }). For a fixed-width button, pass it via the values escape hatch:
<Button
href="https://example.com"
values={{ size: { autoWidth: false, width: '240px' } }}
>
Get Started
</Button>
<Image>
<Image
src={{ url: 'https://example.com/hero.jpg', width: 600, height: 200 }}
alt="Hero banner"
textAlign="center"
/>
<Image
src={{ url: 'https://example.com/hero.jpg', width: 600, height: 200, autoWidth: false, maxWidth: '100%' }}
altText="Hero banner"
action={{ name: 'web', values: { href: 'https://example.com', target: '_blank' } }}
/>
| Prop | Type | Default |
|---|---|---|
src | { url, width?, height?, autoWidth?, maxWidth? } | placeholder URL with autoWidth: true, maxWidth: "100%" |
alt | string | shorthand for altText |
altText | string | "" |
textAlign | "left" | "center" | "right" | "center" |
action | { name: "web", values: { href, target } } | empty href with target: "_blank" |
A plain string src (<Image src="https://..." />) is wrapped to { url, autoWidth: true, maxWidth: "100%" } automatically at runtime, but TypeScript currently rejects the string form against ImageValues['src'], so use the object form in typed code. maxWidth accepts percentages only (e.g. "100%"). For fixed pixel sizing, set width/height instead.
Always supply alt (or altText) for accessibility.
<Divider>
<Divider
borderTopWidth="1px"
borderTopColor="#dddddd"
borderTopStyle="solid"
textAlign="center"
/>
| Prop | Type | Default |
|---|---|---|
width | string | "100%" |
borderTopWidth | string | "1px" |
borderTopColor | string | "#BBBBBB" |
borderTopStyle | string | "solid" |
textAlign | "left" | "center" | "right" | "center" |
<Video>
Embed a YouTube or Vimeo video as a clickable thumbnail. (Email clients don't play inline video, so this is the standard pattern.)
<Video videoUrl="https://www.youtube.com/watch?v=dQw4w9WgXcQ" />
<Video
values={{
video: {
type: 'youtube',
videoId: 'dQw4w9WgXcQ',
thumbnail: 'https://example.com/custom-thumb.jpg',
},
}}
/>
| Prop | Type | Notes |
|---|---|---|
videoUrl | string | YouTube/Vimeo URL, auto-parsed via parseVideoUrl |
values.video | { type: "youtube" | "vimeo", videoId, thumbnail } | Manual control |
The videoUrl shorthand is parsed by a built-in matcher that recognizes youtube.com/watch?v=..., youtu.be/..., youtube.com/embed/..., and vimeo.com/... patterns.
<Html>
Drop in arbitrary HTML — handy for one-off content the library doesn't model yet.
<Html html="<p style='color: red;'>Custom HTML content</p>" />
| Prop | Type | Default |
|---|---|---|
html | string | "<strong>Hello, world!</strong>" |
<Table>
<Table
headers={['Name', 'Plan', 'Status']}
data={[
['Jane', 'Pro', 'Active'],
['Carlos', 'Team', 'Active'],
['Asha', 'Free', 'Trial'],
]}
/>
| Prop | Type | Default |
|---|---|---|
headers | string[] | — (shorthand) |
data | string[][] | — (shorthand) |
columns | number | 2 (auto-set from headers.length when shorthand is used) |
rows | number | 2 (auto-set from data.length when shorthand is used) |
enableHeader | boolean | true |
The headers + data shorthand is the easiest way to build a static table. For full control, use the values escape hatch:
<Table
values={{
table: {
headers: [{ cells: [{ text: 'Name' }, { text: 'Email' }] }],
rows: [{ cells: [{ text: 'John' }, { text: 'john@example.com' }] }],
},
enableHeader: true,
}}
/>
<Social>
Social-icon row.
<Social
icons={[
{ name: 'Facebook', url: 'https://facebook.com/acme' },
{ name: 'Twitter', url: 'https://twitter.com/acme' },
{ name: 'LinkedIn', url: 'https://linkedin.com/company/acme' },
]}
iconType="rounded"
/>
| Prop | Type | Default |
|---|---|---|
icons | { name: string, url: string }[] | — (shorthand) |
iconType | "circle" | "rounded" | "squared" | "circle" |
Other layout props: align (default "center"), iconSize (default 32), spacing (default 5). Pass as flat props, or use values for full control.
<Menu>
Horizontal or vertical link list. Most commonly used in headers and footers.
<Menu
items={[
{ text: 'Home', href: '/' },
{ text: 'Pricing', href: '/pricing' },
{ text: 'About', href: '/about', target: '_self' },
]}
/>
| Prop | Type | Default |
|---|---|---|
items | { text: string, href: string, target?: string }[] | — (shorthand) |
target defaults to "_blank" when you don't supply one. Other layout props: layout ("horizontal" default, "vertical" for stacked), separator (default ""), align (default "center"), fontSize (default "14px").
See Also
- Layout Components —
Row,Column,ColumnLayouts - Configuration — global config and prop rules