@dynamic-field-kit/angular 1.4.0 → 1.5.1
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.
- package/CHANGELOG.md +190 -0
- package/LICENSE +21 -0
- package/README.md +144 -5
- package/dist/components/DynamicFormDevTools.d.ts +16 -0
- package/dist/components/DynamicInput.d.ts +2 -1
- package/dist/components/FieldInput.d.ts +7 -1
- package/dist/components/MultiFieldInput.d.ts +13 -2
- package/dist/fesm2022/dynamic-field-kit-angular.mjs +578 -34
- package/dist/index.d.ts +1 -1
- package/dist/layout/index.d.ts +2 -2
- package/dist/lib/dynamic-field-kit.module.d.ts +4 -4
- package/dist/lib/dynamic-form.store.d.ts +23 -0
- package/dist/public-api.d.ts +10 -8
- package/package.json +58 -24
- package/dist/README.md +0 -235
- package/dist/esm2022/components/BaseInput.mjs +0 -59
- package/dist/esm2022/components/DynamicInput.mjs +0 -244
- package/dist/esm2022/components/FieldInput.mjs +0 -99
- package/dist/esm2022/components/MultiFieldInput.mjs +0 -338
- package/dist/esm2022/dynamic-field-kit-angular.mjs +0 -5
- package/dist/esm2022/fieldRegistryToken.mjs +0 -12
- package/dist/esm2022/layout/defaultLayouts.mjs +0 -114
- package/dist/esm2022/layout/index.mjs +0 -3
- package/dist/esm2022/layout/layoutRegistry.mjs +0 -14
- package/dist/esm2022/lib/dynamic-field-kit.module.mjs +0 -52
- package/dist/esm2022/public-api.mjs +0 -18
- package/dist/esm2022/types/layout.mjs +0 -2
- package/dist/fesm2022/dynamic-field-kit-angular.mjs.map +0 -1
- package/ng-package.json +0 -7
- package/src/components/BaseInput.ts +0 -57
- package/src/components/DynamicInput.ts +0 -280
- package/src/components/FieldInput.ts +0 -74
- package/src/components/MultiFieldInput.ts +0 -331
- package/src/fieldRegistryToken.ts +0 -15
- package/src/layout/defaultLayouts.ts +0 -70
- package/src/layout/index.ts +0 -2
- package/src/layout/layoutRegistry.ts +0 -25
- package/src/lib/dynamic-field-kit.module.ts +0 -29
- package/src/public-api.ts +0 -40
- package/src/types/layout.ts +0 -14
- package/test/DynamicInput.spec.ts +0 -230
- package/test/FieldInput.spec.ts +0 -146
- package/test/MultiFieldInput.spec.ts +0 -256
- package/test/helpers/renderers.ts +0 -89
- package/test/layout.spec.ts +0 -119
- package/test/publicApi.spec.ts +0 -64
- package/test/setup.ts +0 -12
- package/test/smoke.spec.ts +0 -27
- package/tsconfig.json +0 -13
- package/tsconfig.spec.json +0 -9
- package/vitest.config.ts +0 -30
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-field-kit-angular.mjs","sources":["../../src/components/BaseInput.ts","../../src/fieldRegistryToken.ts","../../src/components/DynamicInput.ts","../../src/components/FieldInput.ts","../../src/components/MultiFieldInput.ts","../../src/layout/layoutRegistry.ts","../../src/layout/defaultLayouts.ts","../../src/lib/dynamic-field-kit.module.ts","../../src/public-api.ts","../../src/dynamic-field-kit-angular.ts"],"sourcesContent":["import {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n} from '@angular/core';\n\n// Mirrors the framework-agnostic FieldRendererProps. Domain-specific inputs\n// (acceptFile, maxLength, ...) intentionally live on the individual renderer,\n// not here - pass them per field via FieldDescription.props instead.\nexport interface FieldInputProps {\n value?: unknown;\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n error?: string | string[];\n options?: unknown[];\n className?: string;\n description?: string;\n}\n\n@Component({\n template: '',\n})\nexport abstract class BaseInputComponent implements OnChanges {\n @Input() value?: unknown;\n @Input() label?: string;\n @Input() placeholder?: string;\n @Input() required?: boolean;\n @Input() disabled?: boolean;\n @Input() readOnly?: boolean;\n @Input() error?: string | string[];\n @Input() options?: unknown[];\n @Input() className?: string;\n @Input() description?: string;\n\n @Output() valueChange = new EventEmitter<unknown>();\n\n constructor(protected cdr: ChangeDetectorRef) {}\n\n ngOnChanges(_changes: SimpleChanges): void {\n this.detectChanges();\n }\n\n protected detectChanges(): void {\n this.cdr.markForCheck();\n }\n\n protected hasChanges(changes: SimpleChanges, prop: string): boolean {\n return changes[prop] !== undefined;\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { FieldRegistry, fieldRegistry } from '@dynamic-field-kit/core';\n\n// Injecting this token yields the process-wide singleton by default, so code\n// that never provides it keeps working. Provide it on a component/route to give\n// that subtree an isolated set of renderers:\n//\n// providers: [{ provide: FIELD_REGISTRY, useValue: myScopedRegistry }]\nexport const FIELD_REGISTRY = new InjectionToken<FieldRegistry>(\n 'dfk.FieldRegistry',\n {\n providedIn: 'root',\n factory: () => fieldRegistry,\n }\n);\n","import { CommonModule } from '@angular/common';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n Type,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { FieldTypeKey, Properties } from '@dynamic-field-kit/core';\nimport { Subscription } from 'rxjs';\nimport { FIELD_REGISTRY } from '../fieldRegistryToken';\nimport { BaseInputComponent } from './BaseInput';\n\n// Only the framework-agnostic FieldRendererProps keys. Domain-specific props\n// reach the renderer through `extraProps` (FieldDescription.props) instead.\nconst KNOWN_PROPS = [\n 'value',\n 'label',\n 'placeholder',\n 'required',\n 'disabled',\n 'readOnly',\n 'error',\n 'options',\n 'className',\n 'description',\n] as const;\n\n@Component({\n selector: 'dfk-dynamic-input',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<div #host style=\"display: contents;\"></div>`,\n})\nexport class DynamicInput\n extends BaseInputComponent\n implements OnChanges, AfterViewInit, OnDestroy\n{\n @Input() type!: FieldTypeKey;\n // Extra, framework-agnostic props forwarded verbatim to the renderer.\n @Input() extraProps?: Properties;\n @Output() override valueChange = new EventEmitter<unknown>();\n @Output() onChange = new EventEmitter<unknown>();\n\n private registry = inject(FIELD_REGISTRY);\n\n @ViewChild('host', { read: ViewContainerRef, static: false })\n host!: ViewContainerRef;\n private compRef?: ComponentRef<unknown>;\n private inputInstance?: unknown;\n private subscriptions: Subscription[] = [];\n // Tracks which KNOWN_PROPS were actually supplied to DynamicInput (via\n // SimpleChanges), independent of TS class-field emit. See applyProps.\n private supplied = new Set<string>();\n\n ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n\n for (const prop of KNOWN_PROPS) {\n if (changes[prop]) {\n this.supplied.add(prop);\n }\n }\n\n if (this.inputInstance) {\n this.syncPropsToInstance(changes);\n }\n\n if (changes['type'] && !changes['type'].firstChange && this.host) {\n this.render();\n } else if (!this.inputInstance && this.host) {\n this.render();\n }\n }\n\n ngAfterViewInit(): void {\n this.render();\n }\n\n ngOnDestroy(): void {\n this.cleanup();\n }\n\n private syncPropsToInstance(changes: SimpleChanges): void {\n if (!this.inputInstance) {\n return;\n }\n\n for (const prop of KNOWN_PROPS) {\n if (changes[prop] && this.inputInstance) {\n (this.inputInstance as Record<string, unknown>)[prop] = (\n this as Record<string, unknown>\n )[prop];\n }\n }\n if (changes['extraProps']) {\n this.applyExtraProps(this.inputInstance);\n }\n this.compRef?.changeDetectorRef?.detectChanges();\n }\n\n private cleanup(): void {\n this.cleanupSubscriptions();\n this.cleanupRenderedComponent();\n }\n\n private cleanupSubscriptions(): void {\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n }\n\n private cleanupRenderedComponent(): void {\n this.compRef?.destroy();\n this.compRef = undefined;\n this.inputInstance = undefined;\n }\n\n private render(): void {\n const Renderer = this.registry.get(this.type);\n this.cleanup();\n this.host.clear();\n\n if (!Renderer) {\n this.renderError(`Unknown field type: ${this.type}`);\n return;\n }\n\n if (this.isComponentType(Renderer)) {\n this.renderComponent(Renderer as unknown as Type<unknown>);\n } else if (typeof Renderer === 'function') {\n this.renderFallback(Renderer);\n } else {\n this.renderError(`Invalid renderer for type: ${this.type}`);\n }\n }\n\n // Angular component classes carry a static ɵcmp. Checked instead of\n // reflectComponentType() because the peer range starts at Angular 13 and\n // reflectComponentType is v14+. Plain function renderers have no ɵcmp and\n // fall through to renderFallback. Uses hasOwnProperty (not `in`) so a\n // class that merely extends a component without its own @Component\n // decorator - and would otherwise inherit the parent's static ɵcmp via the\n // prototype chain - is not mistaken for a component in its own right.\n private isComponentType(renderer: unknown): boolean {\n return (\n typeof renderer === 'function' &&\n Object.prototype.hasOwnProperty.call(renderer, 'ɵcmp')\n );\n }\n\n private renderComponent(compType: Type<unknown>): void {\n try {\n const compRef = this.host.createComponent(compType);\n const instance = compRef.instance;\n\n if (!instance) {\n this.renderError(`Failed to create instance for ${this.type}`);\n return;\n }\n\n this.applyProps(instance);\n this.bindOutputs(instance);\n\n this.compRef = compRef;\n this.inputInstance = instance;\n compRef.changeDetectorRef.detectChanges();\n } catch {\n this.renderError(`Failed to render field: ${this.type}`);\n }\n }\n\n private renderFallback(renderer: unknown): void {\n try {\n const props = this.getFallbackProps();\n const result = (renderer as (props: unknown) => string)(props);\n\n if (typeof result === 'string') {\n const el = document.createElement('div');\n el.innerHTML = result;\n this.host.element.nativeElement.appendChild(el);\n }\n } catch {\n this.renderError(`Failed to render field: ${this.type}`);\n }\n }\n\n private getFallbackProps(): Record<string, unknown> {\n return {\n ...this.extraProps,\n value: this.value,\n onValueChange: (v: unknown) => this.emitValue(v),\n label: this.label ?? '',\n placeholder: this.placeholder ?? '',\n required: this.required ?? false,\n disabled: this.disabled ?? false,\n readOnly: this.readOnly ?? false,\n error: this.error,\n options: this.options ?? [],\n className: this.className ?? '',\n description: this.description ?? '',\n };\n }\n\n // Gates on `this.supplied` (populated from SimpleChanges in ngOnChanges),\n // not on `prop in instanceObj` or `prop in this`. Both `in` checks test a\n // TypeScript class-field emit artifact rather than intent: whether a\n // property slot exists at runtime depends on the compile target\n // (useDefineForClassFields is false below ES2022, true at ES2022+), so the\n // same source can behave oppositely between this package's test build and\n // its shipped ES2022 bundle, where every declared field is always an own\n // property. `this.supplied` instead reflects only whether Angular ever\n // fired a SimpleChange for that input, i.e. whether the prop was *bound*\n // at all - it skips only props DynamicInput was never given a binding\n // for. It is NOT a general \"renderer defaults survive\" guarantee: Angular\n // fires a firstChange SimpleChange for every bound input even when the\n // bound value is undefined, and FieldInput's template binds all\n // KNOWN_PROPS unconditionally, so on the real\n // MultiFieldInput -> FieldInput -> DynamicInput path every prop counts as\n // supplied and renderer-side defaults (e.g. `@Input() label = 'None'`)\n // are still overwritten with undefined. This only helps when DynamicInput\n // is mounted directly with some inputs left unbound.\n private applyProps(instance: unknown): void {\n const instanceObj = instance as Record<string, unknown>;\n for (const prop of KNOWN_PROPS) {\n if (this.supplied.has(prop)) {\n instanceObj[prop] = (this as Record<string, unknown>)[prop];\n }\n }\n this.applyExtraProps(instance);\n }\n\n private applyExtraProps(instance: unknown): void {\n if (!instance || !this.extraProps) {\n return;\n }\n const instanceObj = instance as Record<string, unknown>;\n for (const [key, value] of Object.entries(this.extraProps)) {\n instanceObj[key] = value;\n }\n }\n\n private bindOutputs(instance: unknown): void {\n const outputNames: Array<'valueChange' | 'onValueChange'> = [\n 'valueChange',\n 'onValueChange',\n ];\n\n for (const outputName of outputNames) {\n const output = (instance as Record<string, unknown>)[outputName];\n if (output && typeof output === 'object' && 'subscribe' in output) {\n const sub = (\n output as { subscribe: (cb: (v: unknown) => void) => Subscription }\n ).subscribe((value: unknown) => this.emitValue(value));\n this.subscriptions.push(sub);\n }\n }\n }\n\n private emitValue(value: unknown): void {\n this.valueChange.emit(value);\n this.onChange.emit(value);\n }\n\n private renderError(message: string): void {\n const el = document.createElement('div');\n el.textContent = message;\n el.style.color = 'red';\n this.host.element.nativeElement.appendChild(el);\n }\n}\n","import { NgIf } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n} from '@angular/core';\nimport { FieldDescription } from '@dynamic-field-kit/core';\nimport { DynamicInput } from './DynamicInput';\n\n@Component({\n selector: 'dfk-field-input',\n standalone: true,\n imports: [NgIf, DynamicInput],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <dfk-dynamic-input\n *ngIf=\"shouldRender\"\n [type]=\"fieldDescription!.type\"\n [value]=\"value\"\n [label]=\"fieldDescription!.label\"\n [placeholder]=\"fieldDescription!.placeholder\"\n [required]=\"fieldDescription!.required\"\n [description]=\"$any(fieldDescription!.description)\"\n [options]=\"resolvedOptions\"\n [className]=\"fieldDescription!.className\"\n (valueChange)=\"\n onValueChangeField.emit({ value: $event, key: fieldDescription!.name })\n \"\n [disabled]=\"disabled\"\n [readOnly]=\"readOnly\"\n [error]=\"$any(error)\"\n [extraProps]=\"fieldDescription!.props\"\n ></dfk-dynamic-input>\n `,\n})\nexport class FieldInput implements OnChanges {\n @Input() fieldDescription?: FieldDescription;\n @Input() value?: unknown;\n @Input() options?: Record<string, unknown>[];\n @Input() disabled?: boolean;\n @Input() readOnly?: boolean;\n @Input() error?: string | string[];\n @Output() onValueChangeField = new EventEmitter<{\n value: unknown;\n key: string;\n }>();\n\n shouldRender = false;\n\n get resolvedOptions(): Record<string, unknown>[] | undefined {\n if (this.options) {\n return this.options;\n }\n if (!this.fieldDescription?.options) {\n return undefined;\n }\n if (typeof this.fieldDescription.options === 'function') {\n return undefined;\n }\n return this.fieldDescription.options;\n }\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnChanges(_changes: SimpleChanges): void {\n this.shouldRender = !!this.fieldDescription;\n this.cdr.markForCheck();\n }\n}\n","import { NgClass, NgFor, NgIf } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnChanges,\n OnInit,\n Output,\n SimpleChanges,\n} from '@angular/core';\nimport {\n applyComputedValues,\n canAddGroupItem,\n canRemoveGroupItem,\n createGroupItem,\n resolveDisabled,\n resolveOptions,\n resolveReadOnly,\n validateField,\n validateFields,\n FieldDescription,\n Properties,\n} from '@dynamic-field-kit/core';\nimport type { ValidationResult } from '@dynamic-field-kit/core';\nimport { BaseLayoutConfig, LayoutConfig } from '../types/layout';\nimport { FieldInput } from './FieldInput';\n\nconst DEFAULT_BREAKPOINT = 768;\n\n@Component({\n selector: 'dfk-multi-field-input',\n standalone: true,\n // Repeatable field groups render a nested <dfk-multi-field-input> per item\n // (see the #groupTpl below), so this component imports itself. That's the\n // supported way to give a standalone component recursive template usage\n // without a cross-file circular import between FieldInput and a separate\n // group component (whose `imports` arrays are evaluated eagerly at module\n // load time and would deadlock on an actual circular module reference).\n imports: [NgClass, NgFor, NgIf, FieldInput, MultiFieldInput],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div\n class=\"p-4 border rounded-lg bg-gray-50\"\n [ngClass]=\"{\n 'flex flex-col': resolvedLayoutType === 'column',\n 'flex flex-row': resolvedLayoutType === 'row',\n grid: resolvedLayoutType === 'grid'\n }\"\n [style.gap.px]=\"gap\"\n [style.gridTemplateColumns]=\"\n resolvedLayoutType === 'grid' ? 'repeat(' + columns + ', 1fr)' : null\n \"\n >\n <ng-container *ngFor=\"let field of visibleFields; trackBy: trackByFn\">\n <dfk-field-input\n *ngIf=\"!field.fields\"\n [fieldDescription]=\"field\"\n [value]=\"data[field.name]\"\n [options]=\"getResolvedOptions(field)\"\n [disabled]=\"getDisabled(field)\"\n [readOnly]=\"getReadOnly(field)\"\n [error]=\"getError(field)\"\n (onValueChangeField)=\"onFieldChange($event)\"\n ></dfk-field-input>\n\n <div *ngIf=\"field.fields\" [class]=\"field.className\">\n <div *ngIf=\"field.label\">{{ field.label }}</div>\n <div\n *ngFor=\"\n let item of getItems(field);\n let i = index;\n trackBy: groupTrackBy(field)\n \"\n style=\"display: flex; align-items: flex-start; gap: 8px;\"\n >\n <div style=\"flex: 1\">\n <dfk-multi-field-input\n [fieldDescriptions]=\"field.fields\"\n [properties]=\"item\"\n [rootData]=\"rootData ?? data\"\n (onChange)=\"onGroupItemChange(field, i, $event)\"\n ></dfk-multi-field-input>\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"\n (field.removeLabel || 'Remove') +\n ' ' +\n (field.label || field.name) +\n ' ' +\n (i + 1)\n \"\n (click)=\"onGroupItemRemove(field, i)\"\n [disabled]=\"!canRemoveItem(field)\"\n >\n {{ field.removeLabel || 'Remove' }}\n </button>\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"\n (field.addLabel || 'Add') + ' ' + (field.label || field.name)\n \"\n (click)=\"onGroupItemAdd(field)\"\n [disabled]=\"!canAddItem(field)\"\n >\n {{ field.addLabel || 'Add' }}\n </button>\n </div>\n </ng-container>\n </div>\n `,\n})\nexport class MultiFieldInput implements OnInit, OnChanges {\n @Input() fieldDescriptions: FieldDescription[] = [];\n @Input() properties?: Properties;\n @Output() onChange = new EventEmitter<Properties>();\n @Output() validityChange = new EventEmitter<ValidationResult>();\n @Input() layout: LayoutConfig = 'column';\n // Top-level form data, threaded down through repeatable groups so a nested\n // field's appearCondition/computeValue can read the root form. Omitted at\n // the top level, where the form's own data is the root.\n @Input() rootData?: Properties;\n\n data: Properties = {};\n visibleFields: FieldDescription[] = [];\n private isMobile = false;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n @HostListener('window:resize')\n onWindowResize(): void {\n const wasMobile = this.isMobile;\n this.updateIsMobile();\n if (wasMobile !== this.isMobile) {\n this.cdr.markForCheck();\n }\n }\n\n get resolvedLayout(): BaseLayoutConfig {\n if (typeof this.layout === 'object' && this.layout.type === 'responsive') {\n return this.isMobile ? this.layout.mobile : this.layout.desktop;\n }\n return this.layout as BaseLayoutConfig;\n }\n\n get resolvedLayoutType(): string {\n const resolved = this.resolvedLayout;\n return typeof resolved === 'string' ? resolved : resolved.type;\n }\n\n get gap(): number {\n const resolved = this.resolvedLayout;\n if (typeof resolved === 'object' && resolved.gap !== undefined) {\n return resolved.gap;\n }\n return 12;\n }\n\n get columns(): number {\n const resolved = this.resolvedLayout;\n if (typeof resolved === 'object' && resolved.type === 'grid') {\n return resolved.columns ?? 2;\n }\n return 2;\n }\n\n trackByFn(index: number, field: FieldDescription): string | number {\n return field.name || index;\n }\n\n trackByIndex(index: number): number {\n return index;\n }\n\n private groupTrackByCache = new WeakMap<\n FieldDescription,\n (index: number, item: Properties) => unknown\n >();\n\n // Returns a stable trackBy per group field: item[keyField] when configured,\n // else the index. Cached by field reference so the template hands Angular the\n // same function each change-detection pass.\n groupTrackBy(\n field: FieldDescription\n ): (index: number, item: Properties) => unknown {\n let fn = this.groupTrackByCache.get(field);\n if (!fn) {\n fn = (index: number, item: Properties) =>\n field.keyField ? item[field.keyField] ?? index : index;\n this.groupTrackByCache.set(field, fn);\n }\n return fn;\n }\n\n ngOnInit() {\n this.updateIsMobile();\n this.init();\n }\n\n ngOnChanges(_changes: SimpleChanges) {\n this.init();\n }\n\n private updateIsMobile(): void {\n const breakpoint =\n typeof this.layout === 'object' && this.layout.type === 'responsive'\n ? this.layout.breakpoint ?? DEFAULT_BREAKPOINT\n : DEFAULT_BREAKPOINT;\n if (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function'\n ) {\n this.isMobile = window.matchMedia(\n `(max-width: ${breakpoint - 1}px)`\n ).matches;\n } else {\n this.isMobile =\n typeof window !== 'undefined' && window.innerWidth < breakpoint;\n }\n }\n\n private init() {\n if (this.properties) {\n this.data = applyComputedValues(\n this.fieldDescriptions,\n { ...this.properties },\n this.rootData\n );\n }\n this.updateVisibleFields();\n this.validityChange.emit(\n validateFields(this.fieldDescriptions, this.data, this.rootData)\n );\n }\n\n private updateVisibleFields() {\n const root = this.rootData ?? this.data;\n this.visibleFields = this.fieldDescriptions.filter(\n (f) => !f.appearCondition || f.appearCondition(this.data, root)\n );\n }\n\n onFieldChange(event: { value: unknown; key: string }): void {\n this.commitData({ ...this.data, [event.key]: event.value });\n }\n\n getItems(field: FieldDescription): Properties[] {\n const value = this.data[field.name];\n return Array.isArray(value) ? (value as Properties[]) : [];\n }\n\n getResolvedOptions(field: FieldDescription): Properties[] | undefined {\n return resolveOptions(field, this.data, this.rootData);\n }\n\n getDisabled(field: FieldDescription): boolean {\n return resolveDisabled(field, this.data, this.rootData);\n }\n\n getReadOnly(field: FieldDescription): boolean {\n return resolveReadOnly(field, this.data, this.rootData);\n }\n\n getError(field: FieldDescription): string[] | undefined {\n if (this.getDisabled(field)) {\n return undefined;\n }\n const errors = validateField(\n field,\n this.data[field.name],\n this.data,\n this.rootData\n );\n return errors.length > 0 ? errors : undefined;\n }\n\n canAddItem(field: FieldDescription): boolean {\n return canAddGroupItem(field, this.getItems(field));\n }\n\n canRemoveItem(field: FieldDescription): boolean {\n return canRemoveGroupItem(field, this.getItems(field));\n }\n\n onGroupItemAdd(field: FieldDescription): void {\n if (!this.canAddItem(field)) {\n return;\n }\n const items = this.getItems(field);\n this.commitData({\n ...this.data,\n [field.name]: [...items, createGroupItem(field)],\n });\n }\n\n onGroupItemRemove(field: FieldDescription, index: number): void {\n if (!this.canRemoveItem(field)) {\n return;\n }\n const items = this.getItems(field).filter((_, i) => i !== index);\n this.commitData({ ...this.data, [field.name]: items });\n }\n\n onGroupItemChange(\n field: FieldDescription,\n index: number,\n next: Properties\n ): void {\n const items = this.getItems(field).slice();\n items[index] = next;\n this.commitData({ ...this.data, [field.name]: items });\n }\n\n private commitData(nextData: Properties): void {\n this.data = applyComputedValues(\n this.fieldDescriptions,\n nextData,\n this.rootData\n );\n this.updateVisibleFields();\n this.onChange.emit(this.data);\n this.validityChange.emit(\n validateFields(this.fieldDescriptions, this.data, this.rootData)\n );\n this.cdr.markForCheck();\n }\n}\n","import { Type } from '@angular/core';\n\nexport type LayoutRenderer<C = unknown> = (props: {\n children: unknown[];\n config?: C;\n}) => unknown;\n\nexport type AngularLayoutComponent = Type<unknown>;\n\nexport class LayoutRegistry {\n private layouts = new Map<string, AngularLayoutComponent>();\n\n register(type: string, component: AngularLayoutComponent): void {\n if (this.layouts.has(type)) {\n console.warn(`[dynamic-field-kit] Layout \"${type}\" already exists`);\n }\n this.layouts.set(type, component);\n }\n\n get(type: string): AngularLayoutComponent | undefined {\n return this.layouts.get(type);\n }\n}\n\nexport const layoutRegistry = new LayoutRegistry();\n","import { CommonModule } from '@angular/common';\nimport { Component, Input, TemplateRef } from '@angular/core';\nimport { layoutRegistry } from './layoutRegistry';\n\n@Component({\n selector: 'dfk-column-layout',\n standalone: true,\n imports: [CommonModule],\n template: `<div\n [style.display]=\"'flex'\"\n [style.flexDirection]=\"'column'\"\n [style.gap]=\"gap + 'px'\"\n >\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>`,\n})\nexport class ColumnLayout {\n @Input() config?: { gap?: number };\n @Input() template!: TemplateRef<unknown>;\n get gap() {\n return this.config?.gap ?? 12;\n }\n}\n\n@Component({\n selector: 'dfk-row-layout',\n standalone: true,\n imports: [CommonModule],\n template: `<div\n [style.display]=\"'flex'\"\n [style.flexDirection]=\"'row'\"\n [style.gap]=\"gap + 'px'\"\n >\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>`,\n})\nexport class RowLayout {\n @Input() config?: { gap?: number };\n @Input() template!: TemplateRef<unknown>;\n get gap() {\n return this.config?.gap ?? 12;\n }\n}\n\n@Component({\n selector: 'dfk-grid-layout',\n standalone: true,\n imports: [CommonModule],\n template: `<div\n [style.display]=\"'grid'\"\n [style.gridTemplateColumns]=\"'repeat(' + columns + ', 1fr)'\"\n [style.gap]=\"gap + 'px'\"\n >\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>`,\n})\nexport class GridLayout {\n @Input() config?: { columns?: number; gap?: number };\n @Input() template!: TemplateRef<unknown>;\n get columns() {\n return this.config?.columns ?? 2;\n }\n get gap() {\n return this.config?.gap ?? 12;\n }\n}\n\nlayoutRegistry.register('column', ColumnLayout);\nlayoutRegistry.register('row', RowLayout);\nlayoutRegistry.register('grid', GridLayout);\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { DynamicInput } from '../components/DynamicInput';\nimport { FieldInput } from '../components/FieldInput';\nimport { MultiFieldInput } from '../components/MultiFieldInput';\n\nimport { ColumnLayout, RowLayout, GridLayout } from '../layout/defaultLayouts';\n\n@NgModule({\n imports: [\n CommonModule,\n DynamicInput,\n FieldInput,\n MultiFieldInput,\n ColumnLayout,\n RowLayout,\n GridLayout,\n ],\n exports: [\n DynamicInput,\n FieldInput,\n MultiFieldInput,\n ColumnLayout,\n RowLayout,\n GridLayout,\n ],\n})\nexport class DynamicFieldKitModule {}\n","// public-api.ts\n\n// Components\nexport * from './components/BaseInput';\nexport * from './components/DynamicInput';\nexport * from './components/FieldInput';\nexport * from './components/MultiFieldInput';\n\n// Layout\nexport * from './layout';\nexport * from './types/layout';\n\n// Module\nexport * from './lib/dynamic-field-kit.module';\n\n// Re-export types from core (only type, not export * )\nexport type {\n FieldDescription,\n FieldRendererProps,\n FieldTypeKey,\n} from '@dynamic-field-kit/core';\n\n// Optional: expose registry for advanced use cases, but not required for basic usage\nexport { fieldRegistry, FieldRegistry } from '@dynamic-field-kit/core';\n\nexport {\n validateField,\n validateFieldAsync,\n validateFields,\n validateFieldsAsync,\n resolveDisabled,\n resolveReadOnly,\n resolveOptions,\n validators,\n} from '@dynamic-field-kit/core';\nexport type { ValidationResult } from '@dynamic-field-kit/core';\n\n// Scoped registry: provide FIELD_REGISTRY on a component/route to give that\n// subtree an isolated set of renderers.\nexport { FIELD_REGISTRY } from './fieldRegistryToken';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/ng-package.json
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChangeDetectorRef,
|
|
3
|
-
Component,
|
|
4
|
-
EventEmitter,
|
|
5
|
-
Input,
|
|
6
|
-
OnChanges,
|
|
7
|
-
Output,
|
|
8
|
-
SimpleChanges,
|
|
9
|
-
} from '@angular/core';
|
|
10
|
-
|
|
11
|
-
// Mirrors the framework-agnostic FieldRendererProps. Domain-specific inputs
|
|
12
|
-
// (acceptFile, maxLength, ...) intentionally live on the individual renderer,
|
|
13
|
-
// not here - pass them per field via FieldDescription.props instead.
|
|
14
|
-
export interface FieldInputProps {
|
|
15
|
-
value?: unknown;
|
|
16
|
-
label?: string;
|
|
17
|
-
placeholder?: string;
|
|
18
|
-
required?: boolean;
|
|
19
|
-
disabled?: boolean;
|
|
20
|
-
readOnly?: boolean;
|
|
21
|
-
error?: string | string[];
|
|
22
|
-
options?: unknown[];
|
|
23
|
-
className?: string;
|
|
24
|
-
description?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@Component({
|
|
28
|
-
template: '',
|
|
29
|
-
})
|
|
30
|
-
export abstract class BaseInputComponent implements OnChanges {
|
|
31
|
-
@Input() value?: unknown;
|
|
32
|
-
@Input() label?: string;
|
|
33
|
-
@Input() placeholder?: string;
|
|
34
|
-
@Input() required?: boolean;
|
|
35
|
-
@Input() disabled?: boolean;
|
|
36
|
-
@Input() readOnly?: boolean;
|
|
37
|
-
@Input() error?: string | string[];
|
|
38
|
-
@Input() options?: unknown[];
|
|
39
|
-
@Input() className?: string;
|
|
40
|
-
@Input() description?: string;
|
|
41
|
-
|
|
42
|
-
@Output() valueChange = new EventEmitter<unknown>();
|
|
43
|
-
|
|
44
|
-
constructor(protected cdr: ChangeDetectorRef) {}
|
|
45
|
-
|
|
46
|
-
ngOnChanges(_changes: SimpleChanges): void {
|
|
47
|
-
this.detectChanges();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
protected detectChanges(): void {
|
|
51
|
-
this.cdr.markForCheck();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
protected hasChanges(changes: SimpleChanges, prop: string): boolean {
|
|
55
|
-
return changes[prop] !== undefined;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { CommonModule } from '@angular/common';
|
|
2
|
-
import {
|
|
3
|
-
AfterViewInit,
|
|
4
|
-
ChangeDetectionStrategy,
|
|
5
|
-
Component,
|
|
6
|
-
ComponentRef,
|
|
7
|
-
EventEmitter,
|
|
8
|
-
inject,
|
|
9
|
-
Input,
|
|
10
|
-
OnChanges,
|
|
11
|
-
OnDestroy,
|
|
12
|
-
Output,
|
|
13
|
-
SimpleChanges,
|
|
14
|
-
Type,
|
|
15
|
-
ViewChild,
|
|
16
|
-
ViewContainerRef,
|
|
17
|
-
} from '@angular/core';
|
|
18
|
-
import { FieldTypeKey, Properties } from '@dynamic-field-kit/core';
|
|
19
|
-
import { Subscription } from 'rxjs';
|
|
20
|
-
import { FIELD_REGISTRY } from '../fieldRegistryToken';
|
|
21
|
-
import { BaseInputComponent } from './BaseInput';
|
|
22
|
-
|
|
23
|
-
// Only the framework-agnostic FieldRendererProps keys. Domain-specific props
|
|
24
|
-
// reach the renderer through `extraProps` (FieldDescription.props) instead.
|
|
25
|
-
const KNOWN_PROPS = [
|
|
26
|
-
'value',
|
|
27
|
-
'label',
|
|
28
|
-
'placeholder',
|
|
29
|
-
'required',
|
|
30
|
-
'disabled',
|
|
31
|
-
'readOnly',
|
|
32
|
-
'error',
|
|
33
|
-
'options',
|
|
34
|
-
'className',
|
|
35
|
-
'description',
|
|
36
|
-
] as const;
|
|
37
|
-
|
|
38
|
-
@Component({
|
|
39
|
-
selector: 'dfk-dynamic-input',
|
|
40
|
-
standalone: true,
|
|
41
|
-
imports: [CommonModule],
|
|
42
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
43
|
-
template: `<div #host style="display: contents;"></div>`,
|
|
44
|
-
})
|
|
45
|
-
export class DynamicInput
|
|
46
|
-
extends BaseInputComponent
|
|
47
|
-
implements OnChanges, AfterViewInit, OnDestroy
|
|
48
|
-
{
|
|
49
|
-
@Input() type!: FieldTypeKey;
|
|
50
|
-
// Extra, framework-agnostic props forwarded verbatim to the renderer.
|
|
51
|
-
@Input() extraProps?: Properties;
|
|
52
|
-
@Output() override valueChange = new EventEmitter<unknown>();
|
|
53
|
-
@Output() onChange = new EventEmitter<unknown>();
|
|
54
|
-
|
|
55
|
-
private registry = inject(FIELD_REGISTRY);
|
|
56
|
-
|
|
57
|
-
@ViewChild('host', { read: ViewContainerRef, static: false })
|
|
58
|
-
host!: ViewContainerRef;
|
|
59
|
-
private compRef?: ComponentRef<unknown>;
|
|
60
|
-
private inputInstance?: unknown;
|
|
61
|
-
private subscriptions: Subscription[] = [];
|
|
62
|
-
// Tracks which KNOWN_PROPS were actually supplied to DynamicInput (via
|
|
63
|
-
// SimpleChanges), independent of TS class-field emit. See applyProps.
|
|
64
|
-
private supplied = new Set<string>();
|
|
65
|
-
|
|
66
|
-
ngOnChanges(changes: SimpleChanges): void {
|
|
67
|
-
super.ngOnChanges(changes);
|
|
68
|
-
|
|
69
|
-
for (const prop of KNOWN_PROPS) {
|
|
70
|
-
if (changes[prop]) {
|
|
71
|
-
this.supplied.add(prop);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (this.inputInstance) {
|
|
76
|
-
this.syncPropsToInstance(changes);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (changes['type'] && !changes['type'].firstChange && this.host) {
|
|
80
|
-
this.render();
|
|
81
|
-
} else if (!this.inputInstance && this.host) {
|
|
82
|
-
this.render();
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
ngAfterViewInit(): void {
|
|
87
|
-
this.render();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
ngOnDestroy(): void {
|
|
91
|
-
this.cleanup();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private syncPropsToInstance(changes: SimpleChanges): void {
|
|
95
|
-
if (!this.inputInstance) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
for (const prop of KNOWN_PROPS) {
|
|
100
|
-
if (changes[prop] && this.inputInstance) {
|
|
101
|
-
(this.inputInstance as Record<string, unknown>)[prop] = (
|
|
102
|
-
this as Record<string, unknown>
|
|
103
|
-
)[prop];
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (changes['extraProps']) {
|
|
107
|
-
this.applyExtraProps(this.inputInstance);
|
|
108
|
-
}
|
|
109
|
-
this.compRef?.changeDetectorRef?.detectChanges();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private cleanup(): void {
|
|
113
|
-
this.cleanupSubscriptions();
|
|
114
|
-
this.cleanupRenderedComponent();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private cleanupSubscriptions(): void {
|
|
118
|
-
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
119
|
-
this.subscriptions = [];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private cleanupRenderedComponent(): void {
|
|
123
|
-
this.compRef?.destroy();
|
|
124
|
-
this.compRef = undefined;
|
|
125
|
-
this.inputInstance = undefined;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private render(): void {
|
|
129
|
-
const Renderer = this.registry.get(this.type);
|
|
130
|
-
this.cleanup();
|
|
131
|
-
this.host.clear();
|
|
132
|
-
|
|
133
|
-
if (!Renderer) {
|
|
134
|
-
this.renderError(`Unknown field type: ${this.type}`);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (this.isComponentType(Renderer)) {
|
|
139
|
-
this.renderComponent(Renderer as unknown as Type<unknown>);
|
|
140
|
-
} else if (typeof Renderer === 'function') {
|
|
141
|
-
this.renderFallback(Renderer);
|
|
142
|
-
} else {
|
|
143
|
-
this.renderError(`Invalid renderer for type: ${this.type}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Angular component classes carry a static ɵcmp. Checked instead of
|
|
148
|
-
// reflectComponentType() because the peer range starts at Angular 13 and
|
|
149
|
-
// reflectComponentType is v14+. Plain function renderers have no ɵcmp and
|
|
150
|
-
// fall through to renderFallback. Uses hasOwnProperty (not `in`) so a
|
|
151
|
-
// class that merely extends a component without its own @Component
|
|
152
|
-
// decorator - and would otherwise inherit the parent's static ɵcmp via the
|
|
153
|
-
// prototype chain - is not mistaken for a component in its own right.
|
|
154
|
-
private isComponentType(renderer: unknown): boolean {
|
|
155
|
-
return (
|
|
156
|
-
typeof renderer === 'function' &&
|
|
157
|
-
Object.prototype.hasOwnProperty.call(renderer, 'ɵcmp')
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private renderComponent(compType: Type<unknown>): void {
|
|
162
|
-
try {
|
|
163
|
-
const compRef = this.host.createComponent(compType);
|
|
164
|
-
const instance = compRef.instance;
|
|
165
|
-
|
|
166
|
-
if (!instance) {
|
|
167
|
-
this.renderError(`Failed to create instance for ${this.type}`);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
this.applyProps(instance);
|
|
172
|
-
this.bindOutputs(instance);
|
|
173
|
-
|
|
174
|
-
this.compRef = compRef;
|
|
175
|
-
this.inputInstance = instance;
|
|
176
|
-
compRef.changeDetectorRef.detectChanges();
|
|
177
|
-
} catch {
|
|
178
|
-
this.renderError(`Failed to render field: ${this.type}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
private renderFallback(renderer: unknown): void {
|
|
183
|
-
try {
|
|
184
|
-
const props = this.getFallbackProps();
|
|
185
|
-
const result = (renderer as (props: unknown) => string)(props);
|
|
186
|
-
|
|
187
|
-
if (typeof result === 'string') {
|
|
188
|
-
const el = document.createElement('div');
|
|
189
|
-
el.innerHTML = result;
|
|
190
|
-
this.host.element.nativeElement.appendChild(el);
|
|
191
|
-
}
|
|
192
|
-
} catch {
|
|
193
|
-
this.renderError(`Failed to render field: ${this.type}`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private getFallbackProps(): Record<string, unknown> {
|
|
198
|
-
return {
|
|
199
|
-
...this.extraProps,
|
|
200
|
-
value: this.value,
|
|
201
|
-
onValueChange: (v: unknown) => this.emitValue(v),
|
|
202
|
-
label: this.label ?? '',
|
|
203
|
-
placeholder: this.placeholder ?? '',
|
|
204
|
-
required: this.required ?? false,
|
|
205
|
-
disabled: this.disabled ?? false,
|
|
206
|
-
readOnly: this.readOnly ?? false,
|
|
207
|
-
error: this.error,
|
|
208
|
-
options: this.options ?? [],
|
|
209
|
-
className: this.className ?? '',
|
|
210
|
-
description: this.description ?? '',
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Gates on `this.supplied` (populated from SimpleChanges in ngOnChanges),
|
|
215
|
-
// not on `prop in instanceObj` or `prop in this`. Both `in` checks test a
|
|
216
|
-
// TypeScript class-field emit artifact rather than intent: whether a
|
|
217
|
-
// property slot exists at runtime depends on the compile target
|
|
218
|
-
// (useDefineForClassFields is false below ES2022, true at ES2022+), so the
|
|
219
|
-
// same source can behave oppositely between this package's test build and
|
|
220
|
-
// its shipped ES2022 bundle, where every declared field is always an own
|
|
221
|
-
// property. `this.supplied` instead reflects only whether Angular ever
|
|
222
|
-
// fired a SimpleChange for that input, i.e. whether the prop was *bound*
|
|
223
|
-
// at all - it skips only props DynamicInput was never given a binding
|
|
224
|
-
// for. It is NOT a general "renderer defaults survive" guarantee: Angular
|
|
225
|
-
// fires a firstChange SimpleChange for every bound input even when the
|
|
226
|
-
// bound value is undefined, and FieldInput's template binds all
|
|
227
|
-
// KNOWN_PROPS unconditionally, so on the real
|
|
228
|
-
// MultiFieldInput -> FieldInput -> DynamicInput path every prop counts as
|
|
229
|
-
// supplied and renderer-side defaults (e.g. `@Input() label = 'None'`)
|
|
230
|
-
// are still overwritten with undefined. This only helps when DynamicInput
|
|
231
|
-
// is mounted directly with some inputs left unbound.
|
|
232
|
-
private applyProps(instance: unknown): void {
|
|
233
|
-
const instanceObj = instance as Record<string, unknown>;
|
|
234
|
-
for (const prop of KNOWN_PROPS) {
|
|
235
|
-
if (this.supplied.has(prop)) {
|
|
236
|
-
instanceObj[prop] = (this as Record<string, unknown>)[prop];
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
this.applyExtraProps(instance);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
private applyExtraProps(instance: unknown): void {
|
|
243
|
-
if (!instance || !this.extraProps) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
const instanceObj = instance as Record<string, unknown>;
|
|
247
|
-
for (const [key, value] of Object.entries(this.extraProps)) {
|
|
248
|
-
instanceObj[key] = value;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
private bindOutputs(instance: unknown): void {
|
|
253
|
-
const outputNames: Array<'valueChange' | 'onValueChange'> = [
|
|
254
|
-
'valueChange',
|
|
255
|
-
'onValueChange',
|
|
256
|
-
];
|
|
257
|
-
|
|
258
|
-
for (const outputName of outputNames) {
|
|
259
|
-
const output = (instance as Record<string, unknown>)[outputName];
|
|
260
|
-
if (output && typeof output === 'object' && 'subscribe' in output) {
|
|
261
|
-
const sub = (
|
|
262
|
-
output as { subscribe: (cb: (v: unknown) => void) => Subscription }
|
|
263
|
-
).subscribe((value: unknown) => this.emitValue(value));
|
|
264
|
-
this.subscriptions.push(sub);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
private emitValue(value: unknown): void {
|
|
270
|
-
this.valueChange.emit(value);
|
|
271
|
-
this.onChange.emit(value);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
private renderError(message: string): void {
|
|
275
|
-
const el = document.createElement('div');
|
|
276
|
-
el.textContent = message;
|
|
277
|
-
el.style.color = 'red';
|
|
278
|
-
this.host.element.nativeElement.appendChild(el);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { NgIf } from '@angular/common';
|
|
2
|
-
import {
|
|
3
|
-
ChangeDetectionStrategy,
|
|
4
|
-
ChangeDetectorRef,
|
|
5
|
-
Component,
|
|
6
|
-
EventEmitter,
|
|
7
|
-
Input,
|
|
8
|
-
OnChanges,
|
|
9
|
-
Output,
|
|
10
|
-
SimpleChanges,
|
|
11
|
-
} from '@angular/core';
|
|
12
|
-
import { FieldDescription } from '@dynamic-field-kit/core';
|
|
13
|
-
import { DynamicInput } from './DynamicInput';
|
|
14
|
-
|
|
15
|
-
@Component({
|
|
16
|
-
selector: 'dfk-field-input',
|
|
17
|
-
standalone: true,
|
|
18
|
-
imports: [NgIf, DynamicInput],
|
|
19
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
20
|
-
template: `
|
|
21
|
-
<dfk-dynamic-input
|
|
22
|
-
*ngIf="shouldRender"
|
|
23
|
-
[type]="fieldDescription!.type"
|
|
24
|
-
[value]="value"
|
|
25
|
-
[label]="fieldDescription!.label"
|
|
26
|
-
[placeholder]="fieldDescription!.placeholder"
|
|
27
|
-
[required]="fieldDescription!.required"
|
|
28
|
-
[description]="$any(fieldDescription!.description)"
|
|
29
|
-
[options]="resolvedOptions"
|
|
30
|
-
[className]="fieldDescription!.className"
|
|
31
|
-
(valueChange)="
|
|
32
|
-
onValueChangeField.emit({ value: $event, key: fieldDescription!.name })
|
|
33
|
-
"
|
|
34
|
-
[disabled]="disabled"
|
|
35
|
-
[readOnly]="readOnly"
|
|
36
|
-
[error]="$any(error)"
|
|
37
|
-
[extraProps]="fieldDescription!.props"
|
|
38
|
-
></dfk-dynamic-input>
|
|
39
|
-
`,
|
|
40
|
-
})
|
|
41
|
-
export class FieldInput implements OnChanges {
|
|
42
|
-
@Input() fieldDescription?: FieldDescription;
|
|
43
|
-
@Input() value?: unknown;
|
|
44
|
-
@Input() options?: Record<string, unknown>[];
|
|
45
|
-
@Input() disabled?: boolean;
|
|
46
|
-
@Input() readOnly?: boolean;
|
|
47
|
-
@Input() error?: string | string[];
|
|
48
|
-
@Output() onValueChangeField = new EventEmitter<{
|
|
49
|
-
value: unknown;
|
|
50
|
-
key: string;
|
|
51
|
-
}>();
|
|
52
|
-
|
|
53
|
-
shouldRender = false;
|
|
54
|
-
|
|
55
|
-
get resolvedOptions(): Record<string, unknown>[] | undefined {
|
|
56
|
-
if (this.options) {
|
|
57
|
-
return this.options;
|
|
58
|
-
}
|
|
59
|
-
if (!this.fieldDescription?.options) {
|
|
60
|
-
return undefined;
|
|
61
|
-
}
|
|
62
|
-
if (typeof this.fieldDescription.options === 'function') {
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
return this.fieldDescription.options;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
constructor(private cdr: ChangeDetectorRef) {}
|
|
69
|
-
|
|
70
|
-
ngOnChanges(_changes: SimpleChanges): void {
|
|
71
|
-
this.shouldRender = !!this.fieldDescription;
|
|
72
|
-
this.cdr.markForCheck();
|
|
73
|
-
}
|
|
74
|
-
}
|