Callout
A callout: content in a panel set apart from the text around it, as the legacy's callout blocks draw it. A variant sets the look — filled (a tinted panel), outline (a white panel with a border) or left-border (a pale panel with a 4px border down its left) — and a tone its colours, a step of the theme's or a status palette for each; every value they set can be given instead. An icon adds a column for an image beside the content: the legacy's tick, in the tone, or one of the sender's. Its defaults come from callout in lib/callout.ts, and resolveCallout checks the props.
Examples
Callout icon
A filled callout with the tick icon beside its text, in every tone.
58.6 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const themeTones = ['grey', 'primary', 'accent'] as const
const statusTones = ['success', 'warning', 'danger', 'info'] as const
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.';
<CalloutPage
title='Callout icon'
callouts={[...themeTones, ...statusTones].map((tone) => ({
key: tone,
callout: (
<NswCallout tone={tone} icon>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Callout
A filled callout in each of the theme’s tones: grey, primary and accent.
21.9 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const themeTones = ['grey', 'primary', 'accent'] as const
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.';
<CalloutPage
title='Callout'
callouts={themeTones.map((tone) => ({
key: tone,
callout: (
<NswCallout tone={tone}>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Callout left border
A callout with a border down its left in every tone, on a pale panel.
42.1 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const themeTones = ['grey', 'primary', 'accent'] as const
const statusTones = ['success', 'warning', 'danger', 'info'] as const
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.';
<CalloutPage
title='Callout left border'
callouts={[...themeTones, ...statusTones].map((tone) => ({
key: tone,
callout: (
<NswCallout variant='left-border' tone={tone}>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Callout outline
An outlined callout in every tone: a white panel with a border in the tone.
42.5 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const themeTones = ['grey', 'primary', 'accent'] as const
const statusTones = ['success', 'warning', 'danger', 'info'] as const
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.';
<CalloutPage
title='Callout outline'
callouts={[...themeTones, ...statusTones].map((tone) => ({
key: tone,
callout: (
<NswCallout variant='outline' tone={tone}>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Callout status tones
A filled callout in each status tone: success, warning, danger and info.
27.1 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const statusTones = ['success', 'warning', 'danger', 'info'] as const
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.';
<CalloutPage
title='Callout status tones'
callouts={statusTones.map((tone) => ({
key: tone,
callout: (
<NswCallout tone={tone}>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Callout padding
A grey callout padded 24, 32, 40, 48 and 56px.
32.1 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.'
const paddings = [24, 32, 40, 48, 56] as const;
<CalloutPage
title='Callout padding'
callouts={paddings.map((padding) => ({
key: String(padding),
callout: (
<NswCallout padding={padding}>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Callout surface
A filled callout with a border, in every tone.
42.5 KB built. Open the built email (opens in a new tab)
function CalloutPage({
title,
callouts,
}: {
title: string
callouts: ReadonlyArray<{ key: string; callout: ReactNode }>
}) {
return (
<NswLayout title={title}>
{callouts.map(({ key, callout }) => (
<Fragment key={key}>
<NswColumns>
<NswColumn>
<NswSpacer height={32} />
{callout}
<NswSpacer height={32} />
</NswColumn>
</NswColumns>
<NswColumns padding={false} background='grey-100'>
<NswColumn>
<NswSpacer height={24} />
</NswColumn>
</NswColumns>
</Fragment>
))}
</NswLayout>
)
}
const themeTones = ['grey', 'primary', 'accent'] as const
const statusTones = ['success', 'warning', 'danger', 'info'] as const
const lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec nisi sed diam ultricies tempus. Nullam et ligula sodales, blandit arcu sit amet, varius felis.';
<CalloutPage
title='Callout surface'
callouts={[...themeTones, ...statusTones].map((tone) => ({
key: tone,
callout: (
<NswCallout tone={tone} border='all'>
<NswText type='body-lg'>{lorem}</NswText>
</NswCallout>
),
}))}
/><CalloutPage> is a demo helper shown inline above, not part of the package: copy it with the example, or swap in your own.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | — | The panel's width in px. Default, in a column, that column's content width, handed on by <NswColumns>; otherwise the document's row width. Set it yourself only for a callout outside a column of the package's own. |
layout | Layout | — | The layout its row and spacers are drawn from: the document's (handed on by <NswLayout layout>) unless given one of its own. |
devices | Devices | — | Which devices show the callout: left out, every device; desktop hides it on a phone; mobile shows it on a phone only, and never in Windows Outlook (see src/lib/devices.ts), as <NswColumns devices> is. |
tone | CalloutTone | grey | The colour family: grey, primary or accent (the theme's), or success, warning, danger or info. Each shade the variant uses is a step of it. Default grey. |
variant | CalloutVariant | filled | The look: filled (a tinted panel), outline (a white panel with a border) or left-border (a pale panel with a 4px border down its left). Each sets the defaults below, any of which a callout can override. Default filled. |
background | ColorValue | the variant's: the tone's 100, white, or the tone's 50 | The panel's fill: a theme colour name or a hex literal. Default the variant's: the tone's 100, white, or the tone's 50. |
border | CalloutBorder | the variant's | Which sides carry a border: none, all or left. Default the variant's. |
borderColor | ColorValue | the variant's shade of the tone: 300, 400 or 600 | The border's colour: a theme colour name or a hex literal. Default the variant's shade of the tone: 300, 400 or 600. |
borderWidth | number | the variant's: 1, or 4 for left-border | The border's width in whole px, above 0 where a border is drawn. Default the variant's: 1, or 4 for left-border. |
rounded | boolean | the variant's: rounded, square for left-border | Round the panel's corners to the layout's radius (6px by default). Default the variant's: rounded, square for left-border. |
color | ColorValue | the tone's 900 | The colour handed to the text, lists, tables and links inside that set none of their own: a theme colour name or a hex literal. Default the tone's 900. |
padding | number | 24 | The space inside the panel, in whole px, on every side; on a phone its sides take the layout's phone padding (32px by default), as every column's do, unless it is 0, which stays flush. It must leave the content room. Default 24. |
icon | boolean | CalloutIcon | none | An icon beside the content: true for the legacy's tick in a circle, in the tone's 800, or an image of your own as { src, alt, width? } — alt required, '' when the text says what it shows; width in px, drawn square, default 32. Default none. |