CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-primeng

Comprehensive Angular UI component library with 80+ components for building modern web applications

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

overlay.mddocs/

Overlay

PrimeNG provides 8 overlay components for creating modals, dialogs, tooltips, and popup interfaces that appear above the main content layer.

Dialog Components

Dialog

Modal dialog window with header, content, and footer sections.

// Import
import { Dialog } from 'primeng/dialog';
// Module: DialogModule

// Component Interface
interface DialogProps {
  header?: string;
  draggable?: boolean;
  resizable?: boolean;
  positionLeft?: number;
  positionTop?: number;
  contentStyle?: any;
  contentStyleClass?: string;
  modal?: boolean;
  closeOnEscape?: boolean;
  dismissableMask?: boolean;
  rtl?: boolean;
  closable?: boolean;
  responsive?: boolean;
  appendTo?: any;
  breakpoints?: any;
  style?: any;
  styleClass?: string;
  maskStyleClass?: string;
  showHeader?: boolean;
  breakpoint?: string;
  blockScroll?: boolean;
  autoZIndex?: boolean;
  baseZIndex?: number;
  minX?: number;
  minY?: number;
  focusOnShow?: boolean;
  maximizable?: boolean;
  keepInViewport?: boolean;
  focusTrap?: boolean;
  transitionOptions?: string;
  closeIcon?: string;
  closeAriaLabel?: string;
  closeTabindex?: string;
  minimizeIcon?: string;
  maximizeIcon?: string;
}

// Events
interface DialogShowEvent {
  originalEvent?: Event;
}

interface DialogHideEvent {
  originalEvent?: Event;
}

interface DialogResizeInitEvent {
  originalEvent: MouseEvent;
  element: HTMLElement;
}

interface DialogResizeEndEvent {
  originalEvent: MouseEvent;
  element: HTMLElement;
}

interface DialogDragEndEvent {
  originalEvent: MouseEvent;
  element: HTMLElement;
}

// Usage
@Component({
  template: `
    <!-- Basic Dialog -->
    <p-dialog 
      header="Header" 
      [(visible)]="displayBasic" 
      [style]="{width: '50vw'}"
      (onShow)="onShow($event)"
      (onHide)="onHide($event)">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
      <ng-template pTemplate="footer">
        <p-button icon="pi pi-check" (onClick)="displayBasic=false" label="Ok" styleClass="p-button-text"></p-button>
      </ng-template>
    </p-dialog>

    <!-- Maximizable Dialog -->
    <p-dialog 
      header="Header" 
      [(visible)]="displayMaximizable" 
      [modal]="true" 
      [style]="{width: '50vw'}" 
      [maximizable]="true">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
      <ng-template pTemplate="footer">
        <p-button icon="pi pi-times" (onClick)="displayMaximizable=false" label="Cancel" styleClass="p-button-text"></p-button>
        <p-button icon="pi pi-check" (onClick)="displayMaximizable=false" label="Save"></p-button>
      </ng-template>
    </p-dialog>

    <!-- Position Dialog -->
    <p-dialog 
      header="Header" 
      [(visible)]="displayPosition" 
      [modal]="true" 
      [style]="{width: '50vw'}" 
      [position]="position" 
      [draggable]="false" 
      [resizable]="false">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
      <ng-template pTemplate="footer">
        <p-button icon="pi pi-check" (onClick)="displayPosition=false" label="Ok" styleClass="p-button-text"></p-button>
      </ng-template>
    </p-dialog>

    <!-- Custom Header Dialog -->
    <p-dialog 
      [(visible)]="displayCustomHeader" 
      [modal]="true" 
      [style]="{width: '50vw'}" 
      [draggable]="false" 
      [resizable]="false">
      <ng-template pTemplate="header">
        <div class="flex align-items-center gap-2">
          <p-avatar image="assets/showcase/images/demo/avatar/amyelsner.png" shape="circle"></p-avatar>
          <span class="font-bold white-space-nowrap">Amy Elsner</span>
        </div>
      </ng-template>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
      <ng-template pTemplate="footer">
        <p-button icon="pi pi-times" (onClick)="displayCustomHeader=false" label="Cancel" styleClass="p-button-text"></p-button>
        <p-button icon="pi pi-check" (onClick)="displayCustomHeader=false" label="Save"></p-button>
      </ng-template>
    </p-dialog>

    <div class="card flex justify-content-center gap-2 flex-wrap">
      <p-button (onClick)="showDialog()" icon="pi pi-external-link" label="Show"></p-button>
      <p-button (onClick)="showMaximizableDialog()" icon="pi pi-window-maximize" label="Maximizable"></p-button>
      <p-button (onClick)="showPositionDialog('top')" icon="pi pi-arrow-up" label="Top" styleClass="p-button-help"></p-button>
    </div>
  `
})
export class DialogComponent {
  displayBasic: boolean = false;
  displayMaximizable: boolean = false;
  displayPosition: boolean = false;
  displayCustomHeader: boolean = false;
  position: string = 'center';

