Toast
Transient, non-blocking feedback about something that already happened ("Saved", "Upload failed"). If the user MUST see or act on it, it is not a toast — use Notice (inline) or Dialog (blocking).
Added 14 October 2026
React
Codecomponents/react/toast-demo.tsx
import {Button, Toaster, toast} from '@stroeer-labs/design-library/react';
export function ToastDemo() {
return (
<div className="toast-scope">
{/* Toast is imperative: mount <Toaster /> once, then call toast() from anywhere.
toast-scope is a sandbox-only wrapper (see global.css) that pins the toaster inside
this card so the React + Angular showcases don't collide on one page. It sits OUTSIDE
the space-y-6 flow so sonner's (zero-height) section wrapper doesn't add a top gap. */}
<Toaster />
<div className="space-y-6">
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Types</p>
<div className="flex flex-wrap gap-3">
<Button variant="outline" onClick={() => toast('Event has been created')}>
Default
</Button>
<Button variant="outline" onClick={() => toast.success('Event has been created')}>
Success
</Button>
<Button variant="outline" onClick={() => toast.info('Be at the area 10 minutes before the event time')}>
Info
</Button>
<Button variant="outline" onClick={() => toast.warning('Event start time cannot be earlier than 8am')}>
Warning
</Button>
<Button variant="outline" onClick={() => toast.error('Event has not been created')}>
Error
</Button>
</div>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Description, action & promise</p>
<div className="flex flex-wrap gap-3">
<Button
variant="outline"
onClick={() =>
toast('Event has been created', {
description: 'Sunday, December 03, 2023 at 9:00 AM',
action: {label: 'Undo', onClick: () => toast('Undone')},
})
}
>
With description
</Button>
<Button
variant="outline"
onClick={() =>
toast.promise<{name: string}>(() => new Promise((resolve) => setTimeout(() => resolve({name: 'Event'}), 2000)), {
loading: 'Loading...',
success: (data) => `${data.name} has been created`,
error: 'Error',
})
}
>
Promise
</Button>
</div>
</div>
</div>
</div>
);
}Angular
Codecomponents/angular/toast-demo.ts
import {Component} from '@angular/core';
import {HlmButtonImports, HlmToasterImports, toast} from '@stroeer-labs/design-library/angular';
@Component({
selector: 'dl-toast-demo',
standalone: true,
imports: [HlmToasterImports, HlmButtonImports],
template: `
<div class="toast-scope">
<!-- Toast is imperative: mount <hlm-toaster /> once, then call toast() from anywhere.
toast-scope is a sandbox-only wrapper (see global.css) that pins the toaster inside
this card so the React + Angular showcases don't collide on one page. It sits OUTSIDE
the space-y-6 flow to mirror the React demo structure exactly. -->
<hlm-toaster />
<div class="space-y-6">
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Types</p>
<div class="flex flex-wrap gap-3">
<button hlmBtn variant="outline" (click)="showDefault()">Default</button>
<button hlmBtn variant="outline" (click)="showSuccess()">Success</button>
<button hlmBtn variant="outline" (click)="showInfo()">Info</button>
<button hlmBtn variant="outline" (click)="showWarning()">Warning</button>
<button hlmBtn variant="outline" (click)="showError()">Error</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Description, action & promise</p>
<div class="flex flex-wrap gap-3">
<button hlmBtn variant="outline" (click)="showDescription()">With description</button>
<button hlmBtn variant="outline" (click)="showPromise()">Promise</button>
</div>
</div>
</div>
</div>
`,
})
export class ToastDemoComponent {
showDefault() {
toast('Event has been created');
}
showSuccess() {
toast.success('Event has been created');
}
showInfo() {
toast.info('Be at the area 10 minutes before the event time');
}
showWarning() {
toast.warning('Event start time cannot be earlier than 8am');
}
showError() {
toast.error('Event has not been created');
}
showDescription() {
toast('Event has been created', {
description: 'Sunday, December 03, 2023 at 9:00 AM',
action: {label: 'Undo', onClick: () => toast('Undone')},
});
}
showPromise() {
toast.promise<{name: string}>(() => new Promise((resolve) => setTimeout(() => resolve({name: 'Event'}), 2000)), {
loading: 'Loading...',
success: (data) => `${data.name} has been created`,
error: 'Error',
});
}
}