CngxToastOutlet
projects/ui/feedback/toast/toast-outlet.ts
Import#
import { CngxToastOutlet } from '@cngx/ui/feedback'
Description#
Toast outlet - renders the toast stack at a fixed viewport position.
Place once in the app shell. Reads from CngxToaster reactively.
Requires provideToasts() or provideFeedback(withToasts()).
<cngx-toast-outlet position="bottom-end" [maxVisible]="5" />Metadata#
Host#
Dependencies#
Relationships
Index#
HostBindings
Inputs#
"start" | "end"Insert new toasts at start or end of the stack.
'start'HostBindings#
| Binding | Expression |
|---|---|
[class] | positionClass() |
Default visuals for CngxToastOutlet. The host carries
.cngx-toast-outlet and is fixed-positioned with z-index: 9999
so toasts overlay dialogs and popovers. Each toast renders as
.cngx-toast with __icon, __body, __message, __title,
__description, __count, __action, and __dismiss children.
Toasts use their own --cngx-toast-* namespace, separate from
alert and banner so the three feedback channels can be themed
independently.
Placement modifiers
Six anchor classes on the outlet, three vertical x two horizontal (center variants use a transform):
--top-start/--top-center/--top-end--bottom-start/--bottom-center/--bottom-end
Variants
Severity classes paint the leading-edge stripe and the icon color:
.cngx-toast--info- info accent.cngx-toast--success- success accent.cngx-toast--warning- warning accent.cngx-toast--error- error accent
Slots
.cngx-toast__icon- severity glyph (color tracks severity).cngx-toast__default-icon- SVG fallback when no custom icon is projected.cngx-toast__message- body copy.cngx-toast__title- bold header.cngx-toast__description- secondary copy, line-clamped via--cngx-toast-description-max-lines(default 3).cngx-toast__count- trailing message-count badge (60% opacity).cngx-toast__action- underlined inline action button.cngx-toast__dismiss- dismiss control
Toasts enter via 200ms cngx-toast-enter; the animation no-ops
under prefers-reduced-motion.
Inheritance
--cngx-toast-bg->--cngx-color-surface--cngx-toast-color->--cngx-color-text
Dark mode
Three hooks deepen the drop shadow, brighten every severity accent so the leading-edge stripe stays perceptible against the darker toast surface, and lift the description text to the cool muted ramp:
prefers-color-scheme: dark[data-color-scheme="dark"].darkclass
Index#
Layout
Variant / Info
Variant / Success
Variant / Warning
Variant / Error
Typography
State / Overflow
Layout
<number>9999Stacking-context order - high so toasts overlay dialogs / popovers.
*16pxOuter padding around the toast outlet (viewport offset).
<length>420pxMaximum inline size of each toast - caps long messages.
<length>10pxGap between icon, body, and dismiss button inside a toast.
<length>20pxDefault icon size when no custom icon is projected.
Surface
Motion
Variant / Info
<color>oklch(0.62 0.2 250)Severity stripe of the info variant.
Variant / Success
<color>oklch(0.65 0.15 145)Severity stripe of the success variant.
Variant / Warning
<color>oklch(0.72 0.18 70)Severity stripe of the warning variant.
Variant / Error
<color>oklch(0.62 0.22 25)Severity stripe of the error variant.
Typography
<integer>3Maximum number of lines for the description slot before truncation kicks in.
<color>oklch(0.5 0.01 250)Text color of the description slot.
State / Overflow
Async state bridges
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { createManualState } from '@cngx/common/data';
import { CngxBannerOn, CngxBannerOutlet, CngxToastOn, CngxToastOutlet } from '@cngx/ui/feedback';
// Re-export triggers compodocx file-walker so app.config.ts lands in the
// StackBlitz manifest as src/app/app.config.ts, overriding the hardcoded
// stub — the only way to inject EnvironmentProviders into the playground.
export { appConfig } from './app.config';
/**
* Async-state bridges — toast + banner without service plumbing.
*
* One `createManualState<string>()` slot drives two declarative bridges
* (`cngxToastOn`, `cngxBannerOn`) attached to the same host element.
* The bridges read the state via input binding (`[cngxToastOn]="saveState"`)
* and react to status transitions: `loading → success` fires a success
* toast; `loading → error` fires an error toast AND opens a banner. No
* subscriptions, no `inject(CngxToaster)`, no `show()` calls.
*
* Same pattern composes with any `CngxAsyncState` producer — `injectAsyncState`,
* `fromResource`, `fromHttpResource`, the manual state shown here, or a
* commit-action's exposed `commitState` (see Example 3 / 6).
*/
@Component({
selector: 'app-root',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CngxToastOn, CngxBannerOn, CngxToastOutlet, CngxBannerOutlet],
template: `
<p style="margin: 0 0 12px; opacity: 0.8; font-size: 0.875rem">
One <code>createManualState</code> slot drives both bridges on the
same element. Click a button to push the state through
<code>loading → success</code> or <code>loading → error</code> and
watch the toast / banner appear without any explicit
<code>show()</code> call.
</p>
<div
[cngxToastOn]="saveState"
[toastSuccess]="'Saved'"
[toastError]="'Save failed'"
[cngxBannerOn]="saveState"
bannerId="save:error"
[bannerError]="'Save failed — check your connection.'"
style="display: flex; gap: 8px; flex-direction: column; align-items: flex-start"
>
<div style="display: flex; gap: 8px">
<button type="button" (click)="simulateSuccess()">
Simulate success
</button>
<button type="button" (click)="simulateError()">
Simulate error
</button>
</div>
<p>Status: {{ saveState.status() }}</p>
</div>
<cngx-toast-outlet />
<cngx-banner-outlet />
`,
})
export class BridgesExample {
protected readonly saveState = createManualState<string>();
protected simulateSuccess(): void {
this.saveState.set('loading');
setTimeout(() => this.saveState.setSuccess('Saved!'), 1200);
}
protected simulateError(): void {
this.saveState.set('loading');
setTimeout(() => this.saveState.setError('Server error'), 1200);
}
}
export { BridgesExample as AppComponent };