Alert
<sl-alert> | SlAlert
Alerts are used to display important messages inline or as toast notifications.
Examples
Basic Alert
<sl-alert open> <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon> <div slot="header">This is super informative</div> This is a standard informational alert. </sl-alert>
sl-alert open="true" sl-icon slot="icon" library="fa" name="fas-circle-info" div slot="header" This is super informative | This is a standard informational alert.
import { SlAlert, SlIcon } from '@teamshares/shoelace/dist/react'; const App = () => ( <SlAlert open> <SlIcon slot="icon" library="fa" name="fas-circle-info" /> <div slot="header">This is super informative</div> This is a standard standard informational alert. </SlAlert> );
Alerts will not be visible if the open
attribute is not present.
Variants
Set the variant
attribute to change the alert’s variant.
<sl-alert variant="primary" open> <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon> <div slot="header">This is super informative</div> You can tell by how pretty the alert is. </sl-alert> <br /> <sl-alert variant="success" open> <sl-icon slot="icon" library="fa" name="fas-circle-check"></sl-icon> <div slot="header">You can safely exit the app now</div> Your changes have been saved. </sl-alert> <br /> <sl-alert variant="warning" open> <sl-icon slot="icon" library="fa" name="fas-triangle-exclamation"></sl-icon> <div slot="header">Your session has ended</div> Please login again to continue. </sl-alert> <br /> <sl-alert variant="danger" open> <sl-icon slot="icon" library="fa" name="fas-circle-exclamation"></sl-icon> <div slot="header">Your account has been deleted</div> We are very sorry to see you go! </sl-alert>
sl-alert variant="primary" open="true" sl-icon slot="icon" library="fa" name="fas-circle-info" div slot="header" This is super informative | You can tell by how pretty the alert is. br sl-alert variant="success" open="true" sl-icon slot="icon" library="fa" name="fas-circle-check" div slot="header" Your changes have been saved | You can safely exit the app now. br sl-alert variant="warning" open="true" sl-icon slot="icon" library="fa" name="fas-triangle-exclamation" div slot="header" Your session has ended | Please login again to continue. br sl-alert variant="danger" open="true" sl-icon slot="icon" library="fa" name="fas-circle-exclamation" div slot="header" Your account has been deleted | We are very sorry to see you go!
import { SlAlert, SlIcon } from '@teamshares/shoelace/dist/react'; const App = () => ( <> <SlAlert variant="primary" open> <SlIcon slot="icon" library="fa" name="fas-circle-info" /> <div slot="header">This is super informative</div> You can tell by how pretty the alert is. </SlAlert> <br /> <SlAlert variant="success" open> <SlIcon slot="icon" library="fa" name="fas-circle-check" /> <div slot="header">Your changes have been saved</div> You can safely exit the app now. </SlAlert> <br /> <SlAlert variant="warning" open> <SlIcon slot="icon" library="fa" name="fas-triangle-exclamation" /> <div slot="header">Your session has ended</div> Please login again to continue. </SlAlert> <br /> <SlAlert variant="danger" open> <SlIcon slot="icon" library="fa" name="fas-circle-exclamation" /> <div slot="header">Your account has been deleted</div> We are very sorry to see you go! </SlAlert> </> );
Closable
Add the closable
attribute to show a close button that will hide the alert.
<sl-alert variant="primary" open closable class="alert-closable"> <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon> You can close this alert any time! </sl-alert> <script> const alert = document.querySelector('.alert-closable'); alert.addEventListener('sl-after-hide', () => { setTimeout(() => (alert.open = true), 2000); }); </script>
sl-alert.alert-closable variant="primary" open="true" closable="true" sl-icon slot="icon" library="fa" name="fas-circle-info" | You can close this alert any time! javascript: const alert = document.querySelector(.alert-closable); alert.addEventListener(sl-after-hide, () => { setTimeout(() => (alert.open = true), 2000); });
import { useState } from 'react'; import { SlAlert, SlIcon } from '@teamshares/shoelace/dist/react'; const App = () => { const [open, setOpen] = useState(true); function handleHide() { setOpen(false); setTimeout(() => setOpen(true), 2000); } return ( <SlAlert open={open} closable onSlAfterHide={handleHide}> <SlIcon slot="icon" library="fa" name="fas-circle-info" /> You can close this alert any time! </SlAlert> ); };
Duration
Set the duration
attribute to automatically hide an alert after a period of time. This is
useful for alerts that don’t require acknowledgement.
<div class="alert-duration"> <sl-button variant="primary">Show Alert</sl-button> <sl-alert variant="primary" duration="3000" closable> <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon> This alert will automatically hide itself after three seconds, unless you interact with it. </sl-alert> </div> <script> const container = document.querySelector('.alert-duration'); const button = container.querySelector('sl-button'); const alert = container.querySelector('sl-alert'); button.addEventListener('click', () => alert.show()); </script> <style> .alert-duration sl-alert { margin-top: var(--sl-spacing-medium); } </style>
div.alert-duration sl-button variant="primary" Show Alert sl-alert variant="primary" duration="3000" closable="true" sl-icon slot="icon" library="fa" name="fas-circle-info" | This alert will automatically hide itself after three seconds, unless you interact with it. javascript: const container = document.querySelector(.alert-duration); const button = container.querySelector(sl-button); const alert = container.querySelector(sl-alert); button.addEventListener(click, () => alert.show()); css: .alert-duration sl-alert { margin-top: var(--sl-spacing-medium); }
import { useState } from 'react'; import { SlAlert, SlButton, SlIcon } from '@teamshares/shoelace/dist/react'; const css = ` .alert-duration sl-alert { margin-top: var(--sl-spacing-medium); } `; const App = () => { const [open, setOpen] = useState(false); return ( <> <div className="alert-duration"> <SlButton variant="primary" onClick={() => setOpen(true)}> Show Alert </SlButton> <SlAlert variant="primary" duration="3000" open={open} closable onSlAfterHide={() => setOpen(false)}> <SlIcon slot="icon" library="fa" name="fas-circle-info" /> This alert will automatically hide itself after three seconds, unless you interact with it. </SlAlert> </div> <style>{css}</style> </> ); };
Toast Notifications
To display an alert as a toast notification, or “toast”, create the alert and call its
toast()
method. This will move the alert out of its position in the DOM and into
the toast stack where it will be shown. Once dismissed, it will be removed
from the DOM completely. To reuse a toast, store a reference to it and call toast()
again later
on.
You should always use the closable
attribute so users can dismiss the notification. It’s also
common to set a reasonable duration
when the notification doesn’t require acknowledgement.
<div class="alert-toast"> <sl-button variant="primary">Primary</sl-button> <sl-button variant="success">Success</sl-button> <sl-button variant="warning">Warning</sl-button> <sl-button variant="danger">Danger</sl-button> <sl-alert variant="primary" duration="3000" closable> <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon> <div slot="header">This is super informative</div> You can tell by how pretty the alert is. </sl-alert> <sl-alert variant="success" duration="3000" closable> <sl-icon slot="icon" library="fa" name="fas-circle-check"></sl-icon> <div slot="header">Your changes have been saved</div> You can safely exit the app now. </sl-alert> <sl-alert variant="warning" duration="3000" closable> <sl-icon slot="icon" library="fa" name="fas-triangle-exclamation"></sl-icon> <div slot="header">Your session has ended</div> Please login again to continue. </sl-alert> <sl-alert variant="danger" duration="3000" closable> <sl-icon slot="icon" library="fa" name="fas-circle-exclamation"></sl-icon> <div slot="header">Your account has been deleted</div> We are very sorry to see you go! </sl-alert> </div> <script> const container = document.querySelector('.alert-toast'); ['primary', 'success', 'warning', 'danger'].map(variant => { const button = container.querySelector(`sl-button[variant="${variant}"]`); const alert = container.querySelector(`sl-alert[variant="${variant}"]`); button.addEventListener('click', () => alert.toast()); }); </script>
div.alert-toast sl-button variant="primary" Primary sl-button variant="success" Success sl-button variant="warning" Warning sl-button variant="danger" Danger sl-alert variant="primary" duration="3000" closable="true" sl-icon slot="icon" library="fa" name="fas-circle-info" div slot="header" This is super informative | You can tell by how pretty the alert is. sl-alert variant="success" duration="3000" closable="true" sl-icon slot="icon" library="fa" name="fas-circle-check" div slot="header" Your changes have been saved | You can safely exit the app now. sl-alert variant="warning" duration="3000" closable="true" sl-icon slot="icon" library="fa" name="fas-triangle-exclamation" div slot="header" Your session has ended | Please login again to continue. sl-alert variant="danger" duration="3000" closable="true" sl-icon slot="icon" library="fa" name="fas-circle-exclamation" div slot="header" Your account has been deleted | We are very sorry to see you go! javascript: const container = document.querySelector(.alert-toast); [primary, success, warning, danger].map(variant => { const button = container.querySelector(`sl-button[variant="${variant}"]`); const alert = container.querySelector(`sl-alert[variant="${variant}"]`); button.addEventListener(click, () => alert.toast()); });
import { useRef } from 'react'; import { SlAlert, SlButton, SlIcon } from '@teamshares/shoelace/dist/react'; function showToast(alert) { alert.toast(); } const App = () => { const primary = useRef(null); const success = useRef(null); const warning = useRef(null); const danger = useRef(null); return ( <> <SlButton variant="primary" onClick={() => primary.current.toast()}> Primary </SlButton> <SlButton variant="success" onClick={() => success.current.toast()}> Success </SlButton> <SlButton variant="warning" onClick={() => warning.current.toast()}> Warning </SlButton> <SlButton variant="danger" onClick={() => danger.current.toast()}> Danger </SlButton> <SlAlert ref={primary} variant="primary" duration="3000" closable> <SlIcon slot="icon" library="fa" name="fas-circle-info" /> <div slot="header">This is super informative</div> You can tell by how pretty the alert is. </SlAlert> <SlAlert ref={success} variant="success" duration="3000" closable> <SlIcon slot="icon" library="fa" name="fas-circle-check" /> <div slot="header">Your changes have been saved</div> You can safely exit the app now. </SlAlert> <SlAlert ref={warning} variant="warning" duration="3000" closable> <SlIcon slot="icon" library="fa" name="fas-triangle-exclamation" /> <div slot="header">Your session has ended</div> Please login again to continue. </SlAlert> <SlAlert ref={danger} variant="danger" duration="3000" closable> <SlIcon slot="icon" library="fa" name="fas-circle-exclamation" /> <div slot="header">Your account has been deleted</div> We are very sorry to see you go! </SlAlert> </> ); };
Creating Toasts Imperatively
For convenience, you can create a utility that emits toast notifications with a function call rather than
composing them in your HTML. To do this, generate the alert with JavaScript, append it to the body, and call
the toast()
method as shown in the example below.
<div class="alert-toast-wrapper"> <sl-button variant="primary">Create Toast</sl-button> </div> <script> const container = document.querySelector('.alert-toast-wrapper'); const button = container.querySelector('sl-button'); let count = 0; // Always escape HTML for text arguments! function escapeHtml(html) { const div = document.createElement('div'); div.textContent = html; return div.innerHTML; } // Custom function to emit toast notifications function notify(message, variant = 'primary', icon = 'fas-circle-info', duration = 3000) { const alert = Object.assign(document.createElement('sl-alert'), { variant, closable: true, duration: duration, innerHTML: ` <sl-icon name="${icon}" library="fa" slot="icon"></sl-icon> ${escapeHtml(message)} ` }); document.body.append(alert); return alert.toast(); } button.addEventListener('click', () => { notify(`This is custom toast #${++count}`); }); </script>
.alert-toast-wrapper sl-button[variant="primary"] | Create Toast javascript: const container = document.querySelector('.alert-toast-wrapper'); const button = container.querySelector('sl-button'); let count = 0; // Always escape HTML for text arguments! function escapeHtml(html) { const div = document.createElement('div'); div.textContent = html; return div.innerHTML; } // Custom function to emit toast notifications function notify(message, variant = 'primary', icon = 'fas-circle-info', duration = 3000) { const alert = Object.assign(document.createElement('sl-alert'), { variant, closable: true, duration: duration, innerHTML: ` <sl-icon name="${icon}" library="fa" slot="icon"></sl-icon> ${escapeHtml(message)} ` }); document.body.append(alert); return alert.toast(); } button.addEventListener('click', () => { notify(`This is custom toast #${++count}`); });
The Toast Stack
The toast stack is a fixed position singleton element created and managed internally by the alert component. It will be added and removed from the DOM as needed when toasts are shown. When more than one toast is visible, they will stack vertically in the toast stack.
By default, the toast stack is positioned at the top-right of the viewport. You can change its position by
targeting .sl-toast-stack
in your stylesheet. To make toasts appear at the top-left of the
viewport, for example, use the following styles.
.sl-toast-stack { left: 0; right: auto; }
By design, it is not possible to show toasts in more than one stack simultaneously. Such behavior is confusing and makes for a poor user experience.
Usage guidelines
Using Icons in Alerts
Do
- Do always use an icon in the alert
- Do use the icons shown in the examples for each alert variant
Don’t
- Don’t use a one-off icon with your alert variant
- If you have a strong use case for using an one-off icon, check with the design team
Using Headers in Alerts
- Do include a header (using
slot="header"
) in the alert - Do keep the header short and scannable
- Do use sentence case for headers
- Don’t use a a period in the header, even if it’s a complete sentence
The Alert Message
- Do keep the message as short as possible
- Alert messages could contain plain text or a bulleted list, or even a button
Importing
If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.
To import this component from the CDN using a script tag:
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.1.0/cdn/components/alert/alert.js"></script>
To import this component from the CDN using a JavaScript import:
import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.1.0/cdn/components/alert/alert.js';
To import this component using a bundler:
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
To import this component as a React component:
import SlAlert from '@shoelace-style/shoelace/dist/react/alert';
Slots
Name | Description |
---|---|
(default) | The alert’s main content. |
icon
|
An icon to show in the alert. Works best with <sl-icon> . |
header
|
An optional bold header for the alert. |
Learn more about using slots.
Properties
Scroll right to see the entire table
Name | Description | Reflects | Type | Default |
---|---|---|---|---|
open
|
Indicates whether or not the alert is open. You can toggle this attribute to show and hide the
alert, or you can use the show() and hide() methods and this attribute
will reflect the alert’s open state.
|
|
boolean
|
false
|
closable
|
Enables a close button that allows the user to dismiss the alert. |
|
boolean
|
false
|
variant
|
The alert’s theme variant. |
|
'primary' | 'success' | 'neutral' | 'warning' | 'danger'
|
'primary'
|
duration
|
The length of time, in milliseconds, the alert will show before closing itself. If the user
interacts with the alert before it closes (e.g. moves the mouse over it), the timer will restart.
Defaults to Infinity , meaning the alert will not close on its own.
|
- |
Infinity
|
|
updateComplete
|
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Events
Name | React Event | Description | Event Detail |
---|---|---|---|
sl-show
|
onSlShow
|
Emitted when the alert opens. | - |
sl-after-show
|
onSlAfterShow
|
Emitted after the alert opens and all animations are complete. | - |
sl-hide
|
onSlHide
|
Emitted when the alert closes. | - |
sl-after-hide
|
onSlAfterHide
|
Emitted after the alert closes and all animations are complete. | - |
Learn more about events.
Methods
Name | Description | Arguments |
---|---|---|
show()
|
Shows the alert. | - |
hide()
|
Hides the alert | - |
toast()
|
Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by calling this method again. The returned promise will resolve after the alert is hidden. | - |
Learn more about methods.
Parts
Name | Description |
---|---|
base
|
The component’s base wrapper. |
icon
|
The container that wraps the optional icon. |
message
|
The container that wraps the alert’s main content. |
close-button
|
The close button, an <sl-icon-button> . |
close-button__base
|
The close button’s exported base part. |
Learn more about customizing CSS parts.
Animations
Name | Description |
---|---|
alert.show
|
The animation to use when showing the alert. |
alert.hide
|
The animation to use when hiding the alert. |
Learn more about customizing animations.
Dependencies
This component automatically imports the following dependencies.
-
<sl-icon>
-
<sl-icon-button>