@mosaicoo/form-angular 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mosaicoo-form-angular.mjs","sources":["../../../packages/angular/src/lib/form-node.component.ts","../../../packages/angular/src/lib/form-renderer.component.ts","../../../packages/angular/src/mosaicoo-form-angular.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n effect,\n input,\n signal,\n untracked,\n} from '@angular/core';\nimport type {\n ContainerField,\n FieldNode,\n FieldOption,\n FormEngine,\n InputField,\n OptionsProviderRegistry,\n StaticField,\n} from '@mosaicoo/form-core';\n\n/**\n * Renders one schema node (input, container or static) and recurses into\n * children. State lives in the headless engine — this component only projects\n * it and forwards user interaction. `tick` changes whenever the engine emits,\n * invalidating the OnPush view.\n */\n@Component({\n selector: 'mform-node',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'mform-node' },\n template: `\n @let n = node();\n @if (visible()) {\n @switch (n.kind) {\n @case ('static') {\n @if (n.type === 'button') {\n <button\n class=\"mform-btn\"\n [type]=\"buttonAction() === 'submit' ? 'submit' : 'button'\"\n >\n {{ n.label || 'Submit' }}\n </button>\n } @else if (n.type === 'content') {\n <div class=\"mform-content\" [innerHTML]=\"content()\"></div>\n } @else {\n <div class=\"mform-unsupported\" role=\"note\">\n {{ n.label || n.key }} — unsupported content\n </div>\n }\n }\n @case ('container') {\n @switch (containerLayout()) {\n @case ('columns') {\n <div class=\"mform-columns\" [style.grid-template-columns]=\"columnsTemplate()\">\n @for (column of columns(); track $index) {\n <div class=\"mform-column\">\n @for (child of column; track child.key) {\n <mform-node [node]=\"child\" [engine]=\"engine()\" [tick]=\"tick()\" [providers]=\"providers()\" [scope]=\"childScope()\" />\n }\n </div>\n }\n </div>\n }\n @case ('tabs') {\n <div class=\"mform-tabs\">\n <div class=\"mform-tabbar\" role=\"tablist\">\n @for (tab of container().children; track tab.key; let i = $index) {\n <button\n type=\"button\"\n class=\"mform-tab\"\n role=\"tab\"\n [class.is-active]=\"activeTab() === i\"\n [attr.aria-selected]=\"activeTab() === i\"\n (click)=\"activeTab.set(i)\"\n >\n {{ tab.label || 'Tab ' + (i + 1) }}\n </button>\n }\n </div>\n @for (tab of container().children; track tab.key; let i = $index) {\n @if (activeTab() === i) {\n <div class=\"mform-tabpanel\" role=\"tabpanel\">\n <mform-node [node]=\"tab\" [engine]=\"engine()\" [tick]=\"tick()\" [providers]=\"providers()\" [scope]=\"childScope()\" [bare]=\"true\" />\n </div>\n }\n }\n </div>\n }\n @case ('array') {\n <section class=\"mform-panel mform-grid\">\n @if (container().label) {\n <header class=\"mform-panel-head\">{{ container().label }}</header>\n }\n <div class=\"mform-panel-body\">\n @for (row of rows(); track $index; let i = $index) {\n <div class=\"mform-grid-row\" role=\"group\" [attr.aria-label]=\"(container().label || container().key) + ' ' + (i + 1)\">\n <div class=\"mform-grid-fields\">\n @for (child of container().children; track child.key) {\n <mform-node [node]=\"child\" [engine]=\"engine()\" [tick]=\"tick()\" [providers]=\"providers()\" [scope]=\"rowScope(i)\" />\n }\n </div>\n <button\n type=\"button\"\n class=\"mform-row-remove\"\n (click)=\"removeRow(i)\"\n [attr.aria-label]=\"'Remove row ' + (i + 1)\"\n >\n ✕\n </button>\n </div>\n }\n <button type=\"button\" class=\"mform-row-add\" (click)=\"addRow()\">+ Add</button>\n </div>\n </section>\n }\n @default {\n @if (container().label && !bare()) {\n <section class=\"mform-panel\">\n <header class=\"mform-panel-head\">{{ container().label }}</header>\n <div class=\"mform-panel-body\">\n @for (child of container().children; track child.key) {\n <mform-node [node]=\"child\" [engine]=\"engine()\" [tick]=\"tick()\" [providers]=\"providers()\" [scope]=\"childScope()\" />\n }\n </div>\n </section>\n } @else {\n <div class=\"mform-group\">\n @for (child of container().children; track child.key) {\n <mform-node [node]=\"child\" [engine]=\"engine()\" [tick]=\"tick()\" [providers]=\"providers()\" [scope]=\"childScope()\" />\n }\n </div>\n }\n }\n }\n }\n @case ('input') {\n @if (field().type !== 'hidden') {\n <div class=\"mform-field\" [class.has-error]=\"errors().length > 0\">\n @if (field().type !== 'checkbox') {\n <label class=\"mform-label\" [attr.for]=\"controlId()\">\n {{ field().label || field().key }}\n @if (required()) {\n <span class=\"mform-req\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n @switch (field().type) {\n @case ('textarea') {\n <textarea\n class=\"mform-control\"\n [id]=\"controlId()\"\n [value]=\"stringValue()\"\n [placeholder]=\"field().placeholder || ''\"\n [disabled]=\"field().disabled === true\"\n [attr.rows]=\"rowsProp()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errors().length > 0 || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (input)=\"setString($event)\"\n (blur)=\"touch()\"\n ></textarea>\n }\n @case ('select') {\n <select\n class=\"mform-control\"\n [id]=\"controlId()\"\n [disabled]=\"field().disabled === true\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errors().length > 0 || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (change)=\"setSelect($event)\"\n (blur)=\"touch()\"\n >\n <option value=\"\" [selected]=\"stringValue() === ''\"></option>\n @for (option of options(); track option.value) {\n <option\n [value]=\"option.value\"\n [selected]=\"stringValue() === '' + option.value\"\n >\n {{ option.label }}\n </option>\n }\n </select>\n }\n @case ('radio') {\n <div class=\"mform-choices\" role=\"radiogroup\" [attr.aria-label]=\"field().label || field().key\">\n @for (option of options(); track option.value) {\n <label class=\"mform-check\">\n <input\n type=\"radio\"\n [name]=\"controlId()\"\n [checked]=\"stringValue() === '' + option.value\"\n [disabled]=\"field().disabled === true\"\n (change)=\"setValue(option.value)\"\n (blur)=\"touch()\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n }\n @case ('checkbox') {\n <label class=\"mform-check\">\n <input\n type=\"checkbox\"\n [id]=\"controlId()\"\n [checked]=\"value() === true\"\n [disabled]=\"field().disabled === true\"\n [attr.aria-invalid]=\"errors().length > 0 || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (change)=\"setChecked($event)\"\n (blur)=\"touch()\"\n />\n <span>\n {{ field().label || field().key }}\n @if (required()) {\n <span class=\"mform-req\" aria-hidden=\"true\">*</span>\n }\n </span>\n </label>\n }\n @case ('checkbox-group') {\n <div class=\"mform-choices\" role=\"group\" [attr.aria-label]=\"field().label || field().key\">\n @for (option of options(); track option.value) {\n <label class=\"mform-check\">\n <input\n type=\"checkbox\"\n [checked]=\"mapValue()['' + option.value] === true\"\n [disabled]=\"field().disabled === true\"\n (change)=\"toggleMap('' + option.value, $event)\"\n (blur)=\"touch()\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n }\n @case ('file') {\n <input\n class=\"mform-control\"\n type=\"file\"\n multiple\n [id]=\"controlId()\"\n [disabled]=\"field().disabled === true\"\n [attr.aria-describedby]=\"describedBy()\"\n (change)=\"setFiles($event)\"\n (blur)=\"touch()\"\n />\n }\n @case ('unsupported') {\n <input\n class=\"mform-control\"\n type=\"text\"\n disabled\n [id]=\"controlId()\"\n [value]=\"'Unsupported field (' + (sourceType() || 'unknown') + ')'\"\n />\n }\n @default {\n <input\n class=\"mform-control\"\n [type]=\"inputType()\"\n [id]=\"controlId()\"\n [value]=\"stringValue()\"\n [placeholder]=\"field().placeholder || ''\"\n [disabled]=\"field().disabled === true\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errors().length > 0 || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (input)=\"setString($event)\"\n (blur)=\"touch()\"\n />\n }\n }\n @if (field().description) {\n <div class=\"mform-desc\" [id]=\"controlId() + '-desc'\">{{ field().description }}</div>\n }\n @for (error of errors(); track error.rule) {\n <div class=\"mform-error\" [id]=\"controlId() + '-err'\" role=\"alert\">{{ error.message }}</div>\n }\n </div>\n }\n }\n }\n }\n `,\n})\nexport class FormNodeComponent {\n readonly node = input.required<FieldNode>();\n readonly engine = input.required<FormEngine>();\n /** Monotonic counter bumped on every engine event — invalidates the view. */\n readonly tick = input.required<number>();\n /** Data-path prefix (set by array rows and nested groups above this node). */\n readonly scope = input<string>('');\n /** Suppresses the panel chrome (used when a tab already framed the child). */\n readonly bare = input<boolean>(false);\n /** Host-registered providers for `optionsSource: provider` fields. */\n readonly providers = input<OptionsProviderRegistry>({});\n\n readonly activeTab = signal(0);\n\n /** Options resolved from a dynamic source (provider or remote URL). */\n private readonly resolvedOptions = signal<FieldOption[] | null>(null);\n /** Snapshot of the observed refresh source at the last resolution. */\n private lastRefreshKey: string | null = null;\n\n constructor() {\n effect(() => {\n const node = this.node();\n const registry = this.providers();\n if (node.kind !== 'input' || !node.optionsSource) {\n this.resolvedOptions.set(null);\n return;\n }\n const source = node.optionsSource;\n // With refreshOn, engine events re-run this effect; the refresh key\n // then decides whether the observed data actually changed.\n if (source.refreshOn) this.tick();\n const engine = untracked(() => this.engine());\n const path = untracked(() => this.path());\n const refreshKey = !source.refreshOn\n ? 'static'\n : source.refreshOn === 'data'\n ? JSON.stringify(engine.getData())\n : JSON.stringify(engine.getValue(source.refreshOn) ?? null);\n if (refreshKey === this.lastRefreshKey) return;\n this.lastRefreshKey = refreshKey;\n if (source.type === 'provider') {\n const provider = registry[source.name];\n if (!provider) return; // no provider: static options/fallback stand\n Promise.resolve(\n provider({ field: node, path, data: engine.getData(), args: source.args }),\n )\n .then((options) => this.resolvedOptions.set(options))\n .catch(() => {}); // provider failure keeps the static fallback\n } else {\n fetch(source.url)\n .then((response) => (response.ok ? response.json() : []))\n .then((list: Array<Record<string, unknown>>) =>\n this.resolvedOptions.set(\n (Array.isArray(list) ? list : []).map((item) => ({\n label: String(item[source.labelKey ?? 'label'] ?? item[source.valueKey ?? 'value'] ?? ''),\n value: (item[source.valueKey ?? 'value'] ?? '') as FieldOption['value'],\n })),\n ),\n )\n .catch(() => {});\n }\n });\n }\n\n /** Effective options: dynamically resolved first, static as fallback. */\n options(): FieldOption[] {\n return this.resolvedOptions() ?? this.field().options ?? [];\n }\n\n // -- typed views of the node ---------------------------------------------\n\n field(): InputField {\n return this.node() as InputField;\n }\n\n container(): ContainerField {\n return this.node() as ContainerField;\n }\n\n content(): string {\n return (this.node() as StaticField).content ?? '';\n }\n\n buttonAction(): string {\n return String(this.node().props?.['action'] ?? 'submit');\n }\n\n sourceType(): string {\n return String(this.node().props?.['sourceType'] ?? '');\n }\n\n rowsProp(): number | null {\n const rows = this.node().props?.['rows'];\n return typeof rows === 'number' ? rows : null;\n }\n\n // -- paths and visibility -------------------------------------------------\n\n /** Data path of this node (inputs) or of its scope (containers). */\n readonly path = computed(() => {\n const scope = this.scope();\n const node = this.node();\n if (node.kind === 'input') return scope ? `${scope}.${node.key}` : node.key;\n if (node.kind === 'container' && node.dataScope !== 'inherit') {\n return scope ? `${scope}.${node.key}` : node.key;\n }\n return scope;\n });\n\n /** Scope handed to children (nested/array containers extend it). */\n readonly childScope = computed(() => {\n const node = this.node();\n if (node.kind === 'container' && node.dataScope === 'nested') return this.path();\n return this.scope();\n });\n\n rowScope(index: number): string {\n return `${this.path()}.${index}`;\n }\n\n visible(): boolean {\n this.tick();\n const node = this.node();\n const key = node.kind === 'input' ? this.path() : node.key;\n return this.engine().isVisible(key);\n }\n\n containerLayout(): 'columns' | 'tabs' | 'array' | 'block' {\n const node = this.container();\n if (node.dataScope === 'array') return 'array';\n if (node.type === 'tabs') return 'tabs';\n if (node.type === 'columns' && node.columns?.length) return 'columns';\n return 'block';\n }\n\n columns(): FieldNode[][] {\n const node = this.container();\n return (node.columns ?? []).map((column) =>\n column.children\n .map((index) => node.children[index])\n .filter((child): child is FieldNode => child !== undefined),\n );\n }\n\n columnsTemplate(): string {\n const cols = this.container().columns ?? [];\n const total = cols.reduce((sum, c) => sum + c.width, 0) || 12;\n return cols.map((c) => `${((c.width / total) * 100).toFixed(3)}fr`).join(' ');\n }\n\n // -- values ---------------------------------------------------------------\n\n value(): unknown {\n this.tick();\n return this.engine().getValue(this.path());\n }\n\n stringValue(): string {\n const value = this.value();\n return value === undefined || value === null ? '' : String(value);\n }\n\n mapValue(): Record<string, unknown> {\n const value = this.value();\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n }\n\n rows(): unknown[] {\n const value = this.value();\n return Array.isArray(value) ? value : [];\n }\n\n required(): boolean {\n return this.field().validators?.some((v) => v.type === 'required') ?? false;\n }\n\n errors() {\n this.tick();\n return this.engine().getFieldErrors(this.path());\n }\n\n controlId(): string {\n return `mform-${this.path().replace(/\\./g, '-')}`;\n }\n\n describedBy(): string | null {\n const parts: string[] = [];\n if (this.field().description) parts.push(`${this.controlId()}-desc`);\n if (this.errors().length > 0) parts.push(`${this.controlId()}-err`);\n return parts.length ? parts.join(' ') : null;\n }\n\n inputType(): string {\n switch (this.field().type) {\n case 'number':\n case 'currency':\n return 'number';\n case 'email':\n return 'email';\n case 'password':\n return 'password';\n case 'phone':\n return 'tel';\n case 'url':\n return 'url';\n case 'time':\n return 'time';\n case 'datetime':\n return 'datetime-local';\n case 'day':\n return 'date';\n default:\n return 'text';\n }\n }\n\n // -- interaction ----------------------------------------------------------\n\n setValue(value: unknown): void {\n this.engine().setValue(this.path(), value);\n }\n\n setString(event: Event): void {\n const raw = (event.target as HTMLInputElement | HTMLTextAreaElement).value;\n if (this.field().dataType === 'number') {\n const parsed = raw === '' ? undefined : Number(raw);\n this.setValue(parsed !== undefined && Number.isFinite(parsed) ? parsed : undefined);\n } else {\n this.setValue(raw);\n }\n }\n\n setSelect(event: Event): void {\n this.setValue((event.target as HTMLSelectElement).value);\n }\n\n setChecked(event: Event): void {\n this.setValue((event.target as HTMLInputElement).checked);\n }\n\n toggleMap(option: string, event: Event): void {\n const checked = (event.target as HTMLInputElement).checked;\n this.setValue({ ...this.mapValue(), [option]: checked });\n }\n\n setFiles(event: Event): void {\n const files = (event.target as HTMLInputElement).files;\n this.setValue(files ? Array.from(files).map((f) => f.name) : []);\n }\n\n touch(): void {\n this.engine().markTouched(this.path());\n this.engine().validateField(this.path());\n }\n\n addRow(): void {\n this.engine().addRow(this.path());\n }\n\n removeRow(index: number): void {\n this.engine().removeRow(this.path(), index);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n effect,\n input,\n output,\n signal,\n} from '@angular/core';\nimport {\n collectInputs,\n createFormEngine,\n createLegacyImporter,\n importForm,\n type ContainerField,\n type FieldError,\n type FormEngine,\n type FormSchema,\n type ImportWarning,\n type MessageResolver,\n type OptionsProviderRegistry,\n type SubmitResult,\n} from '@mosaicoo/form-core';\nimport { FormNodeComponent } from './form-node.component.js';\n\n/**\n * `<mform-renderer>` — renders a form at runtime from a `FormSchema` (or any\n * definition a registered importer understands) and manages its lifecycle:\n * values, validation, conditional visibility and submission. Wizard schemas\n * (`settings.display: 'wizard'`) render as steps with per-step validation.\n *\n * Theming: every visual primitive reads a `--mform-*` CSS custom property\n * with a self-contained fallback, so the component looks finished on its own\n * and adopts the host design system when the host overrides the tokens.\n */\n@Component({\n selector: 'mform-renderer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [FormNodeComponent],\n styleUrls: ['./form-theme.css'],\n template: `\n @if (engine(); as engine) {\n <form class=\"mform-root\" novalidate (submit)=\"onSubmit($event)\">\n @if (errorSummary().length > 0) {\n <div class=\"mform-summary\" role=\"alert\" tabindex=\"-1\">\n <strong>{{ summaryTitle() }}</strong>\n <ul>\n @for (error of errorSummary(); track error.path + error.rule) {\n <li>{{ error.message }}</li>\n }\n </ul>\n </div>\n }\n @if (isWizard()) {\n <ol class=\"mform-steps\">\n @for (step of steps(); track step.key; let i = $index) {\n <li\n class=\"mform-step\"\n [class.is-active]=\"currentStep() === i\"\n [class.is-done]=\"i < currentStep()\"\n [attr.aria-current]=\"currentStep() === i ? 'step' : null\"\n >\n <span class=\"mform-step-index\">{{ i + 1 }}</span>\n <span class=\"mform-step-label\">{{ step.label || 'Step ' + (i + 1) }}</span>\n </li>\n }\n </ol>\n @if (steps()[currentStep()]; as step) {\n <mform-node\n [node]=\"step\"\n [engine]=\"engine\"\n [tick]=\"tick()\"\n [providers]=\"optionsProviders()\"\n [bare]=\"true\"\n />\n }\n <div class=\"mform-wizard-nav\">\n @if (currentStep() > 0) {\n <button type=\"button\" class=\"mform-btn mform-btn-secondary\" (click)=\"previousStep()\">\n {{ labels().previous }}\n </button>\n }\n @if (currentStep() < steps().length - 1) {\n <button type=\"button\" class=\"mform-btn\" (click)=\"nextStep()\">\n {{ labels().next }}\n </button>\n } @else {\n <button type=\"submit\" class=\"mform-btn\">{{ labels().submit }}</button>\n }\n </div>\n } @else {\n @for (node of engine.schema.fields; track node.key) {\n <mform-node [node]=\"node\" [engine]=\"engine\" [tick]=\"tick()\" [providers]=\"optionsProviders()\" />\n }\n }\n </form>\n }\n `,\n})\nexport class FormRendererComponent {\n /** Native schema input. Takes precedence over `source`. */\n readonly schema = input<FormSchema | null>(null);\n /** Foreign definition (object or JSON string) resolved via importers. */\n readonly source = input<unknown>(null);\n /** Initial data merged over schema defaults. */\n readonly initialData = input<Record<string, unknown> | null>(null);\n /** Named providers resolving `optionsSource: provider` fields. */\n readonly optionsProviders = input<OptionsProviderRegistry>({});\n /** Host-supplied message resolver (localization of validation messages). */\n readonly messages = input<MessageResolver | null>(null);\n /** Fixed renderer texts (override to localize). `{{count}}` in `summary`. */\n readonly labels = input(\n {\n previous: 'Previous',\n next: 'Next',\n submit: 'Submit',\n summary: '{{count}} field(s) need attention:',\n },\n {\n transform: (value: Partial<{ previous: string; next: string; submit: string; summary: string }>) => ({\n previous: 'Previous',\n next: 'Next',\n submit: 'Submit',\n summary: '{{count}} field(s) need attention:',\n ...value,\n }),\n },\n );\n\n summaryTitle(): string {\n return this.labels().summary.replace(/\\{\\{\\s*count\\s*\\}\\}/g, String(this.errorSummary().length));\n }\n\n /** Fired on submit; `ok` is false when validation failed. */\n readonly submitted = output<SubmitResult>();\n /** Fired on every value change with the full data snapshot. */\n readonly valueChanged = output<Record<string, unknown>>();\n\n /** Bumped on every engine event; nodes read it to refresh. */\n readonly tick = signal(0);\n /** Active wizard step index. */\n readonly currentStep = signal(0);\n\n private readonly resolved = computed<{\n schema: FormSchema | null;\n warnings: ImportWarning[];\n }>(() => {\n const native = this.schema();\n if (native) return { schema: native, warnings: [] };\n const source = this.source();\n if (source === null || source === undefined) return { schema: null, warnings: [] };\n try {\n const result = importForm(source, [createLegacyImporter()]);\n return { schema: result.schema, warnings: result.warnings };\n } catch {\n return {\n schema: null,\n warnings: [\n { code: 'unreadable-source', message: 'The form definition could not be read.' },\n ],\n };\n }\n });\n\n /** Import degradations for the current `source`, if any. */\n readonly importWarnings = computed(() => this.resolved().warnings);\n\n readonly engine = computed<FormEngine | null>(() => {\n const schema = this.resolved().schema;\n return schema\n ? createFormEngine(schema, {\n initialData: this.initialData() ?? undefined,\n messages: this.messages() ?? undefined,\n })\n : null;\n });\n\n readonly isWizard = computed(\n () => this.resolved().schema?.settings?.display === 'wizard' && this.steps().length > 0,\n );\n\n /** Wizard pages: the top-level containers of the schema. */\n readonly steps = computed<ContainerField[]>(() =>\n (this.resolved().schema?.fields ?? []).filter(\n (node): node is ContainerField => node.kind === 'container',\n ),\n );\n\n readonly errorSummary = signal<FieldError[]>([]);\n\n constructor() {\n effect((onCleanup) => {\n const engine = this.engine();\n this.errorSummary.set([]);\n this.tick.set(0);\n this.currentStep.set(0);\n if (!engine) return;\n const unsubscribe = engine.subscribe((event) => {\n this.tick.update((v) => v + 1);\n if (event.type === 'value-change') {\n this.valueChanged.emit(engine.getData());\n }\n if (event.type === 'validation') {\n // Keep the banner in sync as the user fixes fields after a submit.\n if (this.errorSummary().length > 0) {\n this.errorSummary.set(event.errors);\n }\n }\n });\n onCleanup(unsubscribe);\n });\n }\n\n // -- wizard navigation ----------------------------------------------------\n\n previousStep(): void {\n this.errorSummary.set([]);\n this.currentStep.update((step) => Math.max(0, step - 1));\n }\n\n nextStep(): void {\n const engine = this.engine();\n const step = this.steps()[this.currentStep()];\n if (!engine || !step) return;\n const errors = engine.validateContainer(step.key);\n if (errors.length > 0) {\n this.errorSummary.set(errors);\n this.focusFirstError(errors);\n return;\n }\n this.errorSummary.set([]);\n this.currentStep.update((index) => Math.min(this.steps().length - 1, index + 1));\n }\n\n // -- submission -----------------------------------------------------------\n\n onSubmit(event: Event): void {\n event.preventDefault();\n const engine = this.engine();\n if (!engine) return;\n const result = engine.submit();\n this.errorSummary.set(result.errors);\n if (!result.ok) {\n if (this.isWizard()) {\n const stepIndex = this.stepIndexForPath(result.errors[0]?.path ?? '');\n if (stepIndex >= 0) this.currentStep.set(stepIndex);\n }\n this.focusFirstError(result.errors);\n }\n this.submitted.emit(result);\n }\n\n /** Finds the wizard step that owns a (possibly row-indexed) data path. */\n private stepIndexForPath(path: string): number {\n const pattern = path\n .split('.')\n .map((part) => (/^\\d+$/.test(part) ? '*' : part))\n .join('.');\n return this.steps().findIndex((step) =>\n collectInputs({ version: 1, fields: step.children }).some(\n (entry) => entry.path === pattern,\n ),\n );\n }\n\n private focusFirstError(errors: FieldError[]): void {\n const first = errors[0];\n if (!first) return;\n const id = `mform-${first.path.replace(/\\./g, '-')}`;\n // Focus after the view updated with the error states.\n queueMicrotask(() => document.getElementById(id)?.focus());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@mosaicoo/form-angular",
3
+ "version": "0.1.0",
4
+ "description": "Angular renderer for Mosaicoo Form: accessible, token-themable dynamic forms with wizard mode and host-provided dynamic options",
5
+ "license": "MIT",
6
+ "author": "Mosaicoo",
7
+ "homepage": "https://github.com/mosaicoo/mosaicoo-form#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/mosaicoo/mosaicoo-form.git",
11
+ "directory": "packages/angular"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/mosaicoo/mosaicoo-form/issues"
15
+ },
16
+ "keywords": [
17
+ "angular",
18
+ "forms",
19
+ "dynamic-forms",
20
+ "form-renderer",
21
+ "design-system",
22
+ "accessibility"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "peerDependencies": {
28
+ "@angular/common": "^21.0.0",
29
+ "@angular/core": "^21.0.0"
30
+ },
31
+ "dependencies": {
32
+ "@mosaicoo/form-core": "^0.1.0",
33
+ "tslib": "^2.3.0"
34
+ },
35
+ "sideEffects": false,
36
+ "module": "fesm2022/mosaicoo-form-angular.mjs",
37
+ "typings": "types/mosaicoo-form-angular.d.ts",
38
+ "exports": {
39
+ "./package.json": {
40
+ "default": "./package.json"
41
+ },
42
+ ".": {
43
+ "types": "./types/mosaicoo-form-angular.d.ts",
44
+ "default": "./fesm2022/mosaicoo-form-angular.mjs"
45
+ }
46
+ },
47
+ "type": "module"
48
+ }
@@ -0,0 +1,128 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import * as _mosaicoo_form_core from '@mosaicoo/form-core';
3
+ import { FormSchema, OptionsProviderRegistry, MessageResolver, SubmitResult, ImportWarning, FormEngine, ContainerField, FieldError, FieldNode, FieldOption, InputField } from '@mosaicoo/form-core';
4
+
5
+ /**
6
+ * `<mform-renderer>` — renders a form at runtime from a `FormSchema` (or any
7
+ * definition a registered importer understands) and manages its lifecycle:
8
+ * values, validation, conditional visibility and submission. Wizard schemas
9
+ * (`settings.display: 'wizard'`) render as steps with per-step validation.
10
+ *
11
+ * Theming: every visual primitive reads a `--mform-*` CSS custom property
12
+ * with a self-contained fallback, so the component looks finished on its own
13
+ * and adopts the host design system when the host overrides the tokens.
14
+ */
15
+ declare class FormRendererComponent {
16
+ /** Native schema input. Takes precedence over `source`. */
17
+ readonly schema: _angular_core.InputSignal<FormSchema | null>;
18
+ /** Foreign definition (object or JSON string) resolved via importers. */
19
+ readonly source: _angular_core.InputSignal<unknown>;
20
+ /** Initial data merged over schema defaults. */
21
+ readonly initialData: _angular_core.InputSignal<Record<string, unknown> | null>;
22
+ /** Named providers resolving `optionsSource: provider` fields. */
23
+ readonly optionsProviders: _angular_core.InputSignal<OptionsProviderRegistry>;
24
+ /** Host-supplied message resolver (localization of validation messages). */
25
+ readonly messages: _angular_core.InputSignal<MessageResolver | null>;
26
+ /** Fixed renderer texts (override to localize). `{{count}}` in `summary`. */
27
+ readonly labels: _angular_core.InputSignalWithTransform<{
28
+ previous: string;
29
+ next: string;
30
+ submit: string;
31
+ summary: string;
32
+ }, Partial<{
33
+ previous: string;
34
+ next: string;
35
+ submit: string;
36
+ summary: string;
37
+ }>>;
38
+ summaryTitle(): string;
39
+ /** Fired on submit; `ok` is false when validation failed. */
40
+ readonly submitted: _angular_core.OutputEmitterRef<SubmitResult>;
41
+ /** Fired on every value change with the full data snapshot. */
42
+ readonly valueChanged: _angular_core.OutputEmitterRef<Record<string, unknown>>;
43
+ /** Bumped on every engine event; nodes read it to refresh. */
44
+ readonly tick: _angular_core.WritableSignal<number>;
45
+ /** Active wizard step index. */
46
+ readonly currentStep: _angular_core.WritableSignal<number>;
47
+ private readonly resolved;
48
+ /** Import degradations for the current `source`, if any. */
49
+ readonly importWarnings: _angular_core.Signal<ImportWarning[]>;
50
+ readonly engine: _angular_core.Signal<FormEngine | null>;
51
+ readonly isWizard: _angular_core.Signal<boolean>;
52
+ /** Wizard pages: the top-level containers of the schema. */
53
+ readonly steps: _angular_core.Signal<ContainerField[]>;
54
+ readonly errorSummary: _angular_core.WritableSignal<FieldError[]>;
55
+ constructor();
56
+ previousStep(): void;
57
+ nextStep(): void;
58
+ onSubmit(event: Event): void;
59
+ /** Finds the wizard step that owns a (possibly row-indexed) data path. */
60
+ private stepIndexForPath;
61
+ private focusFirstError;
62
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormRendererComponent, never>;
63
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormRendererComponent, "mform-renderer", never, { "schema": { "alias": "schema"; "required": false; "isSignal": true; }; "source": { "alias": "source"; "required": false; "isSignal": true; }; "initialData": { "alias": "initialData"; "required": false; "isSignal": true; }; "optionsProviders": { "alias": "optionsProviders"; "required": false; "isSignal": true; }; "messages": { "alias": "messages"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "submitted": "submitted"; "valueChanged": "valueChanged"; }, never, never, true, never>;
64
+ }
65
+
66
+ /**
67
+ * Renders one schema node (input, container or static) and recurses into
68
+ * children. State lives in the headless engine — this component only projects
69
+ * it and forwards user interaction. `tick` changes whenever the engine emits,
70
+ * invalidating the OnPush view.
71
+ */
72
+ declare class FormNodeComponent {
73
+ readonly node: _angular_core.InputSignal<FieldNode>;
74
+ readonly engine: _angular_core.InputSignal<FormEngine>;
75
+ /** Monotonic counter bumped on every engine event — invalidates the view. */
76
+ readonly tick: _angular_core.InputSignal<number>;
77
+ /** Data-path prefix (set by array rows and nested groups above this node). */
78
+ readonly scope: _angular_core.InputSignal<string>;
79
+ /** Suppresses the panel chrome (used when a tab already framed the child). */
80
+ readonly bare: _angular_core.InputSignal<boolean>;
81
+ /** Host-registered providers for `optionsSource: provider` fields. */
82
+ readonly providers: _angular_core.InputSignal<OptionsProviderRegistry>;
83
+ readonly activeTab: _angular_core.WritableSignal<number>;
84
+ /** Options resolved from a dynamic source (provider or remote URL). */
85
+ private readonly resolvedOptions;
86
+ /** Snapshot of the observed refresh source at the last resolution. */
87
+ private lastRefreshKey;
88
+ constructor();
89
+ /** Effective options: dynamically resolved first, static as fallback. */
90
+ options(): FieldOption[];
91
+ field(): InputField;
92
+ container(): ContainerField;
93
+ content(): string;
94
+ buttonAction(): string;
95
+ sourceType(): string;
96
+ rowsProp(): number | null;
97
+ /** Data path of this node (inputs) or of its scope (containers). */
98
+ readonly path: _angular_core.Signal<string>;
99
+ /** Scope handed to children (nested/array containers extend it). */
100
+ readonly childScope: _angular_core.Signal<string>;
101
+ rowScope(index: number): string;
102
+ visible(): boolean;
103
+ containerLayout(): 'columns' | 'tabs' | 'array' | 'block';
104
+ columns(): FieldNode[][];
105
+ columnsTemplate(): string;
106
+ value(): unknown;
107
+ stringValue(): string;
108
+ mapValue(): Record<string, unknown>;
109
+ rows(): unknown[];
110
+ required(): boolean;
111
+ errors(): _mosaicoo_form_core.FieldError[];
112
+ controlId(): string;
113
+ describedBy(): string | null;
114
+ inputType(): string;
115
+ setValue(value: unknown): void;
116
+ setString(event: Event): void;
117
+ setSelect(event: Event): void;
118
+ setChecked(event: Event): void;
119
+ toggleMap(option: string, event: Event): void;
120
+ setFiles(event: Event): void;
121
+ touch(): void;
122
+ addRow(): void;
123
+ removeRow(index: number): void;
124
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormNodeComponent, never>;
125
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormNodeComponent, "mform-node", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "engine": { "alias": "engine"; "required": true; "isSignal": true; }; "tick": { "alias": "tick"; "required": true; "isSignal": true; }; "scope": { "alias": "scope"; "required": false; "isSignal": true; }; "bare": { "alias": "bare"; "required": false; "isSignal": true; }; "providers": { "alias": "providers"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
126
+ }
127
+
128
+ export { FormNodeComponent, FormRendererComponent };