ngx-form-designer
v0.0.8
Published
A visual Form Designer for Angular applications, featuring a drag-and-drop interface, responsive layout management, and an enterprise-grade rules engine.
Readme
NgxFormDesigner
A visual Form Designer for Angular applications, featuring a drag-and-drop interface, responsive layout management, and an enterprise-grade rules engine.
Features
- Drag & Drop: Intuitive canvas for arranging widgets.
- Responsive Layout: Row/Column system with breakpoint support.
- Rules Engine: Conditional logic (show/hide, validation, disabling) based on field values.
- JSON Schema: Export/Import forms as simple JSON.
- Modern UI: Built with Tailwind CSS and lucide-angular icons.
Documentation
Full beginner-friendly docs live in projects/ngx-form-designer/docs/README.md:
projects/ngx-form-designer/docs/GETTING_STARTED.mdprojects/ngx-form-designer/docs/PUBLIC_API.mdprojects/ngx-form-designer/docs/ARCHITECTURE.mdprojects/ngx-form-designer/docs/SCHEMA_REFERENCE.mdprojects/ngx-form-designer/docs/WIDGETS.mdprojects/ngx-form-designer/docs/PLUGINS.mdprojects/ngx-form-designer/docs/DATA_SOURCES.md
Installation
npm install ngx-form-designerDependencies
This library relies on Tailwind CSS and lucide-angular for UI styling and iconography.
Tailwind CSS: The library uses Tailwind utility classes.
Option A: Using the Preset (Recommended) In your
tailwind.config.js(or similar), add the preset:module.exports = { presets: [ require('ngx-form-designer/tailwind.preset.js') ], content: [ "./src/**/*.{html,ts}", "./node_modules/ngx-form-designer/**/*.{html,ts,mjs}" ], }Option B: Manual Configuration If you prefer to manually copy the theme tokens, see
projects/ngx-form-designer/docs/STYLING_AND_THEME.md.
Design tokens (recommended): The demo/theme uses Tailwind tokens like accent-*, ink-*, slate-*, shadow-card, and shadow-popover. If your app doesn’t define them, the UI will still work but can look different. See projects/ngx-form-designer/docs/STYLING_AND_THEME.md.
- lucide-angular: Install and configure lucide-angular icons:
npm install lucide-angularIn your app.config.ts, import and provide the icons you need:
import { LucideAngularModule, icons } from 'lucide-angular';
export const appConfig: ApplicationConfig = {
providers: [
// ... other providers
importProvidersFrom(LucideAngularModule.pick(icons))
]
};Usage
Import JsonFormDesignerComponent (standalone) into your component or route.
import { Component } from '@angular/core';
import { JsonFormDesignerComponent } from 'ngx-form-designer';
@Component({
standalone: true,
imports: [JsonFormDesignerComponent],
template: `<app-json-form-designer></app-json-form-designer>`
})
export class MyComponent {}If you want the full scaffolded UI (top bar + template library) with minimal setup, use the shell component:
import { Component } from '@angular/core';
import { FormDesignerShellComponent } from 'ngx-form-designer';
@Component({
standalone: true,
imports: [FormDesignerShellComponent],
template: `<app-form-designer-shell></app-form-designer-shell>`
})
export class MyDesignerPage {}Provider setup (required)
Widgets are registered via plugins. The simplest setup is to register the built-in plugin pack:
import { ApplicationConfig } from '@angular/core';
import { CORE_DESIGNER_PLUGINS, provideDesignerPlugins } from 'ngx-form-designer';
export const appConfig: ApplicationConfig = {
providers: [
...provideDesignerPlugins(CORE_DESIGNER_PLUGINS),
]
};Without this, the palette will be empty and the renderer can’t resolve widgets.
Publishing
Build the library:
ng build ngx-form-designerPublish from dist:
cd dist/ngx-form-designer
npm publishData Sources (API-only)
The library uses a "Data Sources over APIs" architecture. This means widgets do not store large datasets (like CSVs or JSON arrays) directly in the form schema. Instead, they reference a sourceId and delegate data fetching to a registered DataProvider.
Full guide: projects/ngx-form-designer/docs/DATA_SOURCES.md.
Concepts
- Source ID: A stable string identifier (e.g.,
countries,users,products) representing a dataset. - DataProvider Pipeline: Widgets request data via the
DataProviderservice.DataProviderdelegates toDataSourceClient.DataSourceClientis an abstraction you implement (or use the default) to fetch data.
- Designer & Runtime Consistency: The Form Designer uses the exact same pipeline to render "Live Previews" of data in the configuration panel.
Backend API Contract
If you use the HTTP-based DataSourceClient, your backend should implement these endpoints:
| Method | Endpoint | Description |
| :--- | :--- | :--- |
| GET | /data-sources | List available data sources (id, label) |
| GET | /data-sources/{sourceId} | Get details for a specific source |
| GET | /data-sources/{sourceId}/columns | Get column definitions (name, type) |
| POST | /data-sources/{sourceId}/query | query rows with filtering/sorting/paging |
Query Payload Example:
{
"page": { "limit": 50, "offset": 0 },
"search": { "term": "foo", "columns": ["name"] },
"filters": [
{ "column": "category", "op": "eq", "value": "active" }
],
"sort": [ { "column": "name", "dir": "asc" } ]
}Host App Setup
1. In-Memory / Mock Setup
Use this for rapid prototyping or testing without a real backend.
import { DataCatalog, InMemoryDataCatalogService } from 'ngx-form-designer';
// in app.config.ts
providers: [
{ provide: DataCatalog, useExisting: InMemoryDataCatalogService }
]2. HTTP Backend Setup
Use this to connect to your real API.
import { provideHttpDataSourceClient } from 'ngx-form-designer';
// in app.config.ts
providers: [
provideHttpDataSourceClient({
baseUrl: 'https://api.example.com',
getHeaders: () => ({ Authorization: 'Bearer ' + myAuthService.getToken() })
})
]Configuration Examples
Basic Dropdown (Select)
Fetches data from countries source, uses name as label and isoCode as value.
{
"type": "select",
"dataConfig": {
"type": "source",
"sourceId": "countries",
"labelKey": "name",
"valueKey": "isoCode"
}
}Search-Enabled Dropdown
Enables server-side search to handle large datasets.
{
"type": "select",
"dataConfig": {
"type": "source",
"sourceId": "products",
"labelKey": "productName",
"valueKey": "id",
"searchEnabled": true,
"optionsLimit": 20,
"searchColumns": ["productName", "sku"]
}
}Tree Select (Hierarchical)
Expects a flat list of nodes where each node has an ID and a Parent ID.
{
"type": "tree-select",
"dataConfig": {
"type": "source",
"sourceId": "departments",
"labelKey": "title",
"valueKey": "id",
"treeIdKey": "id",
"treeParentKey": "parentId"
}
}Data Table
Paged table view with server-side sorting.
{
"type": "table",
"dataConfig": {
"type": "source",
"sourceId": "orders",
"pageSize": 10,
"sort": [{ "column": "createdAt", "dir": "desc" }]
},
"columns": [
{ "key": "id", "label": "Order ID" },
{ "key": "total", "label": "Amount" },
{ "key": "status", "label": "Status" }
]
}