npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dynamic-components-angular

v1.2.4

Published

Reusable configuration-driven PrimeNG dialog forms and localized inputs for Angular

Readme

dynamic-components-angular

npm version downloads downloads downloads license

Configuration-driven Angular 18 dialog forms for Nawras / Saned HR apps. Build add/edit dialogs from a field array—no duplicated p-dialog templates, validators, or PrimeNG wiring.

Peer stack: Angular 18, PrimeNG 17, @ngx-translate/core. Includes app-lookup-select (no nawras-library peer).


Install

npm install dynamic-components-angular

It gives you

  • <app-dynamic-dialog-form> — PrimeNG dialog + reactive FormGroup built from GenericFormField[]
  • <lib-localized-inputs> — multi-language name fields (Arabic, etc.) from your System Language API
  • GenericFormField — one strongly typed config object per field (text, dropdown, lookup, radio, checkbox, textarea, file, date, localized)
  • Edit / create flowseditMode, editData patching, save / update outputs, workflow lock when updateWorkflowStatus === 'Submitted'
  • Validation — required rules per type, red asterisk on labels, translated “Required” message
  • Lazy-friendly — use with @if (visible) in parent templates

Quick start

1. App module — language API

import { LOCALIZED_LANGUAGE_ENDPOINT } from 'dynamic-components-angular';
import { getBaseUrl } from './environments/environment';

providers: [
  {
    provide: LOCALIZED_LANGUAGE_ENDPOINT,
    useFactory: () =>
      getBaseUrl() + '/api/0/SharedData/SystemLanguage/v1/all',
  },
]

Optional — bind app LanguageService on the parent component:

import { LanguageService } from 'dynamic-components-angular';
import { LanguageService as AppLanguageService } from './shared/localized-inputs/language.service';

providers: [{ provide: LanguageService, useExisting: AppLanguageService }]

2. Standalone parent component

Template (new-department.component.html):

@if (visible) {
  <app-dynamic-dialog-form
    [visible]="visible"
    (visibleChange)="visible = $event"
    [editMode]="editMode"
    [editData]="editData"
    [fields]="fields"
    [customFieldsConfig]="customFieldsConfig"
    dialogTitle="Department"
    dialogWidth="50vw"
    (save)="onSave($event)"
    (update)="onUpdate($event)"
    (closeDialog)="visible = false"
  />
}

Component (new-department.component.ts):

import {
  DynamicDialogFormComponent,
  GenericFormField,
  GenericFormValue,
  GenericFormCustomFieldsConfig,
} from 'dynamic-components-angular';

@Component({
  standalone: true,
  imports: [DynamicDialogFormComponent],
  templateUrl: './new-department.component.html',
})
export class NewDepartmentComponent {
  visible = false;
  editMode = false;
  editData = null;

  customFieldsConfig = {
    labelPrefix: 'DepartmentName',
    columnClass: 'col-12 md:col-4',
    excludeLangNames: ['English'],
    placeholder: 'Enter name in',
  };

  fields = [
    { name: 'code', label: 'DepartmentCode', type: 'text', required: true },
    { name: 'name', label: 'DepartmentName', type: 'text', required: true },
    { name: 'description', label: 'SecondDescription', type: 'textarea', required: true, rows: 3 },
  ];

  onSave(value) { /* API create */ }
  onUpdate(value) { /* API update */ }
}

npm readme tip: Examples use html / js / json fences so code stays readable in npm dark mode. Avoid large typescript blocks with inline templates.


Supported field types

| type | Control | Notes | |--------|---------|--------| | text | pInputText | numericOnly, placeholder | | number | pInputText | Same as text with number input mode | | dropdown | p-dropdown | options, optionLabel, optionValue, filter/clear | | date | p-calendar | dateFormat, showTime | | lookup | app-lookup-select | Server-side lookup API; see lookup config below | | radio | p-radioButton | options, radioLayout | | checkbox | p-checkbox | binary (default true), checkboxLabel | | textarea | pInputTextarea | rows, autoResize | | file | p-fileUpload (basic) | accept, multiple, maxFileSize; value is File or File[] | | localized | via customFieldsConfig | Multi-language map on customFields control |


GenericFormField properties

Each item in [fields] is a GenericFormField (alias: DynamicDialogFormFieldConfig).

| Property | Type | Used for | |----------|------|----------| | name | string | Form control name | | label | string | Label (translate key) | | type | GenericFormFieldType | Field renderer | | required | boolean | Validation + red * | | columnClass | string | PrimeFlex column, e.g. col-12 md:col-4 | | placeholder | string | Input placeholder | | disabled | boolean | Disable control | | defaultValue | unknown | Create-mode default | | editKey | string | Patch from editData[editKey] | | numericOnly | boolean | Text/number: digits only | | options | array | Dropdown / radio options | | optionLabel / optionValue | string | Option binding keys | | filter, showClear, filterBy | — | Dropdown filter | | entity, module, version | string | Lookup API | | lookupType | string | id-name | text | id | name | | appendTo, styleClass | string | Lookup UI | | sReadOnly, getAll | boolean | Lookup behaviour | | functionName, query | — | Custom lookup endpoint | | selectFirstOnLoad, searchDebounce | — | Lookup load/search | | radioLayout | string | horizontal | vertical | | binary, checkboxLabel | — | Checkbox | | rows, autoResize | — | Textarea | | accept, multiple, maxFileSize, chooseLabel | — | File upload | | dateFormat, showTime | — | Calendar |


