Toast

A succinct message that is displayed temporarily.

PreviousNext
import { Component } from '@angular/core';
import { toast } from 'ngx-sonner';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'zard-demo-toast',
  standalone: true,
  imports: [ZardButtonComponent],
  template: ` <button z-button zType="outline" (click)="showToast()">Show Toast</button> `,
})
export class ZardDemoToastDefaultComponent {
  showToast() {
    toast('Event has been created', {
      description: 'Sunday, December 03, 2023 at 9:00 AM',
      action: {
        label: 'Undo',
        onClick: () => console.log('Undo'),
      },
    });
  }
}
 

Installation

1

Run the CLI

Use the CLI to add the component to your project.

npx @ngzard/ui add toast
2

Register toast to your project

app.component.ts'
app.component.ts'
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ZardToastComponent } from '@shared/components/toast/toast.component';
 
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, ZardToastComponent],
  template: `
    <router-outlet></router-outlet>
    <z-toaster />
  `,
})
export class AppComponent {}
1

Install dependencies

Install the required dependencies for this component.

npm install ngx-sonner
2

Add the component files

Create the component directory structure and add the following files to your project.

toast.component.ts
toast.component.ts
import { ChangeDetectionStrategy, Component, computed, input, ViewEncapsulation } from '@angular/core';
import { NgxSonnerToaster } from 'ngx-sonner';
import type { ClassValue } from 'clsx';
 
import { mergeClasses } from '../../shared/utils/utils';
import { toastVariants, type ZardToastVariants } from './toast.variants';
 
@Component({
  selector: 'z-toast, z-toaster',
  standalone: true,
  exportAs: 'zToast',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  imports: [NgxSonnerToaster],
  template: `
    <ngx-sonner-toaster
      [theme]="theme()"
      [class]="classes()"
      [position]="position()"
      [richColors]="richColors()"
      [expand]="expand()"
      [duration]="duration()"
      [visibleToasts]="visibleToasts()"
      [closeButton]="closeButton()"
      [toastOptions]="toastOptions()"
      [dir]="dir()"
    />
  `,
})
export class ZardToastComponent {
  readonly class = input<ClassValue>('');
  readonly variant = input<ZardToastVariants['variant']>('default');
  readonly theme = input<'light' | 'dark' | 'system'>('system');
  readonly position = input<'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'>('bottom-right');
  readonly richColors = input<boolean>(false);
  readonly expand = input<boolean>(false);
  readonly duration = input<number>(4000);
  readonly visibleToasts = input<number>(3);
  readonly closeButton = input<boolean>(false);
  readonly toastOptions = input<Record<string, unknown>>({});
  readonly dir = input<'ltr' | 'rtl' | 'auto'>('auto');
 
  protected readonly classes = computed(() => mergeClasses('toaster group', toastVariants({ variant: this.variant() }), this.class()));
}
 
toast.variants.ts
toast.variants.ts
import { cva, type VariantProps } from 'class-variance-authority';
 
export const toastVariants = cva('group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg', {
  variants: {
    variant: {
      default: 'group-[.toaster]:bg-background group-[.toaster]:text-foreground',
      destructive: 'group-[.toaster]:bg-destructive group-[.toaster]:text-destructive-foreground destructive group-[.toaster]:border-destructive',
    },
  },
  defaultVariants: {
    variant: 'default',
  },
});
 
export type ZardToastVariants = VariantProps<typeof toastVariants>;
 
3

Register toast to your project

app.component.ts'
app.component.ts'
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ZardToastComponent } from '@shared/components/toast/toast.component';
 
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, ZardToastComponent],
  template: `
    <router-outlet></router-outlet>
    <z-toaster />
  `,
})
export class AppComponent {}

Examples

default

import { Component } from '@angular/core';
import { toast } from 'ngx-sonner';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'zard-demo-toast',
  standalone: true,
  imports: [ZardButtonComponent],
  template: ` <button z-button zType="outline" (click)="showToast()">Show Toast</button> `,
})
export class ZardDemoToastDefaultComponent {
  showToast() {
    toast('Event has been created', {
      description: 'Sunday, December 03, 2023 at 9:00 AM',
      action: {
        label: 'Undo',
        onClick: () => console.log('Undo'),
      },
    });
  }
}
 

destructive

