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

services.mddocs/

Services

PrimeNG provides a comprehensive set of services for global state management, utility functions, and cross-component functionality to enhance your Angular application.

Global Services

ConfirmationService

Manages confirmation dialogs and popups across the application.

// Import
import { ConfirmationService } from 'primeng/api';

// Service Interface
class ConfirmationService {
  // Properties
  requireConfirmationSource: Subject<Confirmation>;
  acceptConfirmationSource: Subject<Confirmation>;

  // Methods
  confirm(confirmation: Confirmation): this;
  close(): this;
  
  // Observables
  requireConfirmation$: Observable<Confirmation>;
  accept: Observable<Confirmation>;
}

// Confirmation 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-confirmdialog></p-confirmdialog>
    <p-button (onClick)="confirm()" label="Delete" severity="danger"></p-button>
  `,
  providers: [ConfirmationService]
})
export class ConfirmationExampleComponent {
  constructor(private confirmationService: ConfirmationService) {}

  confirm() {
    this.confirmationService.confirm({
      message: 'Are you sure you want to delete this item?',
      header: 'Delete Confirmation',
      icon: 'pi pi-exclamation-triangle',
      acceptButtonStyleClass: 'p-button-danger p-button-text',
      rejectButtonStyleClass: 'p-button-text p-button-text',
      accept: () => {
        // Handle acceptance
        console.log('Confirmed');
      },
      reject: () => {
        // Handle rejection
        console.log('Rejected');
      }
    });
  }

  // Multiple confirmation dialogs
  confirmWithKey() {
    this.confirmationService.confirm({
      key: 'custom-dialog',
      message: 'Custom confirmation dialog',
      header: 'Custom Header',
      accept: () => {
        console.log('Custom dialog accepted');
      }
    });
  }

  // Close all confirmations
  closeAllConfirmations() {
    this.confirmationService.close();
  }
}

MessageService

Handles toast notifications and inline messages throughout the application.

// Import
import { MessageService } from 'primeng/api';

// Service Interface
class MessageService {
  // Properties
  messageSource: Subject<Message>;
  clearSource: Subject<string>;

  // Methods
  add(message: Message): void;
  addAll(messages: Message[]): void;
  clear(key?: string): void;

  // Observables
  messageObserver: Observable<Message>;
  clearObserver: Observable<string>;
}

// Message Configuration
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 key="custom" position="top-left"></p-toast>
    
    <div class="flex gap-2">
      <p-button (onClick)="showSuccess()" label="Success" severity="success"></p-button>
      <p-button (onClick)="showError()" label="Error" severity="danger"></p-button>
      <p-button (onClick)="showCustom()" label="Custom" severity="help"></p-button>
      <p-button (onClick)="showMultiple()" label="Multiple" severity="secondary"></p-button>
      <p-button (onClick)="clear()" label="Clear"></p-button>
    </div>
  `,
  providers: [MessageService]
})
export class MessageExampleComponent {
  constructor(private messageService: MessageService) {}

  showSuccess() {
    this.messageService.add({
      severity: 'success',
      summary: 'Success',
      detail: 'Operation completed successfully',
      life: 3000
    });
  }

  showError() {
    this.messageService.add({
      severity: 'error',
      summary: 'Error',
      detail: 'Something went wrong',
      sticky: true
    });
  }

  showCustom() {
    this.messageService.add({
      key: 'custom',
      severity: 'info',
      summary: 'Custom Toast',
      detail: 'This appears in top-left corner'
    });
  }

  showMultiple() {
    this.messageService.addAll([
      { severity: 'info', summary: 'Message 1', detail: 'First message' },
      { severity: 'warn', summary: 'Message 2', detail: 'Second message' },
      { severity: 'error', summary: 'Message 3', detail: 'Third message' }
    ]);
  }

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

  clearCustom() {
    this.messageService.clear('custom');
  }
}

OverlayService

Manages overlay components and their z-index layering.

// Import
import { OverlayService } from 'primeng/api';

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

  // Methods (internal use)
  private add(overlay: any): void;
  private remove(overlay: any): void;
}

