sonner

An opinionated toast component for Angular.

PreviousNext
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { ZardSonnerService } from '@/shared/components/sonner/sonner.service';

@Component({
  selector: 'zard-demo-sonner-default',
  imports: [ZardButtonComponent],
  template: `
    <button type="button" z-button zType="outline" (click)="show()">Show Toast</button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSonnerDefaultComponent {
  private readonly sonner = inject(ZardSonnerService);

  show() {
    this.sonner.show('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.

Copy
npx zard-cli@latest add sonner
2

Register sonner to your project

app.component.ts
Copy
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ZardSonnerComponent } from '@/shared/components/sonner/sonner.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, ZardSonnerComponent],
  template: `
    <router-outlet></router-outlet>
    <z-sonner />
  `,
})
export class AppComponent {}

Usage

import { ZardSonnerComponent } from '@/shared/components/sonner/sonner.component';
Copy
<z-sonner />
Copy

Examples

types

import { ChangeDetectionStrategy, Component, inject } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { ZardSonnerService } from '@/shared/components/sonner/sonner.service';

@Component({
  selector: 'zard-demo-sonner-types',
  imports: [ZardButtonComponent],
  template: `
    <div class="flex flex-wrap gap-2">
      <button type="button" z-button zType="outline" (click)="sonner.show('Event has been created')">Default</button>
      <button type="button" z-button zType="outline" (click)="sonner.success('Event has been created')">Success</button>
      <button
        type="button"
        z-button
        zType="outline"
        (click)="sonner.info('Be at the area 10 minutes before the event time')"
      >
        Info
      </button>
      <button
        type="button"
        z-button
        zType="outline"
        (click)="sonner.warning('Event start time cannot be earlier than 8am')"
      >
        Warning
      </button>
      <button type="button" z-button zType="outline" (click)="sonner.error('Event has not been created')">Error</button>
      <button type="button" z-button zType="outline" (click)="showPromise()">Promise</button>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSonnerTypesComponent {
  protected readonly sonner = inject(ZardSonnerService);

  showPromise() {
    this.sonner.promise<{ name: string }>(
      () => new Promise(resolve => setTimeout(() => resolve({ name: 'Event' }), 2000)),
      {
        loading: 'Loading...',
        success: data => `${data.name} has been created`,
        error: 'Error',
      },
    );
  }
}

description

import { ChangeDetectionStrategy, Component, inject } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { ZardSonnerService } from '@/shared/components/sonner/sonner.service';

@Component({
  selector: 'zard-demo-sonner-description',
  imports: [ZardButtonComponent],
  template: `
    <button type="button" z-button zType="outline" class="w-fit" (click)="show()">Show Toast</button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSonnerDescriptionComponent {
  private readonly sonner = inject(ZardSonnerService);

  show() {
    this.sonner.show('Event has been created', {
      description: 'Monday, January 3rd at 6:00pm',
    });
  }
}

position

Use the position option to change the position of the toast.

import { ChangeDetectionStrategy, Component, inject } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { type ZardSonnerPosition } from '@/shared/components/sonner/sonner.component';
import { ZardSonnerService } from '@/shared/components/sonner/sonner.service';

@Component({
  selector: 'zard-demo-sonner-position',
  imports: [ZardButtonComponent],
  template: `
    <div class="flex flex-wrap justify-center gap-2">
      <button type="button" z-button zType="outline" (click)="show('top-left')">Top Left</button>
      <button type="button" z-button zType="outline" (click)="show('top-center')">Top Center</button>
      <button type="button" z-button zType="outline" (click)="show('top-right')">Top Right</button>
      <button type="button" z-button zType="outline" (click)="show('bottom-left')">Bottom Left</button>
      <button type="button" z-button zType="outline" (click)="show('bottom-center')">Bottom Center</button>
      <button type="button" z-button zType="outline" (click)="show('bottom-right')">Bottom Right</button>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSonnerPositionComponent {
  private readonly sonner = inject(ZardSonnerService);

  show(position: ZardSonnerPosition) {
    this.sonner.show('Event has been created', { position });
  }
}

API Reference

z-sonnerComponent

Container that renders toast notifications. Place once at the root of your app.

PropertyDescriptionTypeDefault
[theme] Theme used for the toasts. 'light' | 'dark' | 'system' 'system'
[position] Position of the toast container on the viewport. 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' 'top-center'
[richColors] Enables tinted backgrounds for success / error / warning / info toasts. boolean false
[expand] Expands toasts by default instead of stacking them. boolean false
[duration] Default auto-dismiss duration (ms). number 4000
[visibleToasts] Maximum number of toasts visible at the same time. number 3
[closeButton] Shows a close button on each toast. boolean false
[toastOptions] Default options applied to every toast (classes, duration, descriptions, etc). ToasterProps['toastOptions'] {}
[dir] Text direction for toasts. 'ltr' | 'rtl' | 'auto' 'auto'
[class] Additional Tailwind / utility classes merged into the host. ClassValue ''

ZardSonnerServiceComponent

Inject this service to dispatch toasts from any component or service.

PropertyDescriptionTypeDefault
show(message, options?) Dispatches a default toast and returns its id. (message: string | number, options?: ExternalToast) => string | number
success(message, options?) Dispatches a success-styled toast (green). (message: string | number, options?: ExternalToast) => string | number
error(message, options?) Dispatches an error-styled toast (red). (message: string | number, options?: ExternalToast) => string | number
warning(message, options?) Dispatches a warning-styled toast (yellow). (message: string | number, options?: ExternalToast) => string | number
info(message, options?) Dispatches an info-styled toast (blue). (message: string | number, options?: ExternalToast) => string | number
loading(message, options?) Dispatches a loading-styled toast with a spinner. (message: string | number, options?: ExternalToast) => string | number
message(message, options?) Dispatches a neutral message-styled toast. (message: string | number, options?: ExternalToast) => string | number
promise(promise, options) Binds a toast to the lifecycle of a promise (loading → success/error). <T>(promise: PromiseT<T>, options: PromiseData<T>) => string | number
dismiss(id?) Dismisses a toast by id, or all toasts when no id is provided. (id?: string | number) => void
github iconwhatsapp icondiscord iconX icon

Made with in Brazil. Open source and available on GitHub .