  showDialog() {
    this.displayBasic = true;
  }

  showMaximizableDialog() {
    this.displayMaximizable = true;
  }

  showPositionDialog(position: string) {
    this.position = position;
    this.displayPosition = true;
  }

  onShow(event: DialogShowEvent) {
    console.log('Dialog shown');
  }

  onHide(event: DialogHideEvent) {
    console.log('Dialog hidden');
  }
}

ConfirmDialog

Confirmation dialog with accept/reject actions.

// Import
import { ConfirmDialog } from 'primeng/confirmdialog';
import { ConfirmationService } from 'primeng/api';
// Module: ConfirmDialogModule

// Service Configuration
interface Confirmation {
  message?: string;
  key?: string;
  icon?: string;
  header?: string;
  accept?: Function;
  reject?: Function;
  acceptLabel?: string;
  rejectLabel?: string;
  acceptIcon?: string;
  rejectIcon?: string;
  acceptVisible?: boolean;
  rejectVisible?: boolean;
  blockScroll?: boolean;
  closeOnEscape?: boolean;
  dismissableMask?: boolean;
  defaultFocus?: string;
  acceptButtonStyleClass?: string;
  rejectButtonStyleClass?: string;
  target?: EventTarget;
  acceptEvent?: Event;
  rejectEvent?: Event;
}

// Usage
@Component({
  template: `
    <p-toast></p-toast>
    <p-confirmdialog></p-confirmdialog>
    
    <!-- Multiple Confirm Dialogs -->
    <p-confirmdialog key="positionDialog" [position]="position" [style]="{width: '50vw'}"></p-confirmdialog>

    <div class="card flex flex-wrap gap-2 justify-content-center">
      <p-button (onClick)="confirm1()" icon="pi pi-check" label="Confirm" size="small"></p-button>
      <p-button (onClick)="confirm2()" icon="pi pi-times" label="Delete" severity="danger" size="small"></p-button>
      <p-button (onClick)="confirmPosition('top')" icon="pi pi-arrow-up" label="Top" size="small" styleClass="p-button-help"></p-button>
    </div>
  `,
  providers: [ConfirmationService]
})
export class ConfirmDialogComponent {
  position: string = 'center';

  constructor(private confirmationService: ConfirmationService, private messageService: MessageService) {}

  confirm1() {
    this.confirmationService.confirm({
      message: 'Are you sure that you want to proceed?',
      header: 'Confirmation',
      icon: 'pi pi-exclamation-triangle',
      accept: () => {
        this.messageService.add({severity:'info', summary:'Confirmed', detail:'You have accepted'});
      },
      reject: (type: any) => {
        switch(type) {
          case ConfirmEventType.REJECT:
            this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});
            break;
          case ConfirmEventType.CANCEL:
            this.messageService.add({severity:'warn', summary:'Cancelled', detail:'You have cancelled'});
            break;
        }
      }
    });
  }

  confirm2() {
    this.confirmationService.confirm({
      message: 'Do you want to delete this record?',
      header: 'Delete Confirmation',
      icon: 'pi pi-info-circle',
      acceptButtonStyleClass: 'p-button-danger p-button-text',
      rejectButtonStyleClass: 'p-button-text p-button-text',
      acceptIcon: 'none',
      rejectIcon: 'none',
      accept: () => {
        this.messageService.add({severity:'info', summary:'Confirmed', detail:'Record deleted'});
      },
      reject: () => {
        this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});
      }
    });
  }

  confirmPosition(position: string) {
    this.position = position;
    this.confirmationService.confirm({
      key: 'positionDialog',
      message: 'Do you want to delete this record?',
      header: 'Delete Confirmation',
      icon: 'pi pi-info-circle',
      accept: () => {
        this.messageService.add({severity:'info', summary:'Confirmed', detail:'Record deleted'});
      },
      reject: () => {
        this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});
      }
    });
  }
}