// Usage
@Component({})
export class OverlayExampleComponent {
  constructor(private overlayService: OverlayService) {
    // Listen to overlay events
    this.overlayService.onShow.subscribe((event) => {
      console.log('Overlay shown:', event);
    });

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

FilterService

Provides data filtering utilities for tables and data components.

// Import
import { FilterService } from 'primeng/api';

// Service Interface
class FilterService {
  // Methods
  filter(data: any[], fields: string[], filterValue: any, filterMatchMode: string, filterLocale?: string): any[];
  filters: { [key: string]: (value: any, filter: any, filterLocale?: string) => boolean };
  
  // Built-in filter functions
  startsWith(value: any, filter: any, filterLocale?: string): boolean;
  contains(value: any, filter: any, filterLocale?: string): boolean;
  notContains(value: any, filter: any, filterLocale?: string): boolean;
  endsWith(value: any, filter: any, filterLocale?: string): boolean;
  equals(value: any, filter: any, filterLocale?: string): boolean;
  notEquals(value: any, filter: any, filterLocale?: string): boolean;
  in(value: any, filter: any[]): boolean;
  between(value: any, filter: any[]): boolean;
  lt(value: any, filter: any, filterLocale?: string): boolean;
  lte(value: any, filter: any, filterLocale?: string): boolean;
  gt(value: any, filter: any, filterLocale?: string): boolean;
  gte(value: any, filter: any, filterLocale?: string): boolean;
  is(value: any, filter: any, filterLocale?: string): boolean;
  isNot(value: any, filter: any, filterLocale?: string): boolean;
  before(value: any, filter: any, filterLocale?: string): boolean;
  after(value: any, filter: any, filterLocale?: string): boolean;
  dateIs(value: any, filter: any): boolean;
  dateIsNot(value: any, filter: any): boolean;
  dateBefore(value: any, filter: any): boolean;
  dateAfter(value: any, filter: any): boolean;
}

// Usage
@Injectable({
  providedIn: 'root'
})
export class CustomFilterService {
  constructor(private filterService: FilterService) {
    // Register custom filter
    this.filterService.filters['customFilter'] = this.customFilterFunction.bind(this);
  }

  // Custom filter function
  customFilterFunction(value: any, filter: any): boolean {
    if (filter === undefined || filter === null || filter.trim() === '') {
      return true;
    }

    if (value === undefined || value === null) {
      return false;
    }

    return value.toString().toLowerCase().includes(filter.toString().toLowerCase());
  }

  // Use filter service for custom filtering
  filterData(data: any[], searchTerm: string): any[] {
    return this.filterService.filter(
      data, 
      ['name', 'description'], 
      searchTerm, 
      'customFilter'
    );
  }

  // Advanced filtering example
  advancedFilter(products: Product[], criteria: FilterCriteria): Product[] {
    let filtered = products;

    if (criteria.name) {
      filtered = this.filterService.filter(
        filtered, 
        ['name'], 
        criteria.name, 
        'contains'
      );
    }

    if (criteria.priceRange) {
      filtered = this.filterService.filter(
        filtered, 
        ['price'], 
        criteria.priceRange, 
        'between'
      );
    }

    if (criteria.categories && criteria.categories.length > 0) {
      filtered = this.filterService.filter(
        filtered, 
        ['category'], 
        criteria.categories, 
        'in'
      );
    }

    return filtered;
  }
}

interface FilterCriteria {
  name?: string;
  priceRange?: [number, number];
  categories?: string[];
}

TreeDragDropService

Handles drag and drop operations for tree components.

// Import
import { TreeDragDropService } from 'primeng/api';

// Service Interface
class TreeDragDropService {
  // Properties
  dragStartSource: Subject<TreeNodeDragEvent>;
  dragStopSource: Subject<TreeNodeDragEvent>;

  // Methods
  startDrag(event: TreeNodeDragEvent): void;
  stopDrag(event: TreeNodeDragEvent): void;

  // Observables
  dragStart$: Observable<TreeNodeDragEvent>;
  dragStop$: Observable<TreeNodeDragEvent>;
}

// Drag Event Interface
interface TreeNodeDragEvent {
  tree?: any;
  node?: TreeNode;
  subNodes?: TreeNode[];
  index?: number;
  scope?: any;
}

// Usage
@Component({
  template: `
    <div class="grid">
      <div class="col-6">
        <p-tree 
          [value]="files1" 
          [draggableNodes]="true" 
          draggableScope="files"
          droppableScope="files"
          selectionMode="single"
          [(selection)]="selectedFile1">
        </p-tree>
      </div>
      <div class="col-6">
        <p-tree 
          [value]="files2" 
          [draggableNodes]="true" 
          [droppableNodes]="true"
          draggableScope="files"
          droppableScope="files"
          selectionMode="single"
          [(selection)]="selectedFile2">
        </p-tree>
      </div>
    </div>
  `,
  providers: [TreeDragDropService]
})
export class TreeDragDropExampleComponent {
  files1: TreeNode[] = [];
  files2: TreeNode[] = [];
  selectedFile1: TreeNode | undefined;
  selectedFile2: TreeNode | undefined;

  constructor(private treeDragDropService: TreeDragDropService) {
    // Listen to drag events
    this.treeDragDropService.dragStart$.subscribe((event: TreeNodeDragEvent) => {
      console.log('Drag started:', event);
    });

    this.treeDragDropService.dragStop$.subscribe((event: TreeNodeDragEvent) => {
      console.log('Drag stopped:', event);
    });
  }
}

ContextMenuService

Manages context menu state and interactions.

// Import
import { ContextMenuService } from 'primeng/api';

// Service Interface (internal use)
class ContextMenuService {
  activeContextMenu: any;

  show(contextMenu: any): void;
  reset(): void;
}

// Usage with ContextMenu component
@Component({
  template: `
    <p-contextmenu #cm [global]="true" [model]="items"></p-contextmenu>
    
    <div class="card">
      <img 
        src="assets/showcase/images/demo/nature/nature3.jpg" 
        alt="Logo" 
        (contextmenu)="cm.show($event)" 
        class="w-full md:w-auto">
    </div>
  `
})
export class ContextMenuExampleComponent {
  items: MenuItem[] = [];

  ngOnInit() {
    this.items = [
      { label: 'View', icon: 'pi pi-fw pi-search' },
      { label: 'Delete', icon: 'pi pi-fw pi-times' }
    ];
  }
}

Utility Services and Classes

DomHandler

Utility class for DOM manipulation and calculations.

// Import
import { DomHandler } from 'primeng/dom';

// Utility Class (static methods)
class DomHandler {
  // Element queries
  static addClass(element: any, className: string): void;
  static removeClass(element: any, className: string): void;
  static hasClass(element: any, className: string): boolean;
  static siblings(element: any): any;
  static find(element: any, selector: string): any[];
  static findSingle(element: any, selector: string): any;
  static index(element: any): number;
  static indexWithinGroup(element: any, attributeName: string): number;

  // Positioning and sizing
  static getOuterWidth(el: any, margin?: boolean): number;
  static getOuterHeight(el: any, margin?: boolean): number;
  static getHiddenElementOuterWidth(element: any): number;
  static getHiddenElementOuterHeight(element: any): number;
  static getClientHeight(element: any, margin?: boolean): number;
  static getViewport(): any;
  static getOffset(el: any): any;
  static generateZIndex(): number;
  static getCurrentZIndex(): number;

  // Scrolling
  static scrollInView(container: any, item: any): void;
  static fadeIn(element: any, duration: number): void;
  static fadeOut(element: any, duration: number): void;

  // Focus management
  static focus(el: any, options?: FocusOptions): void;
  static getFocusableElements(element: any): any[];
  static getFirstFocusableElement(element: any): any;
  static getLastFocusableElement(element: any): any;

  // Browser detection
  static isIOS(): boolean;
  static isAndroid(): boolean;
  static isTouchDevice(): boolean;

  // Calculations
  static calculateScrollbarWidth(): number;
  static invokeElementMethod(element: any, methodName: string, args?: any[]): void;
  static clearSelection(): void;
  static getBrowser(): any;
}

// Usage
@Component({})
export class DomUtilityComponent {
  ngAfterViewInit() {
    const element = document.getElementById('myElement');
    
    // Add/remove classes
    DomHandler.addClass(element, 'highlight');
    DomHandler.removeClass(element, 'old-class');
    
    // Check if element has class
    if (DomHandler.hasClass(element, 'active')) {
      console.log('Element is active');
    }

    // Get dimensions
    const width = DomHandler.getOuterWidth(element, true);
    const height = DomHandler.getOuterHeight(element, true);
    
    // Get viewport info
    const viewport = DomHandler.getViewport();
    console.log('Viewport:', viewport);

    // Focus management
    const focusableElements = DomHandler.getFocusableElements(element);
    if (focusableElements.length > 0) {
      DomHandler.focus(focusableElements[0]);
    }

    // Browser detection
    if (DomHandler.isTouchDevice()) {
      console.log('Touch device detected');
    }

    // Generate z-index
    const zIndex = DomHandler.generateZIndex();
    element.style.zIndex = zIndex.toString();
  }
}

ObjectUtils

Utility functions for object manipulation and comparison.

// Import
import { ObjectUtils } from 'primeng/utils';

// Utility Class (static methods)
class ObjectUtils {
  // Object property access
  static equals(obj1: any, obj2: any, field?: string): boolean;
  static deepEquals(a: any, b: any): boolean;
  static resolveFieldData(data: any, field: string): any;
  static filter(value: any[], fields: any[], filterValue: any): any[];

  // Array utilities
  static reorderArray(value: any[], from: number, to: number): void;
  static findIndexInList(value: any, list: any[], dataKey?: string): number;
  static contains(value: any, list: any[]): boolean;
  static insertIntoOrderedArray(item: any, index: number, arr: any[], sourceArr: any[]): void;
  static findDiffKeys(obj1: any, obj2: any): any;

  // Type checking
  static isArray(value: any, empty?: boolean): boolean;
  static isDate(value: any): boolean;
  static isEmpty(value: any): boolean;
  static isNotEmpty(value: any): boolean;
  static isFunction(value: any): boolean;
  static isObject(value: any, empty?: boolean): boolean;
  static isString(value: any, empty?: boolean): boolean;

  // Data transformation
  static removeAccents(str: string): string;
  static toFlatCase(str: string): string;
  static toCapitalCase(str: string): string;
  static uuid(): string;
}

// Usage
@Component({})
export class ObjectUtilityComponent {
  ngOnInit() {
    // Object comparison
    const obj1 = { name: 'John', age: 30 };
    const obj2 = { name: 'John', age: 30 };
    const areEqual = ObjectUtils.deepEquals(obj1, obj2); // true

    // Field data resolution
    const user = { profile: { name: 'John Doe' } };
    const name = ObjectUtils.resolveFieldData(user, 'profile.name'); // 'John Doe'

    // Array filtering
    const users = [
      { name: 'John Doe', city: 'New York' },
      { name: 'Jane Smith', city: 'London' }
    ];
    const filtered = ObjectUtils.filter(users, ['name', 'city'], 'John'); // [{ name: 'John Doe', city: 'New York' }]

    // Type checking
    if (ObjectUtils.isArray(users)) {
      console.log('users is an array');
    }

    if (ObjectUtils.isEmpty(null)) {
      console.log('Value is empty');
    }

    // String utilities
    const flatCase = ObjectUtils.toFlatCase('Hello World'); // 'helloworld'
    const capitalCase = ObjectUtils.toCapitalCase('hello world'); // 'Hello World'
    const cleanStr = ObjectUtils.removeAccents('café'); // 'cafe'

    // Generate UUID
    const id = ObjectUtils.uuid();
    console.log('Generated UUID:', id);

    // Array manipulation
    const items = [1, 2, 3, 4, 5];
    ObjectUtils.reorderArray(items, 0, 4); // Move first item to last position
    console.log(items); // [2, 3, 4, 5, 1]

    // Find index in array
    const index = ObjectUtils.findIndexInList({ id: 2 }, users, 'id');
    console.log('Index:', index);
  }
}

UniqueComponentId

Generates unique IDs for components.

// Import
import { UniqueComponentId } from 'primeng/utils';

// Function
function UniqueComponentId(prefix?: string): string;

// Usage
@Component({
  template: `
    <div [id]="elementId">
      <label [for]="inputId">Label</label>
      <input [id]="inputId" type="text">
    </div>
  `
})
export class UniqueIdComponent {
  elementId: string;
  inputId: string;

  constructor() {
    this.elementId = UniqueComponentId('element');
    this.inputId = UniqueComponentId('input');
    // Results in IDs like: 'element_1', 'input_2', etc.
  }
}

Configuration Service

PrimeNG Configuration

Global configuration service for theme, locale, and behavior settings.

// Import
import { PrimeNG, providePrimeNG } from 'primeng/config';

// Configuration Interface
interface PrimeNGConfigType {
  ripple?: boolean;
  inputStyle?: 'outlined' | 'filled';
  overlayOptions?: OverlayOptions;
  csp?: {
    nonce?: string;
  };
  filterMatchModeOptions?: {
    text?: FilterMatchMode[];
    numeric?: FilterMatchMode[];
    date?: FilterMatchMode[];
  };
  translation?: Translation;
  zIndex?: {
    modal?: number;
    overlay?: number;
    menu?: number;
    tooltip?: number;
  };
  theme?: {
    preset?: any;
    options?: any;
  };
}

// Service Class
@Injectable({
  providedIn: 'root'
})
export class PrimeNG {
  ripple: Signal<boolean>;
  theme: Signal<any>;
  overlayOptions: Signal<OverlayOptions>;
  csp: Signal<any>;
  filterMatchModeOptions: Signal<any>;
  translation: Signal<any>;
  zIndex: Signal<any>;
  inputStyle: Signal<string>;

  update(config: PrimeNGConfigType): void;
  getTranslation(key: string): string;
}

// Global Provider Setup
import { bootstrapApplication } from '@angular/platform-browser';

bootstrapApplication(AppComponent, {
  providers: [
    providePrimeNG({
      theme: {
        preset: 'Aura',
        options: {
          darkModeSelector: '.p-dark'
        }
      },
      ripple: true,
      inputStyle: 'outlined',
      zIndex: {
        modal: 1100,
        overlay: 1000,
        menu: 1000,
        tooltip: 1100
      },
      translation: {
        accept: 'Accept',
        reject: 'Reject',
        choose: 'Choose',
        upload: 'Upload',
        cancel: 'Cancel',
        dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
        dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
        monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      }
    })
  ]
});

// Component Usage
@Component({})
export class ConfigExampleComponent {
  constructor(private primeng: PrimeNG) {}

  ngOnInit() {
    // Get current configuration
    console.log('Ripple enabled:', this.primeng.ripple());
    console.log('Current theme:', this.primeng.theme());
    console.log('Input style:', this.primeng.inputStyle());

    // Update configuration
    this.primeng.update({
      ripple: false,
      inputStyle: 'filled'
    });

    // Get translation
    const acceptLabel = this.primeng.getTranslation('accept');
    console.log('Accept label:', acceptLabel);
  }

  // Dynamic theme switching
  toggleTheme() {
    const currentTheme = this.primeng.theme();
    const isDark = currentTheme?.options?.darkModeSelector === '.p-dark';
    
    this.primeng.update({
      theme: {
        preset: 'Aura',
        options: {
          darkModeSelector: isDark ? false : '.p-dark'
        }
      }
    });

    // Toggle CSS class on document
    if (isDark) {
      document.documentElement.classList.remove('p-dark');
    } else {
      document.documentElement.classList.add('p-dark');
    }
  }
}

Custom Service Integration

Creating custom services that work with PrimeNG:

@Injectable({
  providedIn: 'root'
})
export class CustomDataService {
  constructor(
    private messageService: MessageService,
    private confirmationService: ConfirmationService,
    private filterService: FilterService
  ) {}

  async saveData(data: any): Promise<boolean> {
    try {
      // Simulate API call
      await this.simulateApiCall();
      
      this.messageService.add({
        severity: 'success',
        summary: 'Success',
        detail: 'Data saved successfully'
      });
      
      return true;
    } catch (error) {
      this.messageService.add({
        severity: 'error',
        summary: 'Error',
        detail: 'Failed to save data'
      });
      
      return false;
    }
  }

  confirmDelete(item: any): Promise<boolean> {
    return new Promise((resolve) => {
      this.confirmationService.confirm({
        message: `Are you sure you want to delete ${item.name}?`,
        header: 'Delete Confirmation',
        icon: 'pi pi-exclamation-triangle',
        accept: () => resolve(true),
        reject: () => resolve(false)
      });
    });
  }

  searchAndFilter(data: any[], searchTerm: string, fields: string[]): any[] {
    if (!searchTerm) {
      return data;
    }

    return this.filterService.filter(data, fields, searchTerm, 'contains');
  }

  private simulateApiCall(): Promise<void> {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (Math.random() > 0.1) { // 90% success rate
          resolve();
        } else {
          reject(new Error('Simulated API error'));
        }
      }, 1000);
    });
  }
}

Service Dependencies

When using PrimeNG services, ensure proper dependency injection:

// Module setup (if using NgModules)
@NgModule({
  providers: [
    ConfirmationService,
    MessageService,
    // Other services are provided automatically
  ]
})
export class AppModule {}

// Standalone component setup
@Component({
  standalone: true,
  providers: [
    ConfirmationService,
    MessageService
  ]
})
export class StandaloneComponent {}

PrimeNG services provide a robust foundation for building complex Angular applications with consistent user experience patterns, global state management, and utility functions that enhance development productivity.

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