UI Libraries Integration PrimeNG

PrimeNG

Beautiful PrimeNG field components for ng-forge dynamic forms, built with the PrimeNG design system.


Installation

Install the package and its peer dependencies:

npm
yarn
pnpm
npm install @ng-forge/dynamic-forms @ng-forge/dynamic-forms-primeng primeng primeicons

Quick Start

1. Configure Providers

Add PrimeNG field types to your application:

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideDynamicForm } from '@ng-forge/dynamic-forms';
import { withPrimeNGFields } from '@ng-forge/dynamic-forms-primeng';
import { providePrimeNG } from 'primeng/config';
import Aura from '@primeuix/themes/aura';

export const appConfig: ApplicationConfig = {
  providers: [
    provideDynamicForm(...withPrimeNGFields()),
    providePrimeNG({
      theme: {
        preset: Aura,
      },
    }),
  ],
};

2. Import Theme & Styles

Add PrimeNG icons to your styles:

styles.scss
@import 'primeicons/primeicons.css';

PrimeNG theming is now configured via the provider (see step 1). You can customize the theme preset:

import Aura from '@primeuix/themes/aura';
import Lara from '@primeuix/themes/lara';
import Nora from '@primeuix/themes/nora';

providePrimeNG({
  theme: {
    preset: Aura, // or Lara, Nora, etc.
  },
});

3. Create Your First Form

import { Component, signal } from '@angular/core';
import { JsonPipe } from '@angular/common';
import { DynamicForm, type FormConfig } from '@ng-forge/dynamic-forms';

@Component({
  selector: 'app-contact-form',
  imports: [DynamicForm, JsonPipe],
  template: `
    <form [dynamic-form]="config" [(value)]="formValue"></form>
    @let value = formValue();
    <pre>{{ value | json }}</pre>
  `,
})
export class ContactFormComponent {
  formValue = signal({});

  config = {
    fields: [
      {
        key: 'name',
        type: 'input',
        value: '',
        label: 'Full Name',
        required: true,
        props: {
          variant: 'outlined',
        },
      },
      {
        key: 'email',
        type: 'input',
        value: '',
        label: 'Email',
        required: true,
        email: true,
        props: {
          type: 'email',
          variant: 'outlined',
        },
      },
      {
        key: 'message',
        type: 'textarea',
        value: '',
        label: 'Message',
        required: true,
        minLength: 10,
        props: {
          rows: 4,
        },
      },
      {
        type: 'submit',
        key: 'submit',
        label: 'Send Message',
        props: {
          severity: 'primary',
        },
      },
    ],
  } as const satisfies FormConfig;
}

Complete Form Example

Here's a full registration form showcasing multiple PrimeNG field types:

Loading example...

Click to view config! 🔧
{
  fields: [
    { key: 'firstName', type: 'input', label: 'First Name', required: true, minLength: 2,
      validationMessages: { required: 'This field is required', minLength: 'Must be at least {{requiredLength}} characters' },
      props: { placeholder: 'Enter your first name', variant: 'outlined' } },
    { key: 'lastName', type: 'input', label: 'Last Name', required: true, minLength: 2,
      validationMessages: { required: 'This field is required', minLength: 'Must be at least {{requiredLength}} characters' },
      props: { placeholder: 'Enter your last name', variant: 'outlined' } },
    { key: 'email', type: 'input', label: 'Email Address', required: true, email: true,
      validationMessages: { required: 'This field is required', email: 'Please enter a valid email address' },
      props: { type: 'email', placeholder: 'user@example.com', variant: 'outlined', hint: 'We will never share your email' } },
    { key: 'age', type: 'input', label: 'Age', required: true, min: 18, max: 120,
      validationMessages: { required: 'This field is required', min: 'Must be at least {{min}}', max: 'Must not exceed {{max}}' },
      props: { type: 'number', placeholder: '18', variant: 'outlined' } },
    { key: 'country', type: 'select', label: 'Country', required: true,
      validationMessages: { required: 'This field is required' },
      options: [
        { value: 'us', label: 'United States' }, { value: 'uk', label: 'United Kingdom' },
        { value: 'ca', label: 'Canada' }, { value: 'au', label: 'Australia' },
        { value: 'de', label: 'Germany' }, { value: 'fr', label: 'France' }, { value: 'jp', label: 'Japan' }
      ],
      props: { placeholder: 'Select your country', variant: 'outlined' } },
    { key: 'plan', type: 'select', label: 'Subscription Plan', required: true,
      validationMessages: { required: 'This field is required' },
      options: [
        { value: 'free', label: 'Free - $0/month' }, { value: 'pro', label: 'Pro - $10/month' },
        { value: 'enterprise', label: 'Enterprise - $50/month' }
      ],
      props: { placeholder: 'Choose a plan', variant: 'outlined' } },
    { key: 'bio', type: 'textarea', label: 'Bio',
      props: { placeholder: 'Tell us about yourself', variant: 'outlined', hint: 'Optional - share a bit about yourself' } },
    { key: 'newsletter', type: 'checkbox', label: 'Subscribe to newsletter' },
    { type: 'submit', key: 'submit', label: 'Create Account', props: { severity: 'success' } },
  ],
}

