Alert

An alert tells the reader something about the page or an action they took. The colour picks the icon and the ARIA role together: danger and warning announce themselves as role="alert", everything quieter is a polite role="status".

Colors

Heads up
A new version of sitelo is available.
Deployed
169 pages published in 1.7 seconds.
Note
Islands are disabled in this project.
stack({ gap: 'sm' },
  alert({ color: 'primary', title: 'Heads up' }, 'A new version of sitelo is available.'),
  alert({ color: 'success', title: 'Deployed' }, '169 pages published in 1.7 seconds.'),
  alert({ color: 'warning', title: 'Slow page' }, 'One page took over 500 ms to render.'),
  alert({ color: 'danger', title: 'Build failed' }, 'Two internal links point at pages that do not exist.'),
  alert({ color: 'neutral', title: 'Note' }, 'Islands are disabled in this project.'),
)

Without a title

A one-line alert does not need a heading above the sentence.

Saved.
stack({ gap: 'sm' },
  alert({ color: 'success' }, 'Saved.'),
  alert({ color: 'danger' }, 'That email address is already in use.'),
)

Variants

stack({ gap: 'sm' },
  alert({ color: 'warning', variant: 'soft', title: 'Soft' }, 'The default — a tinted surface.'),
  alert({ color: 'warning', variant: 'outline', title: 'Outline' }, 'Transparent, with a coloured border.'),
  alert({ color: 'warning', variant: 'solid', title: 'Solid' }, 'The full palette colour, for something that must not be missed.'),
)

Icons

Each colour has a default icon. Pass your own markup as icon, or icon: false for none.

No icon
Just the text.
A custom icon
Any SVG works — icons are markup, not a dependency.
stack({ gap: 'sm' },
  alert({ color: 'primary', icon: false, title: 'No icon' }, 'Just the text.'),
  alert({
    color: 'primary',
    title: 'A custom icon',
    icon: icon('star'),
  }, 'Any SVG works — icons are markup, not a dependency.'),
)

Dismissible

The close button carries its own handler:

onclick="import('/su/alert.js').then(m=>m.dismiss(this))"

So the alert below really closes with nothing imported on this page. If that module never arrives, the button renders and does nothing, which is why an alert should never be the only place a message appears.

Dismissible
Click the × — the handler fetches itself on the first press.
alert({ color: 'primary', title: 'Dismissible', dismissible: true },
  'Click the × — the handler fetches itself on the first press.',
)

Rich content

Alerts take any children, so an action or a list can live inside one.

alert({ color: 'danger', title: 'Link check failed' },
  stack({ gap: 'sm' },
    text({ variant: 'small' }, 'Two links point at pages that were not generated:'),
    list({ plain: true },
      listItem({ title: '/docs/old-routing', description: 'linked from /docs' }),
      listItem({ title: '/blog/draft', description: 'linked from /blog' }),
    ),
    stack({ direction: 'row', gap: 'sm' },
      button({ size: 'sm', color: 'danger' }, 'Show details'),
      button({ size: 'sm', variant: 'ghost', color: 'danger' }, 'Ignore'),
    ),
  ),
)

Props

PropTypeDefaultDescription
color'primary' | 'neutral' | 'success' | 'warning' | 'danger''primary'Picks the palette, the default icon and the ARIA role.
variant'soft' | 'outline' | 'solid''soft'How much weight the alert carries.
titleChildBold first line.
iconChild | falseCustom icon markup, or false for none.
dismissiblebooleanfalseAdds a close button that imports its own handler.
dismissLabelstring'Dismiss'Accessible name for that button.