Alert

Displays a callout for user attention.

PreviousNext
Success! Your changes have been saved
This is an alert with icon, title and description.
This Alert has a title and an icon. No description.
Unable to process your payment.

Please verify your billing information and try again.

  • Check your card details
  • Ensure sufficient funds
  • Verify billing address
import { ChangeDetectionStrategy, Component } from '@angular/core';
 
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardAlertComponent } from '../alert.component';
 
@Component({
  selector: 'z-demo-alert-basic',
  imports: [ZardAlertComponent, ZardIconComponent],
  standalone: true,
  template: `
    <div class="grid w-full max-w-xl items-start gap-4">
      <z-alert
        zIcon="circle-check"
        zTitle="Success! Your changes have been saved"
        zDescription="This is an alert with icon, title and description."
      />
 
      <z-alert [zIcon]="customIcon" zTitle="This Alert has a title and an icon. No description." />
 
      <ng-template #customIcon>
        <z-icon zType="popcorn" />
      </ng-template>
 
      <z-alert zType="destructive" zTitle="Unable to process your payment." [zDescription]="customDescription" />
 
      <ng-template #customDescription>
        <p>Please verify your billing information and try again.</p>
        <ul class="list-disc pl-5">
          <li>Check your card details</li>
          <li>Ensure sufficient funds</li>
          <li>Verify billing address</li>
        </ul>
      </ng-template>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoAlertBasicComponent {}
 

Installation

1

Run the CLI

Use the CLI to add the component to your project.

npx @ngzard/ui@latest add alert
1

Add the component files

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

alert.component.ts
alert.component.ts
import { ChangeDetectionStrategy, Component, computed, input, TemplateRef, ViewEncapsulation } from '@angular/core';
 
import type { ClassValue } from 'clsx';
 
import {
  alertDescriptionVariants,
  alertIconVariants,
  alertTitleVariants,
  alertVariants,
  type ZardAlertVariants,
} from './alert.variants';
import { mergeClasses } from '../../shared/utils/utils';
import { ZardStringTemplateOutletDirective } from '../core/directives/string-template-outlet/string-template-outlet.directive';
import { ZardIconComponent } from '../icon/icon.component';
import type { ZardIcon } from '../icon/icons';
 
@Component({
  selector: 'z-alert, [z-alert]',
  imports: [ZardIconComponent, ZardStringTemplateOutletDirective],
  standalone: true,
  template: `
    @if (zIcon() || iconName()) {
      <span [class]="iconClasses()" data-slot="alert-icon">
        <ng-container *zStringTemplateOutlet="zIcon()">
          <z-icon [zType]="iconName()!" />
        </ng-container>
      </span>
    }
 
    <div class="flex-1">
      @if (zTitle()) {
        <div [class]="titleClasses()" data-slot="alert-title">
          <ng-container *zStringTemplateOutlet="zTitle()">{{ zTitle() }}</ng-container>
        </div>
      }
 
      @if (zDescription()) {
        <div [class]="descriptionClasses()" data-slot="alert-description">
          <ng-container *zStringTemplateOutlet="zDescription()">{{ zDescription() }}</ng-container>
        </div>
      }
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  host: {
    role: 'alert',
    '[class]': 'classes()',
    '[attr.data-slot]': '"alert"',
  },
  exportAs: 'zAlert',
})
export class ZardAlertComponent {
  readonly class = input<ClassValue>('');
  readonly zTitle = input<string | TemplateRef<void>>('');
  readonly zDescription = input<string | TemplateRef<void>>('');
  readonly zIcon = input<ZardIcon | TemplateRef<void>>();
  readonly zType = input<ZardAlertVariants['zType']>('default');
 
  protected readonly classes = computed(() => mergeClasses(alertVariants({ zType: this.zType() }), this.class()));
 
  protected readonly iconClasses = computed(() => alertIconVariants());
 
  protected readonly titleClasses = computed(() => alertTitleVariants());
 
  protected readonly descriptionClasses = computed(() => alertDescriptionVariants({ zType: this.zType() }));
 
  protected readonly iconName = computed((): ZardIcon | null => {
    const customIcon = this.zIcon();
    if (customIcon && !(customIcon instanceof TemplateRef)) {
      return customIcon;
    }
 
    if (this.zType() === 'destructive') return 'circle-alert';
 
    return null;
  });
}
 
alert.variants.ts
alert.variants.ts
import { cva, type VariantProps } from 'class-variance-authority';
 
export const alertVariants = cva('relative w-full rounded-lg border px-4 py-3 text-sm flex items-center gap-3', {
  variants: {
    zType: {
      default: 'bg-card text-card-foreground',
      destructive: 'text-destructive bg-card',
    },
  },
  defaultVariants: {
    zType: 'default',
  },
});
 
export const alertIconVariants = cva('shrink-0 self-start !text-base');
 
export const alertTitleVariants = cva('font-medium tracking-tight leading-none');
 
export const alertDescriptionVariants = cva('text-sm leading-relaxed mt-1', {
  variants: {
    zType: {
      default: 'text-muted-foreground',
      destructive: 'text-destructive/90',
    },
  },
  defaultVariants: {
    zType: 'default',
  },
});
 
export type ZardAlertVariants = VariantProps<typeof alertVariants>;
export type ZardAlertIconVariants = VariantProps<typeof alertIconVariants>;
export type ZardAlertTitleVariants = VariantProps<typeof alertTitleVariants>;
export type ZardAlertDescriptionVariants = VariantProps<typeof alertDescriptionVariants>;
 

Examples

basic

Success! Your changes have been saved
This is an alert with icon, title and description.
This Alert has a title and an icon. No description.
Unable to process your payment.

Please verify your billing information and try again.

  • Check your card details
  • Ensure sufficient funds
  • Verify billing address
import { ChangeDetectionStrategy, Component } from '@angular/core';
 
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardAlertComponent } from '../alert.component';
 
@Component({
  selector: 'z-demo-alert-basic',
  imports: [ZardAlertComponent, ZardIconComponent],
  standalone: true,
  template: `
    <div class="grid w-full max-w-xl items-start gap-4">
      <z-alert
        zIcon="circle-check"
        zTitle="Success! Your changes have been saved"
        zDescription="This is an alert with icon, title and description."
      />
 
      <z-alert [zIcon]="customIcon" zTitle="This Alert has a title and an icon. No description." />
 
      <ng-template #customIcon>
        <z-icon zType="popcorn" />
      </ng-template>
 
      <z-alert zType="destructive" zTitle="Unable to process your payment." [zDescription]="customDescription" />
 
      <ng-template #customDescription>
        <p>Please verify your billing information and try again.</p>
        <ul class="list-disc pl-5">
          <li>Check your card details</li>
          <li>Ensure sufficient funds</li>
          <li>Verify billing address</li>
        </ul>
      </ng-template>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoAlertBasicComponent {}
 

API Reference

z-alert Component

Property Description Type Default
[zTitle] Alert title string | TemplateRef<void> -
[zDescription] Alert description string | TemplateRef<void> -
[zIcon] Alert icon string | TemplateRef<void> -
[zType] Alert variant default | destructive default