This example demonstrates:

  • Text inputs with validation
  • Select dropdowns with search
  • Checkboxes and toggles
  • Radio buttons
  • Date pickers
  • Sliders
  • Multi-checkbox selections
  • Form submission

Field Types Reference

Complete reference for all PrimeNG field types with comprehensive validation, accessibility features, and PrimeNG styling.

Text Input Fields

Text input fields provide user-friendly text entry with PrimeNG styling.

Input

Text input field with HTML5 type support and PrimeNG styling.

Live Demo:

Loading example...

Click to view config! 🔧
const config: FormConfig = {
  fields: [
    {
      key: 'email',
      type: 'input',
      value: '',
      label: 'Email Address',
      props: {
        type: 'email',
        styleClass: 'w-full',
        hint: 'Enter your email address',
      },
    },
    {
      type: 'submit',
      key: 'submit',
      label: 'Submit',
      props: {
        severity: 'primary',
      },
    },
  ],
};

Basic Usage:

{
  key: 'email',
  type: 'input',
  value: '',
  label: 'Email Address',
  required: true,
  email: true,
  props: {
    type: 'email',
    variant: 'outlined',
    placeholder: 'Enter your email',
    hint: 'We will never share your email',
  },
}

Field Properties:

PropertyTypeDescription
keystringUnique field identifier (required)
type'input'Field type (required)
valuestring | numberInitial value
labelstringField label
placeholderstringPlaceholder text
requiredbooleanMark field as required
disabledbooleanDisable the field
readonlybooleanMake field read-only

Validation Properties:

PropertyTypeDescription
emailbooleanEmail format validation
minLengthnumberMinimum character length
maxLengthnumberMaximum character length
minnumberMinimum value (for number inputs)
maxnumberMaximum value (for number inputs)
patternstring | RegExpRegEx pattern validation

Props (PrimeNG-Specific):

PropTypeDefaultDescription
type'text' | 'email' | 'password' | 'number' | 'tel' | 'url''text'HTML input type
variant'outlined' | 'filled''outlined'Visual style
size'small' | 'large'-Input size
hintstring-Helper text below input
styleClassstring-CSS class for input

Textarea

Multi-line text input field with PrimeNG styling and auto-resize support.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'bio',
  type: 'textarea',
  label: 'Biography',
  value: '',
  maxLength: 500,
  props: {
    rows: 6,
    autoResize: true,
    hint: 'Tell us about yourself',
  },
}

Basic Usage:

{
  key: 'bio',
  type: 'textarea',
  value: '',
  label: 'Biography',
  placeholder: 'Tell us about yourself',
  required: true,
  minLength: 50,
  maxLength: 500,
  props: {
    rows: 6,
    autoResize: true,
    hint: 'Maximum 500 characters',
  },
}

Props (PrimeNG-Specific):

