Comprehensive Angular UI component library with 80+ components for building modern web applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
PrimeNG provides a comprehensive set of services for global state management, utility functions, and cross-component functionality to enhance your Angular application.
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();
}
}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');
}
}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);
});
}
}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[];
}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);
});
}
}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 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();
}
}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);
}
}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.
}
}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');
}
}
}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);
});
}
}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