ng-prime-tools
Version:
An advanced PrimeNG table for Angular
938 lines (761 loc) • 28.7 kB
Markdown
An advanced PrimeNG tools library for Angular.
- [Introduction](
- [Installation](
- [Compatibility](
- [PrimeNG Theme Configuration](
- [Usage](
- [pt-advanced-prime-table](
- [Inputs](
- [Outputs](
- [Example](
- [multi-search-criteria](
- [Inputs](
- [Outputs](
- [Example](
- [FormBuilder](
- [Components](
- [Example](
- [Changelog](
- [License](
`ng-prime-tools` is a collection of advanced reusable UI tools built on top of PrimeNG for Angular applications.
The library provides configurable components for advanced tables, dynamic forms, dashboards, cards, menus, dialogs, charts, search criteria, page skeletons, and other common application needs.
Version `2.x` targets Angular 21 and PrimeNG 21.
Install `ng-prime-tools` with its required peer dependencies:
```bash
npm install ng-prime-tools
npm install primeng @primeng/themes primeicons primeflex
npm install chart.js chartjs-plugin-datalabels
```
For Angular 21, use a compatible Node.js, TypeScript, and RxJS environment.
Recommended versions:
- Node.js: `^20.19.0 || ^22.12.0 || ^24.0.0`
- TypeScript: `>=5.9.0 <6.0.0`
- RxJS: `^7.4.0`
- Zone.js: `~0.15.1`
Angular 21 officially supports Node.js `^20.19.0 || ^22.12.0 || ^24.0.0`, TypeScript `>=5.9.0 <6.0.0`, and RxJS `^6.5.3 || ^7.4.0`. For this library, RxJS `^7.4.0` is recommended.
| Library | Version |
| ------------------------- | ---------------- |
| Angular | `^21.0.0` |
| PrimeNG | `^21.0.0` |
| @primeng/themes | `^21.0.0` |
| PrimeIcons | `^7.0.0` |
| PrimeFlex | `^4.0.0` |
| Chart.js | `^4.4.4` |
| chartjs-plugin-datalabels | `^2.2.0` |
| RxJS | `^7.4.0` |
| TypeScript | `>=5.9.0 <6.0.0` |
| Zone.js | `~0.15.1` |
`ng-prime-tools` version `2.x` targets Angular 21 and PrimeNG 21.
For Angular 17 / PrimeNG 17 applications, use the previous `1.x` version of the library.
PrimeNG 21 uses the styled-mode theme system with presets such as Aura, Material, Lara, and Nora. It no longer relies on the old global CSS imports from `primeng/resources/...`.
Remove these old style entries from `angular.json` if they exist:
```json
"node_modules/primeng/resources/themes/saga-blue/theme.css",
"node_modules/primeng/resources/primeng.min.css"
```
Keep only the application stylesheet and the icon/layout libraries:
```json
"styles": [
"src/styles.css",
"node_modules/primeicons/primeicons.css",
"node_modules/@fortawesome/fontawesome-free/css/all.min.css",
"node_modules/primeflex/primeflex.css"
]
```
Then configure PrimeNG using `providePrimeNG`.
Example `app.config.ts`:
```typescript
import { ApplicationConfig } from "@angular/core";
import { provideRouter } from "@angular/router";
import { provideAnimations } from "@angular/platform-browser/animations";
import { providePrimeNG } from "primeng/config";
import Aura from "@primeng/themes/aura";
import { routes } from "./app.routes";
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideAnimations(),
providePrimeNG({
theme: {
preset: Aura,
},
}),
],
};
```
To use the `pt-advanced-prime-table` component, follow these steps.
Import `PTAdvancedPrimeTableModule` in your Angular module or standalone component.
```typescript
import { PTAdvancedPrimeTableModule, TableColumn, TableTypeEnum } from "ng-prime-tools";
```
Add the `pt-advanced-prime-table` component to your template:
```html
<pt-advanced-prime-table [columns]="columns" [data]="data" [hasSearchFilter]="true" [hasColumnFilter]="true" [isPaginated]="true" [totalRecords]="totalRecords" [isSortable]="true"></pt-advanced-prime-table>
```
```typescript
import { Component, OnInit } from "@angular/core";
import { CommonModule } from "@angular/common";
import { PTAdvancedPrimeTableModule, TableColumn, TableTypeEnum } from "ng-prime-tools";
@Component({
selector: "app-root",
standalone: true,
imports: [CommonModule, PTAdvancedPrimeTableModule],
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
export class AppComponent implements OnInit {
columns: TableColumn[] = [];
data: any[] = [];
totalRecords = 0;
ngOnInit(): void {
this.columns = [
{
title: "Name",
code: "name",
type: TableTypeEnum.STRING,
isEditable: true,
},
{
title: "Date",
code: "date",
type: TableTypeEnum.DATE,
isEditable: true,
},
{
title: "Amount",
code: "amount",
type: TableTypeEnum.AMOUNT,
currency: "USD",
isEditable: true,
},
];
this.data = [
{ name: "John Doe", date: "11/06/2024", amount: 100 },
{ name: "Jane Doe", date: "20/06/2024", amount: 200 },
];
this.totalRecords = this.data.length;
}
}
```
- **data** (`any[]`): The data to be displayed in the table.
- **columns** (`TableColumn[]`): The column configuration for the table.
- **totalRecords** (`number`): The total number of records.
- **rowsPerPage** (`number[]`): The number of rows per page options for pagination.
- **hasSearchFilter** (`boolean`): Enables or disables the global search filter.
- **hasColumnFilter** (`boolean`): Enables or disables column-specific filters.
- **isPaginated** (`boolean`): Enables or disables pagination.
- **actions** (`any[]`): The actions available for table rows.
- **isSortable** (`boolean`): Enables or disables sortable columns.
- **filter** (`EventEmitter`): Emitted when the table is filtered.
- **search** (`EventEmitter<any>`): Emitted when a global search is performed.
```typescript
import { Component, OnInit } from "@angular/core";
import { CommonModule } from "@angular/common";
import { PTAdvancedPrimeTableModule, TableColumn, TableTypeEnum } from "ng-prime-tools";
@Component({
selector: "app-root",
standalone: true,
imports: [CommonModule, PTAdvancedPrimeTableModule],
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
export class AppComponent implements OnInit {
columns: TableColumn[] = [];
data: any[] = [];
totalRecords = 0;
ngOnInit(): void {
this.columns = [
{
title: "Name",
code: "name",
type: TableTypeEnum.STRING,
isEditable: true,
},
{
title: "Date",
code: "date",
type: TableTypeEnum.DATE,
isEditable: true,
},
{
title: "Amount",
code: "amount",
type: TableTypeEnum.AMOUNT,
currency: "USD",
isEditable: true,
},
];
this.data = [
{ name: "ZAK JAAI", date: "11/06/2024", amount: 100 },
{ name: "ZAK2 JAAI", date: "20/06/2024", amount: 200 },
];
this.totalRecords = this.data.length;
}
}
```
```html
<pt-advanced-prime-table [columns]="columns" [data]="data" [hasSearchFilter]="true" [hasColumnFilter]="true" [isPaginated]="true" [totalRecords]="totalRecords" [isSortable]="true"></pt-advanced-prime-table>
```
To use the `multi-search-criteria` component, follow these steps.
```typescript
import { MultiSearchCriteriaModule, SearchCriteria, SearchCriteriaTypeEnum } from "ng-prime-tools";
```
```html
<multi-search-criteria [title]="'Multi-Criteria Search'" [criteria]="criteria" [data]="data" [mode]="'dynamic'" (filteredData)="onFilteredData($event)" (searchCriteria)="onSearchData($event)"></multi-search-criteria>
```
```typescript
import { Component, OnInit } from "@angular/core";
import { CommonModule } from "@angular/common";
import { MultiSearchCriteriaModule, SearchCriteria, SearchCriteriaTypeEnum, FilterOption } from "ng-prime-tools";
@Component({
selector: "app-root",
standalone: true,
imports: [CommonModule, MultiSearchCriteriaModule],
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
export class AppComponent implements OnInit {
criteria: SearchCriteria[] = [];
data: any[] = [];
filteredData: any[] = [];
totalRecords = 0;
ngOnInit(): void {
this.criteria = [
{
title: "Name",
code: "name",
type: SearchCriteriaTypeEnum.STRING,
},
{
title: "Date Range",
code: "dateRange",
type: SearchCriteriaTypeEnum.DATERANGE,
},
{
title: "Amount",
code: "amount",
type: SearchCriteriaTypeEnum.AMOUNT,
currency: "USD",
},
{
title: "Type",
code: "type",
type: SearchCriteriaTypeEnum.MULTISELECT,
filterOptions: [
{ label: "Invoice", value: "Invoice" },
{ label: "Bill", value: "Bill" },
] as FilterOption[],
},
];
this.data = [
{
name: "ZAK JAAI",
date: "11/06/2024",
amount: 100,
type: "Invoice",
},
{
name: "ZAK2 JAAI",
date: "20/06/2024",
amount: 200,
type: "Bill",
},
];
this.filteredData = [...this.data];
this.totalRecords = this.data.length;
}
onFilteredData(filteredData: any[]): void {
this.filteredData = filteredData;
this.totalRecords = filteredData.length;
}
onSearchData(searchCriteria: { [key: string]: any }): void {
console.log(searchCriteria);
}
}
```
- **title** (`string`): The title of the multi-search criteria panel.
- **criteria** (`SearchCriteria[]`): The search criteria configuration.
- **data** (`any[]`): The data to be filtered when the component is used in static mode.
- **mode** (`'static' | 'dynamic'`): The filtering mode.
- `'static'`: Filters the provided data directly inside the component.
- `'dynamic'`: Emits the search criteria so that the parent component or backend can handle filtering.
- **filteredData** (`EventEmitter<any[]>`): Emitted with the filtered data in static mode.
- **searchCriteria** (`EventEmitter<{ [key: string]: any }>`): Emitted with the search criteria in dynamic mode.
```typescript
import { Component, OnInit } from "@angular/core";
import { CommonModule } from "@angular/common";
import { MultiSearchCriteriaModule, SearchCriteria, SearchCriteriaTypeEnum, FilterOption, PTAdvancedPrimeTableModule, TableColumn, TableTypeEnum } from "ng-prime-tools";
@Component({
selector: "app-root",
standalone: true,
imports: [CommonModule, MultiSearchCriteriaModule, PTAdvancedPrimeTableModule],
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
export class AppComponent implements OnInit {
criteria: SearchCriteria[] = [];
columns: TableColumn[] = [];
data: any[] = [];
filteredData: any[] = [];
totalRecords = 0;
ngOnInit(): void {
this.criteria = [
{
title: "Name",
code: "name",
type: SearchCriteriaTypeEnum.STRING,
},
{
title: "Date Range",
code: "dateRange",
type: SearchCriteriaTypeEnum.DATERANGE,
},
{
title: "Amount",
code: "amount",
type: SearchCriteriaTypeEnum.AMOUNT,
currency: "USD",
},
{
title: "Type",
code: "type",
type: SearchCriteriaTypeEnum.MULTISELECT,
filterOptions: [
{ label: "Invoice", value: "Invoice" },
{ label: "Bill", value: "Bill" },
] as FilterOption[],
},
];
this.columns = [
{
title: "Name",
code: "name",
type: TableTypeEnum.STRING,
},
{
title: "Amount",
code: "amount",
type: TableTypeEnum.AMOUNT,
currency: "USD",
},
{
title: "Type",
code: "type",
type: TableTypeEnum.STRING,
},
];
this.data = [
{
name: "ZAK JAAI",
date: "11/06/2024",
amount: 100,
type: "Invoice",
},
{
name: "ZAK2 JAAI",
date: "20/06/2024",
amount: 200,
type: "Bill",
},
];
this.filteredData = [...this.data];
this.totalRecords = this.data.length;
}
onFilteredData(filteredData: any[]): void {
this.filteredData = filteredData;
this.totalRecords = filteredData.length;
}
onSearchData(searchCriteria: { [key: string]: any }): void {
console.log(searchCriteria);
}
}
```
```html
<multi-search-criteria [title]="'Multi-Criteria Search'" [criteria]="criteria" [data]="data" [mode]="'dynamic'" (filteredData)="onFilteredData($event)" (searchCriteria)="onSearchData($event)"></multi-search-criteria>
<pt-advanced-prime-table [columns]="columns" [data]="filteredData" [hasSearchFilter]="true" [hasColumnFilter]="true" [isPaginated]="true" [totalRecords]="totalRecords" [isSortable]="true"></pt-advanced-prime-table>
```
The `FormBuilder` component is a powerful and flexible tool for dynamically generating forms with various input types. It allows you to create nested groups, manage validations, and customize the appearance and behavior of your forms.
The `FormBuilder` leverages several input components to build comprehensive forms:
- **`pt-check-box-input`**: A customizable checkbox input component.
- **`pt-date-input`**: A date input component based on PrimeNG DatePicker.
- **`pt-dropdown`**: A select input component based on PrimeNG Select.
- **`pt-form-builder`**: The form builder component that dynamically renders form fields.
- **`pt-multi-select`**: A multi-select dropdown component for selecting multiple values from a list.
- **`pt-number-input`**: A numeric input component with support for validation and formatting.
- **`pt-switch-input`**: A toggle switch input component based on PrimeNG ToggleSwitch.
- **`pt-text-area-input`**: A text area input component based on PrimeNG Textarea.
- **`pt-text-input`**: A standard text input component with support for icons, placeholders, and validation.
During the Angular 21 / PrimeNG 21 migration, the following PrimeNG components were replaced:
| Old PrimeNG API | New PrimeNG API |
| ---------------------------------------- | --------------------------------------- |
| `InputSwitchModule` / `p-inputSwitch` | `ToggleSwitchModule` / `p-toggleswitch` |
| `CalendarModule` / `p-calendar` | `DatePickerModule` / `p-datepicker` |
| `DropdownModule` / `p-dropdown` | `SelectModule` / `p-select` |
| `InputTextareaModule` / `pInputTextarea` | `TextareaModule` / `pTextarea` |
Below is an example of how to use the `FormBuilder` component to create a user registration form with various input fields:
```typescript
import { Component, OnInit } from "@angular/core";
import { CommonModule } from "@angular/common";
import { ReactiveFormsModule } from "@angular/forms";
import { ButtonColorEnum, FormButton, FormCheckBoxField, FormDateField, FormDropdownField, FormFieldGroup, FormInputTypeEnum, FormMultiSelectField, FormNumberField, FormSwitchField, FormTextAreaField, FormTextField, InputValidationEnum, PTFormBuilderModule } from "ng-prime-tools";
@Component({
selector: "app-form-builder-tester",
standalone: true,
imports: [CommonModule, ReactiveFormsModule, PTFormBuilderModule],
templateUrl: "./form-builder-tester.component.html",
styleUrls: ["./form-builder-tester.component.css"],
})
export class FormBuilderTesterComponent implements OnInit {
mainGroup: FormFieldGroup = { fields: [], groups: [] };
buttons: FormButton[] = [];
ngOnInit(): void {
this.initializeSettings();
}
initializeSettings(): void {
this.initializeMainGroup();
this.initializeButtons();
}
initializeMainGroup(): void {
this.mainGroup = {
groups: [this.createNameGroup(), this.createSubscriptionGroup(), this.createAgeGroup(), this.createBirthdateGroup(), this.createDateRangeGroup(), this.createAmountGroup(), this.createCountryGroup(), this.createHobbiesGroup(), this.createDescriptionGroup()],
};
}
createNameGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.TEXT,
label: "First Name",
name: "firstName",
required: true,
placeholder: "Enter your first name",
iconClass: "pi pi-user",
iconPosition: "left",
minLength: 3,
maxLength: 10,
inputValidation: InputValidationEnum.ONLY_LETTERS,
} as FormTextField,
{
type: FormInputTypeEnum.TEXT,
label: "Last Name",
name: "lastName",
required: true,
placeholder: "Enter your last name",
} as FormTextField,
],
};
}
createSubscriptionGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.CHECKBOX,
label: "Subscribe",
name: "subscribe",
required: true,
} as FormCheckBoxField,
{
type: FormInputTypeEnum.SWITCH,
label: "Active",
name: "active",
required: true,
} as FormSwitchField,
],
};
}
createAgeGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.NUMBER,
label: "Age",
name: "age",
minValue: "18",
maxValue: "40",
required: true,
errorText: "Age is required",
placeholder: "Enter your age",
} as FormNumberField,
],
};
}
createBirthdateGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.DATE,
label: "Birthdate",
name: "birthdate",
required: true,
dateFormat: "dd/mm/yy",
hourFormat: "24",
placeholder: "Select your birthdate",
dateInputType: "date",
} as FormDateField,
],
};
}
createDateRangeGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.DATE,
label: "Date Range",
name: "daterange",
required: true,
placeholder: "Select date range",
dateInputType: "range",
} as FormDateField,
],
};
}
createAmountGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.AMOUNT,
label: "Amount",
name: "amount",
minValue: "100",
maxValue: "1000",
required: true,
currency: "MAD",
iconPosition: "right",
placeholder: "Enter the amount",
decimalDigits: 3,
numberFormat: "fr-FR",
disabled: true,
} as FormNumberField,
],
};
}
createCountryGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.SELECT,
label: "Country",
name: "country",
options: [
{ label: "USA", value: "usa" },
{ label: "Canada", value: "canada" },
],
required: true,
placeholder: "Select your country",
} as FormDropdownField,
],
};
}
createHobbiesGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.MULTISELECT,
label: "Hobbies",
name: "hobbies",
options: [
{ label: "Reading", value: "reading" },
{ label: "Travelling", value: "travelling" },
{ label: "Cooking", value: "cooking" },
],
required: true,
placeholder: "Select your hobbies",
} as FormMultiSelectField,
],
};
}
createDescriptionGroup(): FormFieldGroup {
return {
fields: [
{
type: FormInputTypeEnum.TEXTAREA,
label: "Description",
name: "description",
rows: 5,
required: true,
errorText: "Description est obligatoire !",
placeholder: "Enter a description",
minLength: 10,
maxLength: 20,
iconClass: "pi pi-dollar",
iconPosition: "right",
disabled: true,
} as FormTextAreaField,
],
};
}
initializeButtons(): void {
this.buttons = [
{
text: "Custom Action",
action: this.customAction,
color: ButtonColorEnum.SUCCESS,
icon: "pi pi-check",
},
{
text: "Submit",
color: ButtonColorEnum.PRIMARY,
isSubmit: true,
},
{
text: "Clear",
color: ButtonColorEnum.SECONDARY,
isClear: true,
},
];
}
customAction(): void {
console.log("Custom action executed");
}
onFormSubmit(formData: { [key: string]: any }): void {
console.log("Form submitted with data:", formData);
}
}
```
- Migrated the library to **Angular 21**.
- Migrated PrimeNG dependencies to **PrimeNG 21**.
- Updated the library peer dependencies for Angular 21, PrimeNG 21, RxJS 7, and TypeScript 5.9.
- Replaced deprecated PrimeNG components:
- `InputSwitchModule` / `p-inputSwitch` → `ToggleSwitchModule` / `p-toggleswitch`
- `CalendarModule` / `p-calendar` → `DatePickerModule` / `p-datepicker`
- `DropdownModule` / `p-dropdown` → `SelectModule` / `p-select`
- `InputTextareaModule` / `pInputTextarea` → `TextareaModule` / `pTextarea`
- Updated PrimeNG theme configuration to use `@primeng/themes` and `providePrimeNG`.
- Removed old PrimeNG CSS resource imports:
- `primeng/resources/themes/...`
- `primeng/resources/primeng.min.css`
- Updated severity handling to support PrimeNG 21 severity values, including `warn` instead of the old `warning` value.
- Updated Angular templates progressively to support the latest Angular syntax and PrimeNG 21 compatibility.
- Removed obsolete Angular tooling such as TSLint, Codelyzer, and Protractor from the migration target.
- pt-advanced-table: Fixing the filters with asynchronous data and composed types.
- fixing the disabling btn in pt-login
- Changing style of pt-button when disabled
- adding pt-notifier
- fixing pt-confirm-dialog with ameliorations
- fixing pt-confirm-dialog with ameliorations
- adding pt-chart-comparison
- adding pt-group
- adding pt-metric-panel
- fix NUMBER type in advanced table
- adding styles for composed types in advanced table
- fix composed types in advanced table
- fixing error message in login page
- fixing scroll bar pt-card
- fixing search in sidebar position
- pt-card: adding background color transparency and pattern image transparency
- Adding positions for login page
- fix bug z-index fancy menu
- adding pt-line-chart
- fix metric-card `fixedWidth` param
- adding design for icons in metric cards
- fix issue having multiple charts using pt-chart
- fix menu z-index
- adding parametrable toggle
- adding position param for background image in pt-card
- remove background transparency for pt-card
- fix background transparency for pt-card
- fix column width for advanced table
- **New Components:**
- **`pt-bar`**: Introduced a new bar component to visually represent progress or metrics in a horizontal bar layout.
- **`pt-text-input`**: Added a customizable text input component to handle various form input needs with validation and error handling.
- **`pt-page-skeleton`**: Introduced a page skeleton component for loading states, offering a clean UI while data is being fetched.
- **`pt-footer`**: A new footer component providing a customizable and responsive footer layout for pages.
- **`pt-menu-fancy`**: Added a new fancy menu component for stylish navigation menus with enhanced layout options.
- **`pt-button`**: Introduced a highly customizable button component with various styles, icons, and action support.
- **`pt-confirm-dialog`**: Added a flexible dialog component for modal-based interactions, supporting customizable content, actions, and layout.
- **Enhancements to `pt-advanced-prime-table`:**
- **Dynamic Column Width:** Enhanced the table to support dynamic column width adjustments based on content.
- **Customizable Sticky Headers:** Improved sticky header behavior for tables with large datasets.
- **Improved Icon Handling:** Optimized column and icon width calculations.
- **Cell Alignment Fixes:** Resolved issues with header and body cell misalignment when header content wraps.
- **`pt-advanced-prime-table`:**
- **Loading Indicator:** Added loading spinner functionality.
- **Vertical Scrolling:** Enabled vertical scrolling for large datasets.
- **Empty Record Message:** Introduced a customizable empty-state message.
- **`pt-metric-card-group` & `pt-metric-card`**: Introduced metric card components for KPI display.
- **`pt-chart`**: Added chart component support for line, bar, doughnut, pie, and other chart types.
- **`pt-card`**: Introduced a configurable card component.
- **`pt-menu`**: Added a menu component for cards and actions.
- Fix bug on size of buttons exports.
- Adding export to PDF and Excel buttons in the `pt-advanced-prime-table`.
```html
<pt-advanced-prime-table [hasExportExcel]="true" [hasExportPDF]="true" (exportExcelEvent)="onExportExcel()" (exportPdfEvent)="onExportPDF()"></pt-advanced-prime-table>
```
- **FormBuilder Component:** Introduced a flexible `FormBuilder` component for dynamically creating forms with various input types.
- **New Input Components:**
- **`pt-check-box-input`**: A customizable checkbox input component.
- **`pt-date-input`**: A date input component supporting single date and range selections.
- **`pt-dropdown`**: A select input component for choosing a single option.
- **`pt-multi-select`**: A multi-select component for choosing multiple values.
- **`pt-number-input`**: A numeric input component with validation and formatting support.
- **`pt-switch-input`**: A toggle switch input component.
- **`pt-text-area-input`**: A multi-line text area input component.
- **`pt-text-input`**: A standard text input component.
- **`multi-search-criteria` Component**
- Added support for `mode` input to handle dynamic and static filtering.
- Fixed the bug in the `selectAll` functionality for multi-select filters.
- **`pt-advanced-prime-table` Component**
- Added support for customizable amount formatting.
- New inputs for columns of type `AMOUNT`:
- `thousandSeparator` (`comma` or `space`)
- `decimalSeparator` (`comma` or `dot`)
- Updated the `customCurrency` pipe to handle optional currency display and customizable separators.
- Added `multi-search-criteria` component.
- Initial release with `pt-advanced-prime-table` component.
This project is licensed under the MIT License.