PropTypeDefaultDescription
rowsnumber4Number of visible rows
autoResizebooleanfalseAuto-resize based on content
maxlengthnumber-Maximum character limit
hintstring-Help text below field
styleClassstring-CSS class for textarea

Selection Fields

Selection fields enable users to choose from predefined options.

Select

Dropdown selection field with search capability and virtual scrolling support.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'framework',
  type: 'select',
  label: 'Choose Framework',
  options: [
    { value: 'angular', label: 'Angular' },
    { value: 'react', label: 'React' },
    { value: 'vue', label: 'Vue.js' },
  ],
  props: {
    placeholder: 'Select a framework...',
    filter: true,  // Enable search
    showClear: true,  // Show clear button
  },
}

Basic Usage:

{
  key: 'country',
  type: 'select',
  value: '',
  label: 'Country',
  required: true,
  options: [
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'ca', label: 'Canada' },
    { value: 'au', label: 'Australia' },
  ],
  props: {
    filter: true,
    showClear: true,
    placeholder: 'Select a country',
  },
}

Props (PrimeNG-Specific):

PropTypeDefaultDescription
filterbooleanfalseEnable search/filter
showClearbooleanfalseShow clear button
multiplebooleanfalseEnable multiple selection
placeholderstring-Dropdown placeholder text
hintstring-Help text below select
styleClassstring-CSS class for dropdown

Radio

Radio button group for selecting a single option.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'subscriptionPlan',
  type: 'radio',
  label: 'Subscription Plan',
  options: [
    { value: 'free', label: 'Free' },
    { value: 'pro', label: 'Pro' },
    { value: 'enterprise', label: 'Enterprise' },
  ],
  props: {
    hint: 'Choose your plan',
  },
}

Basic Usage:

{
  key: 'size',
  type: 'radio',
  value: '',
  label: 'Select Size',
  required: true,
  options: [
    { value: 'small', label: 'Small' },
    { value: 'medium', label: 'Medium' },
    { value: 'large', label: 'Large' },
  ],
  props: {
    hint: 'Choose your preferred size',
  },
}

Props (PrimeNG-Specific):

PropTypeDefaultDescription
hintstring-Help text displayed below group
styleClassstring-CSS class for radio group

Checkbox

Boolean checkbox control for single true/false selections.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'newsletter',
  type: 'checkbox',
  label: 'Subscribe to newsletter',
  value: false,
  props: {
    hint: 'Get updates about new features',
  },
}

Basic Usage:

{
  key: 'terms',
  type: 'checkbox',
  value: false,
  label: 'I accept the terms and conditions',
  required: true,
  props: {
    binary: true,
  },
}

Props (PrimeNG-Specific):

PropTypeDefaultDescription
binarybooleantrueTreat as boolean (true/false)
trueValueanytrueValue when checked
falseValueanyfalseValue when unchecked
styleClassstring-CSS class for checkbox

Multi-Checkbox

Multiple checkbox selection field for choosing multiple options.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'interests',
  type: 'multi-checkbox',
  label: 'Interests',
  options: [
    { value: 'sports', label: 'Sports' },
    { value: 'music', label: 'Music' },
    { value: 'technology', label: 'Technology' },
    { value: 'art', label: 'Art' },
  ],
  props: {
    hint: 'Select all that apply',
  },
}

Basic Usage:

{
  key: 'interests',
  type: 'multi-checkbox',
  value: [],
  label: 'Select Your Interests',
  required: true,
  options: [
    { value: 'sports', label: 'Sports' },
    { value: 'music', label: 'Music' },
    { value: 'reading', label: 'Reading' },
    { value: 'travel', label: 'Travel' },
    { value: 'cooking', label: 'Cooking' },
  ],
  props: {
    hint: 'Select all that apply',
  },
}

Props (PrimeNG-Specific):

PropTypeDefaultDescription
hintstring-Help text displayed below group
styleClassstring-CSS class for checkbox group

Interactive Fields

Interactive fields provide advanced user input controls.

Toggle

Slide toggle switch (InputSwitch) for boolean on/off selections.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'darkMode',
  type: 'toggle',
  label: 'Dark Mode',
  value: false,
  props: {
    hint: 'Enable dark mode theme',
  },
}

