@dinesh-kumar-sridharan/ui-renderer-angular
v1.0.0
Published
Angular adapter for the Universal UI Renderer — pass one schema, get complete Angular UI.
Downloads
18
Maintainers
Readme
@dinesh-kumar-sridharan/ui-renderer-angular
Angular 18 adapter for the schema-driven Universal UI Renderer.
Pass ONE JSON schema — get a complete, production-ready Angular component.
Author: Dinesh Kumar Sridharan — https://github.com/Dinesh-kumar-sridharan
Install
npm install @dinesh-kumar-sridharan/ui-renderer-angular
# peer deps (already present in any Angular 18 project)
npm install @angular/common @angular/core @angular/formsSetup
The adapter uses standalone components — no NgModule required. Import UIRendererComponent directly in any standalone component's imports array.
import { UIRendererComponent } from '@dinesh-kumar-sridharan/ui-renderer-angular'
@Component({
standalone: true,
imports: [UIRendererComponent],
template: `<ui-renderer [schema]="schema" (submitted)="onSubmit($event)" />`,
})
export class MyComponent { ... }Usage
Form
import type { UISchema } from '@dinesh-kumar-sridharan/ui-renderer-angular'
schema: UISchema = {
id: 'contact',
version: '1.0.0',
type: 'form',
title: 'Contact Us',
columns: 2,
fields: [
{ id: 'name', type: 'text', label: 'Name', required: true, colSpan: 1 },
{ id: 'email', type: 'email', label: 'Email', required: true, colSpan: 1 },
{ id: 'message', type: 'textarea', label: 'Message', colSpan: 2 },
],
}<ui-renderer [schema]="schema" (submitted)="onSubmit($event)" />Table
<ui-renderer [schema]="tableSchema" (rowClick)="onRowClick($event)" />Wizard (multi-step form)
<ui-renderer [schema]="wizardSchema" (submitted)="onSubmit($event)" />Detail, Dashboard, List
<ui-renderer [schema]="detailSchema" [data]="record" />
<ui-renderer [schema]="dashboardSchema" />
<ui-renderer [schema]="listSchema" (itemClick)="onItemClick($event)" />From raw JSON
<ui-renderer [schemaJson]="rawJsonString" (submitted)="onSubmit($event)" />Inputs & outputs
| Input / Output | Type | Description |
|----------------|------|-------------|
| [schema] | UISchema \| unknown | Parsed or plain schema object |
| [schemaJson] | string | Raw JSON string — parsed at render time |
| [data] | Record<string, unknown> | Pre-populate form / detail fields |
| [handlers] | Record<string, Function> | Named handler map referenced by schema actions |
| (submitted) | Record<string, unknown> | Emitted on form / wizard submit |
| (rowClick) | Record<string, unknown> | Emitted on table row click |
| (itemClick) | Record<string, unknown> | Emitted on list item click |
Signals-based state
The Angular adapter is built on Angular 18 signals throughout — no RxJS, no BehaviorSubject. Internal state in each renderer uses signal() and computed(), so change detection is fully OnPush-compatible.
// FormStateService — available for injection within the form renderer's providers scope
import { FormStateService } from '@dinesh-kumar-sridharan/ui-renderer-angular'
// state.values() → Record<string, unknown> (computed signal)
// state.errors() → Record<string, string> (computed signal)
// state.isValid() → boolean (computed signal)Conditional fields
Conditional visibility works the same across all adapters — driven by the schema, evaluated by the shared core engine:
fields: [
{
id: 'employmentType',
type: 'select',
label: 'Employment Type',
options: [
{ value: 'employed', label: 'Employed' },
{ value: 'student', label: 'Student' },
],
},
{
id: 'companyName',
type: 'text',
label: 'Company Name',
showWhen: [{ field: 'employmentType', operator: 'equals', value: 'employed' }],
},
]Plugin registration
import { pluginRegistry } from '@dinesh-kumar-sridharan/ui-renderer-angular'
import { SignaturePadComponent } from './signature-pad.component'
// Call once at app startup (e.g. in main.ts or an APP_INITIALIZER)
pluginRegistry.register('signature-pad', SignaturePadComponent)
// In schema:
// { id: 'sig', type: 'custom', plugin: 'signature-pad', label: 'Signature' }Custom plugin components must accept these Angular @Input parameters:
@Input() field!: FieldSchema
@Input() value: unknown = undefined
@Input() error?: string
@Output() valueChange = new EventEmitter<unknown>()Parse raw JSON manually
import { parseSchema, validateAIGeneratedSchema } from '@dinesh-kumar-sridharan/ui-renderer-angular'
const result = validateAIGeneratedSchema(rawJson)
if (result.valid) {
const schema = parseSchema(JSON.parse(rawJson))
// → bind to [schema] input
}Links
License
MIT © Dinesh Kumar Sridharan
