A NSW Government website

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

Props of NswCallout, read from the component
PropTypeDefaultDescription
widthnumber—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.
layoutLayout—The layout its row and spacers are drawn from: the document's (handed on by <NswLayout layout>) unless given one of its own.
devicesDevices—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.
toneCalloutTonegreyThe 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.
variantCalloutVariantfilledThe 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.
backgroundColorValuethe variant's: the tone's 100, white, or the tone's 50The 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.
borderCalloutBorderthe variant'sWhich sides carry a border: none, all or left. Default the variant's.
borderColorColorValuethe variant's shade of the tone: 300, 400 or 600The border's colour: a theme colour name or a hex literal. Default the variant's shade of the tone: 300, 400 or 600.
borderWidthnumberthe variant's: 1, or 4 for left-borderThe border's width in whole px, above 0 where a border is drawn. Default the variant's: 1, or 4 for left-border.
roundedbooleanthe variant's: rounded, square for left-borderRound the panel's corners to the layout's radius (6px by default). Default the variant's: rounded, square for left-border.
colorColorValuethe tone's 900The 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.
paddingnumber24The 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.
iconboolean | CalloutIconnoneAn 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.