Skip to content

Alert Stack

4.39 KB gzip3.86 KB brotli4.52 KB zstd

sv-alert-stack displays stackable alerts on the page’s top layer.

Warning

Use a single alert stack per document. Multiple stacks compete over the keyboard shortcut and focus.

Usage

The element renders nothing on its own; alerts are created from script:

<sv-alert-stack></sv-alert-stack>
const alertStack = document.querySelector("sv-alert-stack");
alertStack.create({
severity: "error",
title: "File not found",
description: "The file at /path/to/file does not exist",
});

The stack expands on hover, on tap, and when an alert receives keyboard focus. Auto-dismiss timers pause while it is expanded.

Position and offset

Combine one vertical attribute with one horizontal attribute:

<sv-alert-stack top end></sv-alert-stack>

Offset the stack from the viewport edge by padding the wrapper part:

sv-alert-stack::part(wrapper) {
padding-block-start: 2rem;
padding-inline-end: 2rem;
}

Swipe to dismiss

Swiping is enabled on the stack, not per alert:

<sv-alert-stack swipe-dismiss></sv-alert-stack>

The swipeToDismiss option then opts a single alert out of it.

Custom actions and icons

An actionButton.action replaces the default dismissal, so dismiss the alert once the work is done:

const dismiss = alertStack.create({
title: "Export ready",
actionButton: {
label: "Download",
action: () => {
downloadFile();
dismiss();
},
},
});

iconOverride replaces the severity icon. Return nothing to keep the default icon for that severity.

The icon renders inside the shadow DOM, so give it a part attribute when it needs external styling:

alertStack.create({
severity: "success",
title: "Export ready",
iconOverride: () => {
const icon = document.createElement("span");
icon.part = "icon icon-success";
icon.textContent = "OK";
return icon;
},
});
sv-alert-stack::part(icon-success) {
color: var(--sv-success);
}

Accessibility

Alerts with severity "error" are announced as role="alert", the rest as role="status". Alerts created before the page finishes loading are not announced.

An appearing alert never takes keyboard focus, so its buttons can be far away in tab order. The shortcut attribute, Alt+T by default, focuses the first alert and expands the stack. Escape collapses the stack and restores the previous focus.

The stack is labelled "Notifications"; set aria-label on the element to rename it.

Give auto-dismissing alerts enough time to be read. Frequent or rapid alerts overwhelm users relying on assistive technologies.

API References

Methods

create()

Creates an item and adds it to the stack.
Returns a function that dismisses and removes the item.

export type ItemOptions = {
// The id of the item.
id?: string;
// The severity of the item.
// Default: "info"
severity?: Severity;
// The title of the item.
// Default: severity.toUpperCase()
title?: string;
// The message of the item.
// Default: ""
description?: string;
// The time before auto dismissing the item in milliseconds. Use `-1` to disable auto dismiss.
// Default: -1
duration?: number;
// Whether this item can be dismissed with a swipe gesture.
// Default: true
swipeToDismiss?: boolean;
// Whether to show an action button.
// Use `null` to remove the action button.
actionButton?: null | {
// The text of the action button.
// Default: "Dismiss"
label?: string;
// The click event handler.
// Default: dismiss the item
action?: (event: MouseEvent) => void;
};
// Optional function to provide a custom icon element.
//
// If provided, this function receives the item's `severity` and
// should return an `HTMLElement` to replace the default severity icon.
//
// Allows full customization of the icon, including animated or complex elements.
iconOverride?: (severity: Severity) => HTMLElement;
};

Properties

maxExpandedItems

The number of items shown when the stack is expanded.

A hidden item with keyboard focus is temporarily brought to the front, then returned when focus leaves it.

maxItems

The maximum number of items allowed in the stack.

When this limit is exceeded, the oldest item is removed.

swipeDismiss

Whether items can be dismissed by swiping them horizontally.

items

All item elements within the container.

shortcut

Keyboard shortcut used to focus and expand the stack.

The shortcut is written as a + separated string, such as "Alt+T" or "Alt+Shift+T".

Attributes

"top"

Positions the stack at the top of the page

"bottom"

Has no effect because the stack is positioned at the bottom by default

"start"

Positions the stack on the start side of the screen (left in LTR, right in RTL)

"center"

Positions the stack in the center of the screen

"end"

Has no effect because the stack is positioned on the end side by default (right in LTR, left in RTL)

"max-items"

The maximum number of items allowed in the stack.

When this limit is exceeded, the oldest item is removed.

"max-expanded-items"

The number of items shown when the stack is expanded.

A hidden item with keyboard focus is temporarily brought to the front, then returned when focus leaves it.

"shortcut"

Keyboard shortcut used to focus and expand the stack.

The shortcut is written as a + separated string, such as "Alt+T" or "Alt+Shift+T".

"swipe-dismiss"

Whether items can be dismissed by swiping them horizontally.

Events

closed

Fired when the user dismisses an alert using its action button or a swipe.

removed

Emitted just before an item is removed from the stack.

added

Emitted when an item is added to the stack.

CSS Properties

NameDescription
--sv-toggle-durThe duration of stack animations.
--sv-toggle-easeThe easing function used by stack animations.
--sv-successColor for success icons and titles
--sv-errorColor for error icons and titles
--sv-infoColor for info icons and titles
--sv-warningColor for warning icons and titles
--sv-gray-6The background color of the items.
--sv-gray-2The text color of the items and the dismiss action button.
--sv-gray-5The background color of the dismiss action button.
--sv-bdr-rad-mdThe border radius of the items.
--sv-bdr-rad-smThe border radius of the dismiss action button.
--sv-bdr-sz-smThe border size of the items.

CSS Parts

NameDescription
::part(popover)The popover element to display the alerts at the top of the page.
::part(wrapper)Cards container element.
::part(alert)The card container element.
::part(icon)The icon svg element.
::part(title)The title element.
::part(action-button)The action button element.
::part(description)The description element.