ConfirmPopup

Confirmation popup tooltip attached to target element.

// Import
import { ConfirmPopup } from 'primeng/confirmpopup';
import { ConfirmationService } from 'primeng/api';
// Module: ConfirmPopupModule

// Usage
@Component({
  template: `
    <p-toast></p-toast>
    <p-confirmpopup></p-confirmpopup>
    
    <div class="card flex flex-wrap gap-2 justify-content-center">
      <p-button (onClick)="confirm1($event)" icon="pi pi-check" label="Save" size="small"></p-button>
      <p-button (onClick)="confirm2($event)" icon="pi pi-times" label="Delete" severity="danger" size="small"></p-button>
    </div>
  `,
  providers: [ConfirmationService]
})
export class ConfirmPopupComponent {
  constructor(private confirmationService: ConfirmationService, private messageService: MessageService) {}

  confirm1(event: Event) {
    this.confirmationService.confirm({
      target: event.target as EventTarget,
      message: 'Are you sure that you want to proceed?',
      header: 'Confirmation',
      icon: 'pi pi-exclamation-triangle',
      acceptIcon: 'none',
      rejectIcon: 'none',
      rejectButtonStyleClass: 'p-button-text',
      accept: () => {
        this.messageService.add({severity:'info', summary:'Confirmed', detail:'You have accepted'});
      },
      reject: () => {
        this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});
      }
    });
  }

  confirm2(event: Event) {
    this.confirmationService.confirm({
      target: event.target as EventTarget,
      message: 'Do you want to delete this record?',
      header: 'Delete Confirmation',
      icon: 'pi pi-info-circle',
      acceptButtonStyleClass: 'p-button-danger p-button-text',
      rejectButtonStyleClass: 'p-button-text p-button-text',
      acceptIcon: 'none',
      rejectIcon: 'none',
      accept: () => {
        this.messageService.add({severity:'info', summary:'Confirmed', detail:'Record deleted'});
      },
      reject: () => {
        this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});
      }
    });
  }
}

DynamicDialog

Programmatically created dialogs with component injection.

// Import
import { DynamicDialogModule, DynamicDialogRef, DialogService } from 'primeng/dynamicdialog';

// Service Interface
interface DynamicDialogConfig {
  data?: any;
  header?: string;
  footer?: string;
  width?: string;
  height?: string;
  closeOnEscape?: boolean;
  baseZIndex?: number;
  autoZIndex?: boolean;
  dismissableMask?: boolean;
  rtl?: boolean;
  style?: any;
  contentStyle?: any;
  styleClass?: string;
  transitionOptions?: string;
  closable?: boolean;
  showHeader?: boolean;
  modal?: boolean;
  position?: string;
  blockScroll?: boolean;
  closeIcon?: string;
  minimizeIcon?: string;
  maximizeIcon?: string;
  maximizable?: boolean;
  keepInViewport?: boolean;
  focusOnShow?: boolean;
  focusTrap?: boolean;
  resizable?: boolean;
  draggable?: boolean;
  maskStyleClass?: string;
}

// Dynamic Component
@Component({
  template: `
    <div class="flex align-items-center gap-3 mb-3">
      <img src="assets/showcase/images/demo/avatar/{{data.image}}" alt="{{data.name}}" width="32" style="vertical-align: middle" />
      <div>
        <span class="font-bold">{{data.name}}</span>
        <div>{{data.email}}</div>
      </div>
    </div>
    
    <p>{{data.description}}</p>
    
    <div class="flex justify-content-end gap-2">
      <p-button label="Close" styleClass="p-button-text" (onClick)="closeDialog()"></p-button>
      <p-button label="Save" (onClick)="saveUser()"></p-button>
    </div>
  `
})
export class UserDetailComponent {
  constructor(
    public ref: DynamicDialogRef,
    public config: DynamicDialogConfig
  ) {}