import { Component } from '@angular/core';
import { toast } from 'ngx-sonner';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'zard-demo-toast-destructive',
  standalone: true,
  imports: [ZardButtonComponent],
  template: ` <button z-button zType="outline" (click)="showToast()">Show Error Toast</button> `,
})
export class ZardDemoToastDestructiveComponent {
  showToast() {
    toast.error('Something went wrong', {
      description: 'There was a problem with your request.',
    });
  }
}
 

success

import { Component } from '@angular/core';
import { toast } from 'ngx-sonner';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'zard-demo-toast-success',
  standalone: true,
  imports: [ZardButtonComponent],
  template: ` <button z-button zType="outline" (click)="showToast()">Show Success Toast</button> `,
})
export class ZardDemoToastSuccessComponent {
  showToast() {
    toast.success('Event created successfully', {
      description: 'Your event has been saved and will start soon.',
    });
  }
}
 

loading

import { Component } from '@angular/core';
 
import { toast } from 'ngx-sonner';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'z-demo-toast-loading',
  standalone: true,
  imports: [ZardButtonComponent],
  template: ` <button z-button zType="outline" (click)="showToast()">Show Loading Toast</button> `,
})
export class ZardDemoToastLoadingComponent {
  showToast() {
    const promise = () => new Promise(resolve => setTimeout(() => resolve({ name: 'Sonner' }), 2000));
 
    toast.promise(promise, {
      loading: 'Loading...',
      success: (data: any) => {
        return `${data.name} has been created`;
      },
      error: 'Error',
    });
  }
}
 

advanced

import { Component } from '@angular/core';
 
import { toast } from 'ngx-sonner';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'z-demo-toast-advanced',
  standalone: true,
  imports: [ZardButtonComponent],
  template: `
    <div class="flex flex-wrap gap-2">
      <button z-button zType="outline" (click)="showWithAction()">With Action</button>
      <button z-button zType="outline" (click)="showCustomDuration()">Custom Duration</button>
    </div>
  `,
})
export class ZardDemoToastAdvancedComponent {
  showWithAction() {
    toast('Event created', {
      description: 'Your event has been saved successfully.',
      action: {
        label: 'View',
        onClick: () => console.log('View clicked'),
      },
    });
  }
 
  showCustomDuration() {
    toast('This toast lasts 8 seconds', {
      description: 'Custom duration example.',
      duration: 8000,
    });
  }
}
 

position

Top Left Top Center Top Right Bottom Left Bottom Center Bottom Right
import { toast } from 'ngx-sonner';
 
import { ChangeDetectionStrategy, Component } from '@angular/core';
 
import { ZardButtonComponent } from '../../button/button.component';
 
@Component({
  selector: 'zard-demo-toast-position',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ZardButtonComponent],
  template: `
    <div class="flex flex-wrap gap-2">
      <z-button zType="outline" (click)="showToast('top-left')"> Top Left </z-button>
 
      <z-button zType="outline" (click)="showToast('top-center')"> Top Center </z-button>
 
      <z-button zType="outline" (click)="showToast('top-right')"> Top Right </z-button>
 
      <z-button zType="outline" (click)="showToast('bottom-left')"> Bottom Left </z-button>
 
      <z-button zType="outline" (click)="showToast('bottom-center')"> Bottom Center </z-button>
 
      <z-button zType="outline" (click)="showToast('bottom-right')"> Bottom Right </z-button>
    </div>
  `,
})
export class ZardDemoToastPositionComponent {
  currentPosition: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' = 'bottom-right';
 
  showToast(position: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right') {
    this.currentPosition = position;
 
    toast(`Toast at ${position.replace('-', ' ')}`, {
      action: {
        label: 'Close',
        onClick: () => console.log('Toast closed'),
      },
      position: position,
    });
  }
}
 

API

[z-toaster] Component

z-toaster is a component that displays toast notifications. It uses ngx-sonner under the hood.

To customize the toaster, pass the following props to the component.

Property Description Type Default
[variant] Toast variant styling default | destructive default
[theme] Theme for the toasts light | dark | system system
[position] Position of the toast container top-left | top-center | top-right | bottom-left | bottom-center | bottom-right bottom-right
[richColors] Enable rich colors boolean false
[expand] Expand toasts by default boolean false
[duration] Auto-dismiss duration (ms) number 4000
[visibleToasts] Maximum visible toasts number 3
[closeButton] Show close button boolean false