Alert
In-flow message box with severity indicator. Alpine is only needed when `dismissible="true"`.
Requires Alpine.js
Severities
Info:
Heads up
The default info alert is for neutral guidance.
Success:
Saved
Your changes have been saved.
Error:
Could not save
Fix the highlighted fields and try again.
1{{ partial:components/primitives/alert title="Heads up" }}
2 The default info alert is for neutral guidance.
3{{ /partial:components/primitives/alert }}
4{{ partial:components/primitives/alert title="Saved" severity="success" }}
5 Your changes have been saved.
6{{ /partial:components/primitives/alert }}
7{{ partial:components/primitives/alert title="Could not save" severity="error" }}
8 Fix the highlighted fields and try again.
9{{ /partial:components/primitives/alert }}
{{ partial:components/primitives/alert title="Heads up" }}
The default info alert is for neutral guidance.
{{ /partial:components/primitives/alert }}
{{ partial:components/primitives/alert title="Saved" severity="success" }}
Your changes have been saved.
{{ /partial:components/primitives/alert }}
{{ partial:components/primitives/alert title="Could not save" severity="error" }}
Fix the highlighted fields and try again.
{{ /partial:components/primitives/alert }}
Body only
Info:
Alert
Short guidance can omit the title line.
1{{ partial:components/primitives/alert severity="info" }}
2 Short guidance can omit the title line.
3{{ /partial:components/primitives/alert }}
{{ partial:components/primitives/alert severity="info" }}
Short guidance can omit the title line.
{{ /partial:components/primitives/alert }}
Dismissible
Success:
Draft restored
This message can be dismissed with the close button.
1{{ partial:components/primitives/alert title="Draft restored" severity="success" dismissible="true" }}
2 This message can be dismissed with the close button.
3{{ /partial:components/primitives/alert }}
{{ partial:components/primitives/alert title="Draft restored" severity="success" dismissible="true" }}
This message can be dismissed with the close button.
{{ /partial:components/primitives/alert }}
Props
| Name | Type | Default | Description |
|---|---|---|---|
severity
|
string
|
info
|
Visual severity: info|success|error |
title
|
string
|
Optional bold heading line | |
dismissible
|
boolean
|
|
Adds an Alpine-powered dismiss button when true |
class
|
string
|
Additional classes merged via tw_merge (root element only) |
Slots
| Name | Fallback / Default | Description |
|---|---|---|
default
|
Alert body content |
Source
1{{#
2 @name Alert
3 @desc In-flow message box with severity indicator. Alpine is only needed when `dismissible="true"`.
4 @param severity string [info] - Visual severity: info|success|error
5 @param title string - Optional bold heading line
6 @param dismissible boolean [false] - Adds an Alpine-powered dismiss button when true
7 @param class string - Additional classes merged via tw_merge (root element only)
8 @slot default - Alert body content
9#}}
10{{# format-ignore-start #}}
11{{ _severity_key = severity ?? 'info' }}
12
13{{ _borders = [
14 'info' => 'border-l-primary',
15 'success' => 'border-l-success',
16 'error' => 'border-l-destructive',
17] }}
18
19{{ _icons = [
20 'info' => 'info',
21 'success' => 'check',
22 'error' => 'error',
23] }}
24
25{{ _icon_classes = [
26 'info' => 'text-primary',
27 'success' => 'text-success',
28 'error' => 'text-destructive',
29] }}
30
31{{ _prefixes = [
32 'info' => 'Info:',
33 'success' => 'Success:',
34 'error' => 'Error:',
35] }}
36
37{{ _class_border = _borders[_severity_key] ?? _borders['info'] }}
38{{ _icon = _icons[_severity_key] ?? _icons['info'] }}
39{{ _class_icon = _icon_classes[_severity_key] ?? _icon_classes['info'] }}
40{{ _prefix = _prefixes[_severity_key] ?? _prefixes['info'] }}
41{{# format-ignore-end #}}
42<div
43 class="{{ 'border-border bg-background text-foreground relative border border-l-4 p-4 {_class_border} {class}' | tw_merge }}"
44 {{ if dismissible == 'true' }}
45 x-data="{ visible: true }"
46 x-show="visible"
47 {{ /if }}
48>
49 <div class="flex gap-3">
50 {{ svg src="icons/{_icon}" class="size-5 shrink-0 {_class_icon}" aria-hidden="true" }}
51 <div class="min-w-0 flex-1 text-sm">
52 <span class="sr-only">{{ _prefix }}</span>
53 {{ if title }}
54 <div class="font-bold">{{ title }}</div>
55 {{ /if }}
56 <div class="{{ title ?= 'mt-1' }}">
57 {{ slot }}
58 </div>
59 </div>
60 {{ if dismissible == 'true' }}
61 <button
62 type="button"
63 class="text-muted-foreground focus-visible:border-focus-text focus-visible:outline-focus active:border-focus active:bg-focus active:text-focus-text -m-1 inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 border-transparent transition-colors hover:border-current focus-visible:outline focus-visible:outline-4"
64 aria-label="Dismiss"
65 @click="visible = false"
66 >
67 {{ svg src="icons/close" class="size-4" aria-hidden="true" }}
68 </button>
69 {{ /if }}
70 </div>
71</div>
{{#
@name Alert
@desc In-flow message box with severity indicator. Alpine is only needed when `dismissible="true"`.
@param severity string [info] - Visual severity: info|success|error
@param title string - Optional bold heading line
@param dismissible boolean [false] - Adds an Alpine-powered dismiss button when true
@param class string - Additional classes merged via tw_merge (root element only)
@slot default - Alert body content
#}}
{{# format-ignore-start #}}
{{ _severity_key = severity ?? 'info' }}
{{ _borders = [
'info' => 'border-l-primary',
'success' => 'border-l-success',
'error' => 'border-l-destructive',
] }}
{{ _icons = [
'info' => 'info',
'success' => 'check',
'error' => 'error',
] }}
{{ _icon_classes = [
'info' => 'text-primary',
'success' => 'text-success',
'error' => 'text-destructive',
] }}
{{ _prefixes = [
'info' => 'Info:',
'success' => 'Success:',
'error' => 'Error:',
] }}
{{ _class_border = _borders[_severity_key] ?? _borders['info'] }}
{{ _icon = _icons[_severity_key] ?? _icons['info'] }}
{{ _class_icon = _icon_classes[_severity_key] ?? _icon_classes['info'] }}
{{ _prefix = _prefixes[_severity_key] ?? _prefixes['info'] }}
{{# format-ignore-end #}}
<div
class="{{ 'border-border bg-background text-foreground relative border border-l-4 p-4 {_class_border} {class}' | tw_merge }}"
{{ if dismissible == 'true' }}
x-data="{ visible: true }"
x-show="visible"
{{ /if }}
>
<div class="flex gap-3">
{{ svg src="icons/{_icon}" class="size-5 shrink-0 {_class_icon}" aria-hidden="true" }}
<div class="min-w-0 flex-1 text-sm">
<span class="sr-only">{{ _prefix }}</span>
{{ if title }}
<div class="font-bold">{{ title }}</div>
{{ /if }}
<div class="{{ title ?= 'mt-1' }}">
{{ slot }}
</div>
</div>
{{ if dismissible == 'true' }}
<button
type="button"
class="text-muted-foreground focus-visible:border-focus-text focus-visible:outline-focus active:border-focus active:bg-focus active:text-focus-text -m-1 inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 border-transparent transition-colors hover:border-current focus-visible:outline focus-visible:outline-4"
aria-label="Dismiss"
@click="visible = false"
>
{{ svg src="icons/close" class="size-4" aria-hidden="true" }}
</button>
{{ /if }}
</div>
</div>
Dependencies
Packages
1composer require marcorieser/tailwind-merge-statamic
2npm install alpinejs
composer require marcorieser/tailwind-merge-statamic npm install alpinejs