  get data() {
    return this.config.data;
  }

  closeDialog() {
    this.ref.close();
  }

  saveUser() {
    this.ref.close(this.data);
  }
}

// Parent Component
@Component({
  template: `
    <p-toast></p-toast>
    
    <div class="card">
      <p-table [value]="users" selectionMode="single" [(selection)]="selectedUser" dataKey="id" 
               (onRowSelect)="onRowSelect($event)" [metaKeySelection]="false">
        <ng-template pTemplate="header">
          <tr>
            <th>Name</th>
            <th>Image</th>
            <th>Email</th>
          </tr>
        </ng-template>
        <ng-template pTemplate="body" let-user>
          <tr [pSelectableRow]="user">
            <td>{{user.name}}</td>
            <td><img src="assets/showcase/images/demo/avatar/{{user.image}}" alt="{{user.name}}" width="32" style="vertical-align: middle" /></td>
            <td>{{user.email}}</td>
          </tr>
        </ng-template>
      </p-table>
    </div>
  `,
  providers: [DialogService]
})
export class DynamicDialogComponent {
  users: User[] = [];
  selectedUser: User = {};
  ref: DynamicDialogRef | undefined;

  constructor(
    public dialogService: DialogService,
    public messageService: MessageService
  ) {}

  onRowSelect(event: any) {
    this.ref = this.dialogService.open(UserDetailComponent, {
      header: 'User Information',
      width: '50%',
      contentStyle: { overflow: 'auto' },
      baseZIndex: 10000,
      maximizable: true,
      data: event.data
    });

    this.ref.onClose.subscribe((result: User) => {
      if (result) {
        this.messageService.add({severity:'info', summary:'User Selected', detail: result.name});
      }
    });

    this.ref.onMaximize.subscribe((value) => {
      this.messageService.add({severity:'info', summary:'Maximized', detail: `maximized: ${value.maximized}`});
    });
  }

  ngOnDestroy() {
    if (this.ref) {
      this.ref.close();
    }
  }
}

Drawer Component

Drawer

Slide-out side panel for navigation or content.

// Import
import { Drawer } from 'primeng/drawer';
// Module: DrawerModule

// Component Interface
interface DrawerProps {
  visible?: boolean;
  position?: 'left' | 'right' | 'top' | 'bottom' | 'full';
  header?: string;
  style?: any;
  styleClass?: string;
  maskStyleClass?: string;
  contentStyle?: any;
  contentStyleClass?: string;
  modal?: boolean;
  dismissible?: boolean;
  showCloseIcon?: boolean;
  closeIcon?: string;
  autoZIndex?: boolean;
  baseZIndex?: number;
  transitionOptions?: string;
  focusTrap?: boolean;
  closeOnEscape?: boolean;
  blockScroll?: boolean;
}

// Events
interface DrawerShowEvent {
  originalEvent?: Event;
}

interface DrawerHideEvent {
  originalEvent?: Event;
}

