Toast Notification
Toasts display temporary, high-visibility messages that appear briefly in the viewport to communicate system events or status changes without interrupting user interactions.
import {ToastModule, createToaster} from "@qualcomm-ui/angular/toast"Usage Guidelines
Global Toaster
- Use our
provideToasterfunction to create a toaster instance near the root of your application. - Inject the
ToasterService. - Import and render the
q-toasterdirective with the ToasterService.toaster property.
import {Component} from "@angular/core"
import {provideToaster, ToasterService} from "@qualcomm-ui/angular/toast"
@Component({
providers: [provideToaster({placement: "bottom-end"})],
template: `
<div q-toaster [toaster]="toaster"></div>
<!-- the rest of your app... -->
`
})
export class AppComponent {
protected readonly toaster = inject(ToasterService).toaster
}To customize toast rendering, you can provide an <ng-template> child element to the q-toaster directive. If children are omitted, a fallback element will be used instead.
<div q-toaster [toaster]="toaster">
<!-- typesafe toast object is available via the q-toast-context directive -->
<ng-template q-toast-context let-toast>
<div q-toast-root>
<h3 q-toast-label>{{ toast.title }}</h3>
<p q-toast-description>{{ toast.description }}</p>
<button q-toast-close-button></button>
</div>
</ng-template>
</div>Examples
Demos
Each demo uses its own q-toaster instance for demonstration. Note that multiple toaster instances may obscure other toasts in practice, so it's recommended to use a single toaster instance for your entire app.
With Action
Use the action property to add an action button to the toast.
import {Component, inject} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
import {WINDOW} from "@qualcomm-ui/angular-core/dom"
@Component({
imports: [ToastModule, ButtonModule],
providers: [provideToaster({placement: "bottom-end"})],
selector: "toast-action-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<button q-button variant="outline" (click)="createToast()">
Create Toast
</button>
`,
})
export class ToastActionDemo {
toaster = inject(ToasterService).toaster
protected readonly window = inject(WINDOW)
createToast() {
this.toaster.create({
action: {
label: "Action",
onClick: () => {
this.window.alert("You clicked an action")
},
},
description: "Toast Description",
label: "Toast Label",
})
}
}Toast Emphasis
Here's an example of each toast type.
import {Component, inject} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
import type {QdsNotificationEmphasis} from "@qualcomm-ui/qds-core/inline-notification"
@Component({
imports: [ToastModule, ButtonModule],
providers: [provideToaster({placement: "bottom-end"})],
selector: "toast-emphasis-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<div class="flex flex-wrap gap-4">
@for (emphasis of types; track emphasis) {
<button q-button variant="outline" (click)="createToast(emphasis)">
{{ emphasis }}
</button>
}
</div>
`,
})
export class ToastEmphasisDemo {
toaster = inject(ToasterService).toaster
protected readonly types: QdsNotificationEmphasis[] = [
"info",
"success",
"warning",
"danger",
"neutral",
"loading",
]
createToast(emphasis: QdsNotificationEmphasis) {
this.toaster.create({
label: `The status is ${emphasis}`,
type: emphasis,
})
}
}Overlapping Toasts
By default, toasts are stacked on top of each other. To conserve space when rendering many toasts, set the overlap property to true in the createToaster function.
import {Component, inject} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
@Component({
imports: [ToastModule, ButtonModule],
providers: [
provideToaster({
overlap: true,
placement: "bottom-end",
}),
],
selector: "toast-overlap-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<button q-button variant="outline" (click)="createToast()">
Show Toast
</button>
`,
})
export class ToastOverlapDemo {
toaster = inject(ToasterService).toaster
createToast() {
this.toaster.create({
description: "Toast Description",
label: "Toast Label",
})
}
}Toast Duration
Use the duration property to set the duration of the toast.
import {Component, inject} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
@Component({
imports: [ToastModule, ButtonModule],
providers: [provideToaster({overlap: true, placement: "bottom-end"})],
selector: "toast-duration-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<button q-button variant="outline" (click)="createToast()">
Show Toast
</button>
`,
})
export class ToastDurationDemo {
protected readonly toaster = inject(ToasterService).toaster
createToast() {
this.toaster.create({
duration: 10000,
label: "Task failed successfully",
type: "success",
})
}
}Persistent Toast
Set the type property to loading to make the toast stay on screen until dismissed.
import {Component, inject} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
@Component({
imports: [ToastModule, ButtonModule],
providers: [
provideToaster({
overlap: true,
placement: "bottom-end",
}),
],
selector: "toast-persistent-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<button q-button variant="outline" (click)="createToast()">
Show Toast
</button>
`,
})
export class ToastPersistentDemo {
toaster = inject(ToasterService).toaster
createToast() {
this.toaster.create({
label: "Persistent Toast",
type: "loading",
})
}
}Pause and Resume
Use the pause and resume methods on the toaster instance to pause and play the toast.
Pausing a toast prevents it from timing out, while resuming it will continue the timeout from the remaining duration.
import {Component, inject, signal} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
@Component({
imports: [ToastModule, ButtonModule],
providers: [provideToaster({placement: "bottom-end"})],
selector: "toast-pause-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<div class="flex gap-4">
<button q-button variant="outline" [disabled]="shown()" (click)="show()">
Show Toast
</button>
<button
q-button
variant="outline"
[disabled]="!shown() || paused()"
(click)="pause()"
>
Pause Toast
</button>
<button
q-button
variant="outline"
[disabled]="!shown() || !paused()"
(click)="play()"
>
Play Toast
</button>
</div>
`,
})
export class ToastPauseDemo {
toaster = inject(ToasterService).toaster
protected readonly paused = signal(false)
protected readonly shown = signal(false)
show() {
this.toaster.create({
label: "This is a success toast",
onStatusChange: (details) => {
if (details.status === "visible") {
this.shown.set(true)
} else if (details.status === "dismissing") {
this.shown.set(false)
}
},
type: "success",
})
}
pause() {
this.toaster.pause()
this.paused.set(true)
}
play() {
this.toaster.resume()
this.paused.set(false)
}
}Max Visible
Set the max prop on the createToaster function to define the maximum number of toasts that can be rendered at a time. Extra toasts will be queued and rendered when the number of visible toasts drops below the max.
import {Component, inject} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {
provideToaster,
ToasterService,
ToastModule,
} from "@qualcomm-ui/angular/toast"
@Component({
imports: [ToastModule, ButtonModule],
providers: [
provideToaster({
max: 3,
placement: "bottom-end",
}),
],
selector: "toast-max-visible-demo",
template: `
<div q-toaster [toaster]="toaster"></div>
<button q-button variant="outline" (click)="createToast()">
Show Toast
</button>
`,
})
export class ToastMaxVisibleDemo {
toaster = inject(ToasterService).toaster
createToast() {
this.toaster.create({
description: "Toast Description",
label: "Toast Label",
})
}
}Screen Placement
Toasts can be displayed on all four corners of a page. We recommend picking a single placement for your app, as this creates a consistent experience for your users.
import {Component} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {createToaster, ToastModule} from "@qualcomm-ui/angular/toast"
@Component({
imports: [ToastModule, ButtonModule],
selector: "toast-placement-demo",
template: `
<div q-toaster [toaster]="topToaster"></div>
<div q-toaster [toaster]="bottomToaster"></div>
<div class="flex gap-4">
<button q-button variant="outline" (click)="showTop()">
Show Top Toast
</button>
<button q-button variant="outline" (click)="showBottom()">
Show Bottom Toast
</button>
</div>
`,
})
export class ToastPlacementDemo {
topToaster = createToaster({
placement: "top-end",
})
bottomToaster = createToaster({
placement: "bottom-start",
})
showTop() {
this.topToaster.create({
description: "Toast Description",
label: "Toast Label",
})
}
showBottom() {
this.bottomToaster.create({
description: "Toast Description",
label: "Toast Label",
})
}
}API
In the following sections, the toaster instance is referred to as toaster.
ToastCreateOptions
These are the options passed to the toaster.create function.
| Prop | Type | Default |
|---|---|---|
The action of the toast | { | |
Whether the toast is closable | boolean | true |
The description of the toast. | string | |
The duration the toast will be visible, in milliseconds. | number | |
The unique id of the toast | string | |
The title of the toast. | string | |
The metadata of the toast. Use this to provide additional information about the
toast for use in your own component | Record< | |
Function called when the toast is visible | ( | |
The duration the toast will be visible, in milliseconds.
Required for exit transitions. | number | 200 |
The type of the toast. Controls the color and icon of the toast. | | 'success' |
{
label: string
onClick: () => void
}
booleanstringnumberstringstringRecord<
string,
any
>
(
details: ToastStatusChangeDetails,
) => void
number| 'success'
| 'danger'
| 'loading'
| 'info'
| 'warning'
| 'neutral'
ToasterCreateOptions
Options passed to the createToaster / provideToaster functions.
| Prop | Type | Default |
|---|---|---|
number | ||
The gap between the toasts | number | 16 |
The maximum number of toasts. When the number of toasts exceeds this limit, the new toasts are queued. | number | 12 |
The offset from the safe environment edge of the viewport | | string | "1rem" |
Whether to overlap the toasts | boolean | false |
Whether to pause toast when the user leaves the browser tab | boolean | true |
The placement of the toast | | 'top-start' | "bottom-end" |
The duration for the toast to kept alive before it is removed.
Useful for exit transitions. | number | 200 |
numbernumbernumber| string
| Record<
| 'bottom'
| 'left'
| 'right'
| 'top',
string
>
booleanboolean| 'top-start'
| 'top'
| 'top-end'
| 'bottom-start'
| 'bottom'
| 'bottom-end'
numberToasterInstance
This is the instance returned from the createToaster function.
| Prop | Type |
|---|---|
The attributes of the toast store | |
Create a new toast with the given options | ( |
Dismiss a toast by its ID. If no ID is provided, dismisses all toasts | ( |
Get the total number of toasts | () => number |
Get all currently visible toasts | () => Partial< |
Check if a toast with the given ID has been dismissed | ( |
Check if a toast with the given ID is currently visible | ( |
Pause a toast's auto-dismiss timer. If no ID is provided, pauses all toasts | ( |
Create a toast that tracks a promise's state | ( |
Remove a toast by its ID | ( |
Resume a toast's auto-dismiss timer. If no ID is provided, resumes all toasts | ( |
Subscribe to the toast store | ( |
Update an existing toast with new properties | ( |
(
data: ToastOptions<string>,
) => string
(
id?: string,
) => void
() => number
() => Partial<
ToastApiProps<string>
>[]
(
id: string,
) => boolean
(
id: string,
) => boolean
(
id?: string,
) => void
(
promise:
| Promise<T>
| (() => Promise<T>),
options: ToastPromiseOptions<string>,
shared?: Omit<
ToastOptions<V>,
'type'
>,
) => {
id: string
unwrap: () => Promise<T>
}
(
id?: string,
) => void
(
id?: string,
) => void
(
subscriber: (
...args: any[]
) => void,
) => VoidFunction
(
id: string,
data: Partial<
ToastApiProps<V>
>,
) => string
ToastPromiseOptions
These are the options passed to the toaster.promise function.
| Prop | Type |
|---|---|
The options for the toast that displays while the Promise is pending. | Omit< |
The function called when the Promise is rejected. | ( |
The function called after the Promise is resolved successfully or rejected. | () => void | Promise<void> |
The function called when the Promise is resolved successfully. | ( |
Omit<
ToastOptions,
'type'
>
(
response: any,
) => Omit<
ToastOptions<V>,
'type'
>
() => void | Promise<void>
(
response: any,
) => Omit<
ToastOptions<V>,
'type'
>