Toast
Global notification service for non-blocking, auto-dismissing messages. Opened imperatively via kuiToast(), not rendered as a bound component instance.
Import the inject-function and global options provider from the published package entrypoint.
import { kuiToast, provideKikitaUi } from '@kikita-labs/ui';
// Import runtime styles once, application-wide:
import '@kikita-labs/ui/styles';Inject kuiToast() once per component and call open() with a config object. The service lazily creates a single toast region on document.body the first time it is used, so there is nothing to render in your template.
<div class="basic-toast-example">
@for (trigger of triggers; track trigger.appearance) {
<button kuiButton type="button" shape="soft" (click)="show(trigger.appearance)">
{{ trigger.label }}
</button>
}
</div>Use persistent for messages that must stay open, pass a signal when the lifecycle is controlled by application state, and use the returned ref for in-place updates or programmatic dismissal.
import { signal } from '@angular/core';
import { kuiToast } from '@kikita-labs/ui';
export class UploadComponent {
private readonly toast = kuiToast();
protected readonly persistent = signal(true);
protected startUpload(): void {
const ref = this.toast.open({
title: 'Uploading...',
message: 'This toast is controlled by a signal.',
persistent: this.persistent,
});
// Start the configured auto-dismiss timer when the upload begins.
this.persistent.set(false);
// Update in place when an async operation completes.
ref.update({ title: 'Uploaded', appearance: 'success', duration: 3000 });
// Later, close one ref by id or every toast owned by this service.
this.toast.dismiss(ref.id);
this.toast.dismissAll();
}
}- A signal only needs to be readable; the toast never writes to it, so a
computedworks. - Turning the signal
truefreezes the time left andfalseresumes it. A toast opened with atruesignal starts the full duration the first time the signal becomesfalse. ref.update({ persistent })orref.update({ duration })restarts the full duration. An update that omitspersistentkeeps the current binding; one that sets it replaces the previous value or signal and detaches the old signal.- An explicit
persistentvalue, evenfalse, wins overduration: Infinity; a non-finite or missing duration then uses the default duration. - Updates after the toast starts closing are ignored. Closing the toast or destroying the region detaches every signal subscription and timer and completes
closed$andaction$.
Set actionLabel to render an inline action button. Clicking it emits once on the returned ref's action$ observable, which completes after emitting.
<button kuiButton type="button" shape="outline" appearance="danger" (click)="deleteMessage()">
Delete message
</button>The toast region renders at one of six positions. top-* stacks grow downward; bottom-* stacks grow upward, keeping the newest toast closest to the viewport edge. setPosition() changes the shared region at runtime and is intended for interactive demos like this one; prefer defaults.toast.position for real app configuration.
<div class="toast-position-example">
@for (position of positions; track position) {
<button kuiButton type="button" shape="soft" size="sm" (click)="show(position)">
{{ position }}
</button>
}
</div>Set defaults.toast once for the application or for a subtree. Each option resolves as local input > defaults.toast.<option> > built-in default.
import { provideKikitaUi } from '@kikita-labs/ui';
export const appConfig: ApplicationConfig = {
providers: [
provideKikitaUi({
defaults: {
toast: {
/* options below */
},
},
}),
],
};| Name | Type | Default | Description |
|---|---|---|---|
| position | 'top-start' | 'top-center' | 'top-end' | 'bottom-start' | 'bottom-center' | 'bottom-end' | — | Where the toast region is placed. Follows runtime changes of the default. |
| duration | number | — | Auto-dismiss delay in ms. |
| maxVisible | number | — | Toasts shown at once. Follows runtime changes of the default. |
| showProgress | boolean | — | Shows the remaining-time bar. |
| closable | boolean | — | Shows the close button. |
| showIcon | boolean | — | Shows the status icon. |
| closeIcon | KuiIconGlyph | — | Icon of the close button. Takes precedence over defaults.icons.close. See Structural Icons. |
Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-toast-color | CSS custom property | --kui-color-text | Color |
| --kui-toast-title-color | CSS custom property | --kui-color-text | Title color |
| --kui-toast-message-color | CSS custom property | --kui-color-text-secondary | Message color |
| --kui-toast-close-color | CSS custom property | --kui-color-text-secondary | Close color |
| --kui-toast-close-bg-hover | CSS custom property | --kui-color-state-hover | Close background, hover |
| --kui-toast-close-color-hover | CSS custom property | --kui-color-text | Close color, hover |
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-toast-close-radius | CSS custom property | --kui-radius-xs | Close corner radius |
| --kui-toast-accent-width | CSS custom property | 3px | Accent border width |
Every text the component owns (accessible names, visible words, announcements) is a typed message with an English default. Override it for the application with provideKikitaUi({ messages }), or for a subtree with provideKuiMessages.
| Name | Type | Default | Description |
|---|---|---|---|
| region | string | — | Accessible name of the notification region. Default Notifications. |
API verified against @kikita-labs/ui v2.0.0 public typings.
| Name | Type | Default | Description |
|---|---|---|---|
| title | string | - | Required headline text passed to open(). |
| message | string | undefined | - | Optional supporting text below the title. |
| appearance | 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'neutral' | Visual intent. Controls the accent bar and icon color; neutral renders no icon. |
| actionLabel | string | undefined | - | Label for the inline action button. Clicking it emits once on KuiToastRef.action$. |
| duration | number | 5000 | Auto-dismiss delay in ms. Ignored when persistent is true. App-wide default overridable via defaults.toast. |
| persistent | boolean | Signal<boolean> | false | Keeps the toast open until it is closed explicitly. A signal can start or pause the auto-dismiss timer reactively. |
| closable | boolean | true | Shows the close button. App-wide default overridable via defaults.toast. |
| showIcon | boolean | true | Shows the appearance icon. App-wide default overridable via defaults.toast. |
| showProgress | boolean | false | Shows a progress bar tracking time until auto-dismiss. App-wide default overridable via defaults.toast. |
| kuiToast() | () => KuiToast | - | Inject-function returning a reusable opener bound to the current injector scope. Call once per component; prefer over injecting KuiToast directly. |
| KuiToast.open(config) | (config: KuiToastConfig) => KuiToastRef | - | Shows a toast notification and returns a ref for programmatic control. |
| KuiToast.setPosition(position) | (position: KuiToastPosition) => void | - | Changes the shared toast region position at runtime. Intended for interactive demos; prefer defaults.toast for app-level configuration. |
| KuiToastRef.close() | () => void | - | Closes this toast programmatically and plays the exit animation. |
| KuiToastRef.id | number | - | Stable identifier for this toast within its owning toast service. |
| KuiToastRef.update(config) | (config: Partial<KuiToastConfig>) => void | - | Updates this toast in place and re-evaluates its auto-dismiss timer. |
| KuiToastRef.closed$ | Observable<void> | - | Emits once after the close animation finishes, then completes. |
| KuiToastRef.action$ | Observable<void> | - | Emits once when the action button is clicked, then completes. |
| KuiToast.dismiss(id) | (id: number) => void | - | Dismisses one toast created by this service using its stable reference id. |
| KuiToast.dismissAll() | () => void | - | Dismisses all active toasts created by this service. |
| provideKuiDefaults({ toast }) | (defaults: KuiComponentDefaults) => Provider | - | App or route-level provider for toast defaults: position, duration, maxVisible, showProgress, closable, showIcon and closeIcon. |
| position | 'top-start' | 'top-center' | 'top-end' | 'bottom-start' | 'bottom-center' | 'bottom-end' | 'bottom-center' | Global region position. Set app-wide via defaults.toast, or at runtime via KuiToast.setPosition for demos. |
| maxVisible | number | 3 | Max simultaneous toasts, set via defaults.toast. The oldest visible toast is evicted when exceeded. It follows runtime changes of the default. |
| KuiToastOptions | interface | - | Shape of defaults.toast: position, duration, maxVisible, showProgress, closable, showIcon and closeIcon. |
Toast uses a polite live region instead of stealing focus, matching how assistive technology expects transient status messages to behave.
- The toast region has
aria-live="polite", so new toasts are announced without interrupting current speech. - Toasts do not capture keyboard focus on appear, unlike Dialog. Keep critical, blocking confirmations in a Dialog instead of a toast.
- Hovering a toast pauses its auto-dismiss timer; leaving resumes it with the remaining time. This gives pointer users time to read before it disappears, but there is no keyboard-equivalent pause gesture documented yet — treat
persistentas the safer choice for messages a keyboard-only user must be able to act on. - Set
persistentfor errors or messages requiring a response instead of relying on the default 5 second auto-dismiss. - A persistent toast can still be dismissed by its close button, by
KuiToastRef.close(), or by the owning service'sdismiss()anddismissAll()methods. prefers-reduced-motionreplaces slide animations with an opacity-only fade.- The region is named by the
toast.regionmessage (Notifications). While toasts are visible it is a manual popover in the browser top layer, alongside Dialog, Drawer and Menu. - On narrow screens the card stretches to the viewport width and aligns to the bottom edge.
- On the server,
KuiToast.open()returns a no-op ref and performs no DOM access, so calling it during SSR is safe.
Consumer-visible changes of @kikita-labs/ui 2.0 for Toast.
provideKuiToastOptionsandKUI_TOAST_OPTIONSare replaced bydefaults.toastthroughprovideKikitaUi({ defaults })orprovideKuiDefaults; position andmaxVisiblefollow runtime changes of the default.- The service class is
KuiToast(wasKuiToastService);kuiToast()still returns it. - The notification region name comes from the
toast.regionmessage, and the close glyph fromdefaults.toast.closeIconordefaults.icons.close. - While toasts are visible the region is shown in the top layer, so it stays above open Dialogs and Drawers.
- Close button, message and title colours have tokens, and the close radius and accent width have geometry tokens.