// Usage
@Component({
  template: `
    <!-- Left Drawer -->
    <p-drawer header="Drawer" [(visible)]="visibleLeft" position="left" [style]="{width:'20rem'}">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </p-drawer>

    <!-- Right Drawer -->
    <p-drawer header="Drawer" [(visible)]="visibleRight" position="right" [style]="{width:'20rem'}">
      <ng-template pTemplate="header">
        <div class="flex align-items-center gap-2">
          <p-avatar image="assets/showcase/images/demo/avatar/amyelsner.png" shape="circle"></p-avatar>
          <span class="font-bold">Amy Elsner</span>
        </div>
      </ng-template>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
      <ng-template pTemplate="footer">
        <div class="flex gap-2">
          <p-button label="Save" (onClick)="visibleRight = false"></p-button>
          <p-button label="Cancel" severity="secondary" (onClick)="visibleRight = false"></p-button>
        </div>
      </ng-template>
    </p-drawer>

    <!-- Top Drawer -->
    <p-drawer header="Drawer" [(visible)]="visibleTop" position="top" [style]="{height:'20rem'}">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    </p-drawer>

    <!-- Bottom Drawer -->
    <p-drawer header="Drawer" [(visible)]="visibleBottom" position="bottom" [style]="{height:'20rem'}">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    </p-drawer>

    <!-- Full Screen Drawer -->
    <p-drawer header="Drawer" [(visible)]="visibleFull" position="full">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    </p-drawer>

    <div class="card flex justify-content-center gap-2 flex-wrap">
      <p-button (onClick)="visibleLeft = true" icon="pi pi-arrow-right" label="Left"></p-button>
      <p-button (onClick)="visibleRight = true" icon="pi pi-arrow-left" label="Right"></p-button>
      <p-button (onClick)="visibleTop = true" icon="pi pi-arrow-down" label="Top"></p-button>
      <p-button (onClick)="visibleBottom = true" icon="pi pi-arrow-up" label="Bottom"></p-button>
      <p-button (onClick)="visibleFull = true" icon="pi pi-external-link" label="Full Screen"></p-button>
    </div>
  `
})
export class DrawerComponent {
  visibleLeft: boolean = false;
  visibleRight: boolean = false;
  visibleTop: boolean = false;
  visibleBottom: boolean = false;
  visibleFull: boolean = false;
}

Popup Components

Popover

Floating content container positioned relative to target.

// Import
import { Popover } from 'primeng/popover';
// Module: PopoverModule

// Component Interface
interface PopoverProps {
  dismissable?: boolean;
  style?: any;
  styleClass?: string;
  appendTo?: any;
  autoZIndex?: boolean;
  baseZIndex?: number;
  showTransitionOptions?: string;
  hideTransitionOptions?: string;
  ariaLabel?: string;
  ariaLabelledBy?: string;
}

// Usage
@Component({
  template: `
    <div class="card flex justify-content-center">
      <p-button (onClick)="toggle($event)" icon="pi pi-share-alt" label="Share"></p-button>
      
      <p-popover #op>
        <div class="flex flex-column gap-3 w-25rem">
          <div>
            <span class="font-medium text-900 block mb-2">Share this document</span>
            <p-inputtext placeholder="Email" class="w-full" size="small"></p-inputtext>
          </div>
          <div>
            <div class="flex align-items-center gap-2 mb-2">
              <label for="link" class="font-medium text-900">Share with link</label>
              <p-inputswitch [(ngModel)]="linkActive"></p-inputswitch>
            </div>
            <p-inputtext [disabled]="!linkActive" placeholder="Role" class="w-full" size="small"></p-inputtext>
          </div>
          <div class="flex gap-2">
            <p-button label="Save" size="small" (onClick)="op.hide()"></p-button>
            <p-button label="Cancel" size="small" severity="secondary" (onClick)="op.hide()"></p-button>
          </div>
        </div>
      </p-popover>
    </div>

    <!-- Custom Popover -->
    <div class="card flex justify-content-center">
      <img src="assets/showcase/images/demo/avatar/amyelsner.png" 
           (click)="toggleUserPopover($event)" 
           alt="user-avatar" 
           class="w-3rem h-3rem cursor-pointer border-circle shadow-4" />
      
      <p-popover #userPopover>
        <div class="flex flex-column">
          <div class="flex align-items-center gap-2 mb-2">
            <img src="assets/showcase/images/demo/avatar/amyelsner.png" alt="user-avatar" class="w-2rem h-2rem" />
            <div>
              <div class="font-medium">Amy Elsner</div>
              <div class="text-sm text-color-secondary">Agent</div>
            </div>
          </div>
          <ul class="list-none p-0 m-0">
            <li class="border-bottom-1 surface-border p-2 hover:surface-hover cursor-pointer">Profile</li>
            <li class="border-bottom-1 surface-border p-2 hover:surface-hover cursor-pointer">Settings</li>
            <li class="p-2 hover:surface-hover cursor-pointer">Logout</li>
          </ul>
        </div>
      </p-popover>
    </div>
  `
})
export class PopoverComponent {
  linkActive: boolean = false;

  toggle(event: Event) {
    // Popover will be toggled via template reference
  }

  toggleUserPopover(event: Event) {
    // Popover will be toggled via template reference
  }
}

