Toast overview
Headless toast gives you semantic viewport and item directives only. The owner decides where the stack lives, how messages are queued, when items dismiss, and what the notification shell looks like.
Imports
Bring in the viewport and item directives when you want full control over queue state and markup.
Headless toast imports
ts
import {
TngToastItem,
TngToastViewport,
type TngToastTone,
} from '@tailng-ui/primitives';
Basic composition
The primitive only reflects semantics on the viewport and each toast item. Your component owns queue state, timers, and placement.
Headless toast composition
html
<section class="toast-stage">
<button type="button" class="toast-trigger" (click)="queueToast()">Show toast</button>
<section tngToastViewport class="toast-viewport">
@for (toast of toasts(); track toast.id) {
<article tngToastItem [tone]="toast.tone" class="toast-item">
<div class="toast-content">
<strong>{{ toast.title }}</strong>
<p>{{ toast.message }}</p>
</div>
<button type="button" class="toast-dismiss" (click)="dismissToast(toast.id)">Dismiss</button>
</article>
}
</section>
</section>
Style variants
The same primitive contract skinned with owner-authored CSS or Tailwind utilities.
Headless toast with owner CSS
active toasts: 0
Headless toast with Tailwind shell
active toasts: 0
Behavior baseline
tngToastViewportis structural only. You own stack placement and spacing.tngToastItemmaps tone torole,aria-live, anddata-tone.- No queue logic, timers, or JavaScript positioning are built into the primitive.
- Dismiss by removing items from your collection or by driving
[open]yourself.