Basic Usage:

{
  key: 'notifications',
  type: 'toggle',
  value: false,
  label: 'Enable email notifications',
  props: {
    hint: 'Receive updates via email',
  },
}

Props (PrimeNG-Specific):

PropTypeDefaultDescription
hintstring-Help text below toggle
styleClassstring-CSS class for toggle

Slider

Numeric slider control for selecting values from a range.

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'volume',
  type: 'slider',
  label: 'Volume',
  minValue: 0,
  maxValue: 100,
  step: 5,
  props: {
    hint: 'Adjust the volume level',
  },
}

Basic Usage:

{
  key: 'volume',
  type: 'slider',
  value: 50,
  label: 'Volume',
  minValue: 0,
  maxValue: 100,
  step: 5,
  props: {
    hint: 'Adjust audio volume',
  },
}

Field Properties:

PropertyTypeDefaultDescription
minValuenumber0Minimum value
maxValuenumber100Maximum value
stepnumber1Increment step

Props (PrimeNG-Specific):

PropTypeDefaultDescription
orientation'horizontal' | 'vertical''horizontal'Slider orientation
rangebooleanfalseEnable range mode (2 knobs)
hintstring-Help text below slider
styleClassstring-CSS class for slider

Datepicker

Date selection field with calendar popup (p-calendar).

Live Demo:

Loading example...

Click to view config! 🔧
{
  key: 'birthDate',
  type: 'datepicker',
  label: 'Birth Date',
  props: {
    showIcon: true,
    dateFormat: 'mm/dd/yy',
    hint: 'Select your birth date',
  },
}

Basic Usage:

{
  key: 'birthdate',
  type: 'datepicker',
  value: null,
  label: 'Date of Birth',
  required: true,
  minDate: new Date('1900-01-01'),
  maxDate: new Date(),
  props: {
    dateFormat: 'mm/dd/yy',
    showIcon: true,
    showButtonBar: true,
    hint: 'Select your birth date',
  },
}

Field Properties:

PropertyTypeDescription
minDateDate | string | nullMinimum selectable date
maxDateDate | string | nullMaximum selectable date

Props (PrimeNG-Specific):

PropTypeDefaultDescription
dateFormatstring'mm/dd/yy'Date format string
showIconbooleanfalseShow calendar icon
showButtonBarbooleanfalseShow today/clear buttons
inlinebooleanfalseDisplay calendar inline
selectionMode'single' | 'multiple' | 'range''single'Date selection mode
view'date' | 'month' | 'year''date'Initial calendar view
touchUIbooleanfalseTouch-optimized UI
hintstring-Help text below field
styleClassstring-CSS class for datepicker

Buttons & Actions

Action buttons provide form submission and navigation controls.

Submit Button

Form submission button that's automatically disabled when the form is invalid.

Live Demo:

Loading example...

Click to view config! 🔧
{
  type: 'submit',
  key: 'submit',
  label: 'Create Account',
  props: {
    severity: 'primary',
    icon: 'pi pi-check',
    iconPos: 'right',
  },
}

Basic Usage:

{
  type: 'submit',
  key: 'submit',
  label: 'Create Account',
  props: {
    severity: 'primary',
    icon: 'pi pi-check',
    iconPos: 'right',
  },
}

The submit button automatically:

  • Disables when the form is invalid
  • Emits a SubmitEvent when clicked
  • Validates all fields before submission

Props:

PropTypeDefaultDescription
severity'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'help' | 'danger' | 'contrast''primary'Button theme
outlinedbooleanfalseOutlined style
textbooleanfalseText-only style
raisedbooleanfalseRaised style
roundedbooleanfalseRounded style
iconstring-Icon class
iconPos'left' | 'right' | 'top' | 'bottom''left'Icon position

Navigation buttons for multi-step (paged) forms.

Basic Usage:

{
  fields: [
    {
      key: 'step1',
      type: 'page',
      fields: [
        { key: 'step1Title', type: 'text', label: 'Personal Information', props: { elementType: 'h3' } },
        { key: 'step1Desc', type: 'text', label: 'Tell us about yourself' },
        { key: 'firstName', type: 'input', value: '', label: 'First Name', required: true },
        { key: 'lastName', type: 'input', value: '', label: 'Last Name', required: true },
        {
          type: 'next',
          key: 'next',
          label: 'Continue',
          props: { severity: 'primary', icon: 'pi pi-arrow-right', iconPos: 'right' },
        },
      ],
    },
    {
      key: 'step2',
      type: 'page',
      fields: [
        { key: 'step2Title', type: 'text', label: 'Contact Information', props: { elementType: 'h3' } },
        { key: 'email', type: 'input', value: '', label: 'Email', required: true, email: true },
        { key: 'phone', type: 'input', value: '', label: 'Phone', props: { type: 'tel' } },
        {
          key: 'navigation',
          type: 'row',
          fields: [
            { type: 'previous', key: 'back', label: 'Back', props: { icon: 'pi pi-arrow-left' } },
            { type: 'submit', key: 'submit', label: 'Complete', props: { severity: 'primary' } },
          ],
        },
      ],
    },
  ],
}

Button Types:

  • Next Button: Navigates to the next page. Automatically disabled when current page has validation errors.
  • Previous Button: Navigates to the previous page. Always enabled to allow users to go back.

Custom Action Button

Generic button for custom events. Use this for application-specific actions.

Basic Usage:

import { FormEvent } from '@ng-forge/dynamic-forms';

// Define your custom event
class SaveDraftEvent implements FormEvent {
  readonly type = 'save-draft' as const;
}

const config = {
  fields: [
    { key: 'title', type: 'input', value: '', label: 'Document Title', required: true },
    { key: 'content', type: 'textarea', value: '', label: 'Content' },
    {
      key: 'actions',
      type: 'row',
      fields: [
        {
          type: 'button',
          key: 'saveDraft',
          label: 'Save as Draft',
          event: SaveDraftEvent,
          props: {
            severity: 'secondary',
            icon: 'pi pi-save',
          },
        },
        {
          type: 'submit',
          key: 'publish',
          label: 'Publish',
          props: {
            severity: 'primary',
            icon: 'pi pi-upload',
          },
        },
      ],
    },
  ],
} as const satisfies FormConfig;

Then listen for the event in your component:

import { EventBus } from '@ng-forge/dynamic-forms';

class MyComponent {
  private eventBus = inject(EventBus);

  ngOnInit() {
    this.eventBus.on<SaveDraftEvent>('SaveDraft').subscribe(() => {
      console.log('Save draft clicked', this.form.value);
      // Handle draft saving logic
    });
  }
}

Theming

PrimeNG supports extensive theming through CSS variables and theme presets. Customize your theme using the provider:

import { providePrimeNG } from 'primeng/config';
import Aura from '@primeuix/themes/aura';
import Lara from '@primeuix/themes/lara';
import Nora from '@primeuix/themes/nora';

providePrimeNG({
  theme: {
    preset: Aura, // or Lara, Nora, etc.
    options: {
      darkModeSelector: '.dark-mode',
    },
  },
});

Severity Colors

Control button and component colors using the severity prop:

{
  type: 'submit',
  key: 'submit',
  label: 'Submit',
  props: {
    severity: 'primary', // 'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'help' | 'danger' | 'contrast'
  },
}

Size Variants

Adjust component sizes using the size prop:

{
  key: 'email',
  type: 'input',
  label: 'Email',
  props: {
    size: 'small', // 'small' | 'large' | undefined (default/medium)
  },
}

Custom Styling

Add custom CSS classes to any component:

{
  key: 'email',
  type: 'input',
  label: 'Email',
  props: {
    styleClass: 'my-custom-input',
  },
}

For more information, see the PrimeNG Theming Guide .

Accessibility

All PrimeNG components include:

  • Proper ARIA attributes
  • Keyboard navigation support
  • Screen reader compatibility
  • Focus management
  • Error announcements

PrimeNG components are designed with accessibility in mind and follow WAI-ARIA standards.

Next Steps