Example configurations

Text

{
  "name": "code",
  "label": "DepartmentCode",
  "type": "text",
  "required": true,
  "numericOnly": true,
  "columnClass": "col-12 md:col-4",
  "placeholder": "Enter code"
}

Dropdown

{
  "name": "divisionId",
  "label": "Parent Division",
  "type": "dropdown",
  "columnClass": "col-12 md:col-4",
  "optionLabel": "label",
  "optionValue": "value",
  "filter": true,
  "showClear": true,
  "filterBy": "label"
}

Lookup (app-lookup-select)

{
  "name": "managerId",
  "label": "DepartmentManager",
  "type": "lookup",
  "required": true,
  "columnClass": "col-12 md:col-4",
  "entity": "Employees",
  "module": "SanedHR",
  "version": "v1",
  "lookupType": "id-name",
  "optionLabel": "text",
  "optionValue": "id",
  "appendTo": "body",
  "placeholder": "Select manager",
  "sReadOnly": false,
  "getAll": false,
  "query": {},
  "selectFirstOnLoad": false,
  "searchDebounce": 400
}

Radio

{
  "name": "status",
  "label": "Status",
  "type": "radio",
  "required": true,
  "radioLayout": "horizontal",
  "optionLabel": "label",
  "optionValue": "value",
  "options": [
    { "label": "Active", "value": "active" },
    { "label": "Inactive", "value": "inactive" }
  ]
}

Checkbox

{
  "name": "isPrimary",
  "label": "PrimaryDepartment",
  "type": "checkbox",
  "binary": true,
  "checkboxLabel": "Mark as primary",
  "defaultValue": false,
  "columnClass": "col-12 md:col-4"
}

Textarea

{
  "name": "description",
  "label": "SecondDescription",
  "type": "textarea",
  "required": true,
  "rows": 4,
  "autoResize": true,
  "columnClass": "col-12"
}

File upload

{
  "name": "attachment",
  "label": "Attachment",
  "type": "file",
  "accept": ".pdf,.doc,.docx",
  "multiple": false,
  "maxFileSize": 5000000,
  "chooseLabel": "Choose file",
  "columnClass": "col-12 md:col-6"
}

On submit, form.getRawValue() includes attachment as a File (or File[] when multiple: true).


app-dynamic-dialog-form API

Inputs

| Input | Description | |-------|-------------| | visible | Show/hide dialog (two-way with visibleChange) | | editMode | false = Save, true = Update | | editData | Row object to patch in edit mode | | fields | GenericFormField[] | | dialogTitle | Header title (translate key) | | dialogWidth | CSS width, e.g. '50vw' | | customFieldsConfig | Localized inputs block (lib-localized-inputs) | | newRecordDefaults | Default values when creating | | updateWorkflowStatus | 'Submitted' disables the form |

Outputs

| Output | Description | |--------|-------------| | save | Emits form value on create | | update | Emits form value on edit | | closeDialog | User closed dialog | | visibleChange | Dialog visibility changed |


Public exports

DynamicDialogFormComponent
DynamicDialogFormModule
GenericFormField
GenericFormFieldType
GenericFormValue
GenericFormCustomFieldsConfig
GENERIC_FORM_FIELD_EXAMPLES
SAMPLE_GENERIC_FORM_FIELDS
LocalizedInputsModule
LocalizedInputsComponent
LanguageService
LOCALIZED_LANGUAGE_ENDPOINT

Import from package name: dynamic-components-angular


Peer dependencies

| Package | Purpose | |---------|---------| | @angular/core ^18.2 | Framework | | @angular/forms ^18.2 | Reactive forms | | primeng 17.18 | Dialog, inputs, file upload, etc. | | @ngx-translate/core ^15 | Labels and validation messages | | rxjs ~7.8 | — |

Host apps must provide HttpClientModule (or provideHttpClient()) so lookups can call your Nawras API. Lookup URLs follow the same tenant/subdomain rules as nawras-library.


For maintainers

Build and pack from this workspace root:

npm run release-dynamic-components

Publish to npm (after npm login):

npm run publish-dynamic-components

Do not run npm publish dist/dynamic-components — npm may treat that path as a git URL.

Local .tgz install:

"dynamic-components-angular": "file:dynamic-components-angular-1.1.6.tgz"

License

UNLICENSED — internal / Obeikan Nawras use unless otherwise specified.