Overlay

Generic overlay container for custom positioning.

// Import
import { Overlay } from 'primeng/overlay';
// Module: OverlayModule

// Component Interface
interface OverlayProps {
  visible?: boolean;
  mode?: 'overlay' | 'modal';
  style?: any;
  styleClass?: string;
  contentStyle?: any;
  contentStyleClass?: string;
  target?: any;
  appendTo?: any;
  autoZIndex?: boolean;
  baseZIndex?: number;
  showTransitionOptions?: string;
  hideTransitionOptions?: string;
  listener?: any;
  responsive?: any;
  options?: OverlayOptions;
}

interface OverlayOptions {
  my?: string;
  at?: string;
  of?: any;
  collision?: string;
}

// Usage
@Component({
  template: `
    <div class="card flex justify-content-center">
      <p-button 
        type="button" 
        icon="pi pi-search" 
        (click)="toggle($event)" 
        aria-haspopup="true" 
        aria-controls="overlay_panel">
      </p-button>
      
      <p-overlay 
        [(visible)]="overlayVisible" 
        [target]="target" 
        [responsive]="responsiveOptions" 
        [showTransitionOptions]="'0.12s cubic-bezier(0, 0, 0.2, 1)'" 
        [hideTransitionOptions]="'0.12s cubic-bezier(0, 0, 0.2, 1)'"
        (onAnimationStart)="onOverlayClick($event)">
        <div class="flex flex-column gap-3 w-25rem">
          <div>
            <label for="search-input" class="font-medium text-900">Search Products</label>
            <span class="p-input-icon-left w-full mt-2">
              <i class="pi pi-search"></i>
              <input pInputText id="search-input" type="text" placeholder="Search" class="w-full" />
            </span>
          </div>
          <div>
            <label for="category-select" class="font-medium text-900">Category</label>
            <p-select 
              [options]="categories" 
              [(ngModel)]="selectedCategory" 
              optionLabel="name" 
              id="category-select" 
              placeholder="Select" 
              class="w-full mt-2">
            </p-select>
          </div>
          <div class="flex gap-2">
            <p-button label="Search" class="w-full"></p-button>
          </div>
        </div>
      </p-overlay>
    </div>
  `
})
export class OverlayComponent {
  overlayVisible: boolean = false;
  target: any;
  categories: any[] = [];
  selectedCategory: any;

  responsiveOptions: any = {
    '960px': {
      my: 'center top',
      at: 'center bottom',
      collision: 'flip'
    },
    '640px': {
      my: 'center top',
      at: 'center bottom',
      collision: 'flip'
    }
  };

  ngOnInit() {
    this.categories = [
      { name: 'Electronics', code: 'ELE' },
      { name: 'Clothing', code: 'CLO' },
      { name: 'Books', code: 'BOO' }
    ];
  }

  toggle(event: Event) {
    this.target = event.currentTarget;
    this.overlayVisible = !this.overlayVisible;
  }

  onOverlayClick(event: any) {
    if (event.toState === 'visible') {
      console.log('Overlay shown');
    }
  }
}

Toast Notifications

Toast

Non-intrusive notification messages.

// Import
import { Toast } from 'primeng/toast';
import { MessageService } from 'primeng/api';
// Module: ToastModule

// Component Interface
interface ToastProps {
  key?: string;
  autoZIndex?: boolean;
  baseZIndex?: number;
  style?: any;
  styleClass?: string;
  position?: 'top-right' | 'top-left' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center' | 'center';
  preventOpenDuplicates?: boolean;
  preventDuplicates?: boolean;
  showTransformOptions?: string;
  hideTransformOptions?: string;
  showTransitionOptions?: string;
  hideTransitionOptions?: string;
  breakpoints?: any;
}

// Message Interface
interface Message {
  severity?: 'success' | 'info' | 'warn' | 'error' | 'custom';
  summary?: string;
  detail?: string;
  id?: any;
  key?: string;
  life?: number;
  sticky?: boolean;
  closable?: boolean;
  data?: any;
  icon?: string;
  contentStyleClass?: string;
  styleClass?: string;
}

// Usage
@Component({
  template: `
    <p-toast></p-toast>
    <p-toast position="top-left" key="tl"></p-toast>
    <p-toast position="bottom-center" key="bc"></p-toast>
    
    <div class="card flex flex-wrap gap-2 justify-content-center">
      <p-button (onClick)="showSuccess()" label="Success" severity="success"></p-button>
      <p-button (onClick)="showInfo()" label="Info" severity="info"></p-button>
      <p-button (onClick)="showWarn()" label="Warn" severity="warning"></p-button>
      <p-button (onClick)="showError()" label="Error" severity="danger"></p-button>
      <p-button (onClick)="showTopLeft()" label="Top Left" styleClass="p-button-help"></p-button>
      <p-button (onClick)="showBottomCenter()" label="Bottom" styleClass="p-button-help"></p-button>
      <p-button (onClick)="showMultiple()" label="Multiple" severity="secondary"></p-button>
      <p-button (onClick)="showSticky()" label="Sticky"></p-button>
      <p-button (onClick)="showConfirm()" label="Confirm" severity="help"></p-button>
      <p-button (onClick)="clear()" label="Clear" class="p-button-secondary"></p-button>
    </div>
  `,
  providers: [MessageService]
})
export class ToastComponent {
  constructor(private messageService: MessageService) {}

  showSuccess() {
    this.messageService.add({severity:'success', summary: 'Success', detail: 'Message Content'});
  }

  showInfo() {
    this.messageService.add({severity:'info', summary: 'Info', detail: 'Message Content'});
  }

  showWarn() {
    this.messageService.add({severity:'warn', summary: 'Warn', detail: 'Message Content'});
  }

  showError() {
    this.messageService.add({severity:'error', summary: 'Error', detail: 'Message Content'});
  }

  showTopLeft() {
    this.messageService.add({key: 'tl', severity:'info', summary: 'Info', detail: 'Message Content'});
  }

  showBottomCenter() {
    this.messageService.add({key: 'bc', severity:'success', summary: 'Success', detail: 'Message Content'});
  }

  showSticky() {
    this.messageService.add({severity:'info', summary: 'Sticky', detail: 'Message Content', sticky: true});
  }

  showMultiple() {
    this.messageService.addAll([
      {severity:'info', summary: 'Message 1', detail: 'Message Content'},
      {severity:'info', summary: 'Message 2', detail: 'Message Content'},
      {severity:'info', summary: 'Message 3', detail: 'Message Content'}
    ]);
  }

  showConfirm() {
    this.messageService.clear();
    this.messageService.add({key: 'c', sticky: true, severity:'warn', summary:'Are you sure?', detail:'Confirm to proceed'});
  }

  onConfirm() {
    this.messageService.clear('c');
    this.messageService.add({severity:'info', summary:'Confirmed', detail:'You have accepted'});
  }

  onReject() {
    this.messageService.clear('c');
    this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});
  }

  clear() {
    this.messageService.clear();
  }
}

Overlay Service

The OverlayService provides global overlay management:

// Service Interface
class OverlayService {
  onShow: Subject<any>;
  onHide: Subject<any>;
}

// Usage
@Component({})
export class CustomComponent {
  constructor(private overlayService: OverlayService) {
    this.overlayService.onShow.subscribe(() => {
      console.log('Overlay shown');
    });

    this.overlayService.onHide.subscribe(() => {
      console.log('Overlay hidden');
    });
  }
}

Z-Index Management

PrimeNG automatically manages z-index layering for overlays:

// Global Configuration
providePrimeNG({
  zIndex: {
    modal: 1100,        // Dialog, Drawer
    overlay: 1000,      // Popover, Overlay
    menu: 1000,         // Context Menu, Menu
    tooltip: 1100       // Tooltip
  }
})

Accessibility Features

All overlay components include comprehensive accessibility support:

  • Focus management - Automatic focus trapping and restoration
  • ARIA attributes - Proper roles, labels, and states
  • Keyboard navigation - ESC to close, Tab navigation
  • Screen reader support - Announcements and descriptions
  • Modal behavior - Background interaction blocking

Install with Tessl CLI

npx tessl i tessl/npm-primeng

docs

data-display.md

form-controls.md

index.md

layout.md

navigation.md

overlay.md

services.md

tile.json