@dynamic-field-kit/angular 1.3.3 → 1.4.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +50 -3
  3. package/dist/README.md +50 -3
  4. package/dist/components/BaseInput.d.ts +5 -11
  5. package/dist/components/DynamicInput.d.ts +6 -2
  6. package/dist/components/FieldInput.d.ts +6 -2
  7. package/dist/components/MultiFieldInput.d.ts +10 -1
  8. package/dist/esm2022/components/BaseInput.mjs +8 -17
  9. package/dist/esm2022/components/DynamicInput.mjs +67 -14
  10. package/dist/esm2022/components/FieldInput.mjs +39 -20
  11. package/dist/esm2022/components/MultiFieldInput.mjs +87 -13
  12. package/dist/esm2022/fieldRegistryToken.mjs +12 -0
  13. package/dist/esm2022/public-api.mjs +6 -2
  14. package/dist/esm2022/types/layout.mjs +1 -1
  15. package/dist/fesm2022/dynamic-field-kit-angular.mjs +208 -61
  16. package/dist/fesm2022/dynamic-field-kit-angular.mjs.map +1 -1
  17. package/dist/fieldRegistryToken.d.ts +3 -0
  18. package/dist/public-api.d.ts +4 -1
  19. package/dist/types/layout.d.ts +4 -25
  20. package/package.json +14 -16
  21. package/src/components/BaseInput.ts +7 -10
  22. package/src/components/DynamicInput.ts +67 -11
  23. package/src/components/FieldInput.ts +23 -16
  24. package/src/components/MultiFieldInput.ts +101 -8
  25. package/src/fieldRegistryToken.ts +15 -0
  26. package/src/public-api.ts +40 -24
  27. package/src/types/layout.ts +14 -36
  28. package/test/DynamicInput.spec.ts +217 -17
  29. package/test/FieldInput.spec.ts +131 -29
  30. package/test/MultiFieldInput.spec.ts +256 -0
  31. package/test/helpers/renderers.ts +89 -0
  32. package/test/layout.spec.ts +119 -0
  33. package/test/publicApi.spec.ts +64 -0
  34. package/{test.ts → test/setup.ts} +2 -2
  35. package/test/smoke.spec.ts +27 -0
  36. package/tsconfig.json +13 -13
  37. package/tsconfig.spec.json +4 -16
  38. package/vitest.config.ts +30 -0
  39. package/angular.json +0 -27
  40. package/karma.conf.js +0 -37
  41. package/test/angular.spec.ts +0 -102
  42. package/test/integration.spec.ts +0 -57
  43. package/test/layouts.spec.ts +0 -26
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # @dynamic-field-kit/angular
2
+
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 132f74b: Framework adapters: validation support, scoped field registries via dependency
8
+ injection, and unified cross-framework layout types.
9
+
10
+ - Validation wired through `DynamicInput` / `FieldInput` / `MultiFieldInput`.
11
+ - Scoped `FieldRegistry` injection (React context, Vue provide/inject, Angular
12
+ `FIELD_REGISTRY` token) so consumers can supply their own registry.
13
+ - Shared layout type definitions aligned across React, Vue, and Angular.
14
+
15
+ Requires `@dynamic-field-kit/core@^1.3.0` (peer dependency) for the new
16
+ validation and layout APIs.
17
+
18
+ Note: `@dynamic-field-kit/core` is a peer dependency (not bundled). Consumers
19
+ must install it alongside the adapter.
package/README.md CHANGED
@@ -12,9 +12,7 @@ Demo app: https://github.com/vannt-dev/dynamic-field-kit-demo
12
12
  npm install @dynamic-field-kit/core @dynamic-field-kit/angular
13
13
  ```
14
14
 
15
- Note: Core is shared runtime. Install core separately and ensure a single version is used across adapters to avoid duplicate registries.
16
-
17
- - Install with core: `npm install @dynamic-field-kit/core @dynamic-field-kit/angular`
15
+ Note: `@dynamic-field-kit/core`, `@angular/core`, and `@angular/common` are **peer dependencies** this adapter does not bundle or auto-install them, so add them to your app explicitly (as shown above). Keep a single `@dynamic-field-kit/core` version across all adapters so they share one registry.
18
16
 
19
17
  If you need to pin versions explicitly:
20
18
 
@@ -29,6 +27,9 @@ npm install @dynamic-field-kit/core@^1.0.12 @dynamic-field-kit/angular@^1.2.3
29
27
  - `MultiFieldInput`
30
28
  - `DynamicFieldKitModule`
31
29
  - `fieldRegistry`
30
+ - `FieldRegistry` (class, for scoped registries)
31
+ - `FIELD_REGISTRY` (injection token)
32
+ - `validateField` / `validateFields` / `resolveDisabled` / `resolveReadOnly` / `ValidationResult`
32
33
 
33
34
  ## Basic setup (Angular 19+)
34
35
 
@@ -124,6 +125,23 @@ fields: FieldDescription[] = [
124
125
  ];
125
126
  ```
126
127
 
128
+ ## Validation & conditions
129
+
130
+ Declare a `validate` hook and dynamic `disabledCondition`/`readOnlyCondition`;
131
+ your renderer component receives `error`, `disabled`, and `readOnly` inputs, and
132
+ `dfk-multi-field-input` emits `(validityChange)`:
133
+
134
+ ```html
135
+ <dfk-multi-field-input
136
+ [fieldDescriptions]="fields"
137
+ [properties]="data"
138
+ (onChange)="onChange($event)"
139
+ (validityChange)="canSubmit = $event.valid"
140
+ ></dfk-multi-field-input>
141
+ ```
142
+
143
+ For submit-time whole-form validation, call `validateFields(fields, data)`.
144
+
127
145
  ## Repeatable field groups
128
146
 
129
147
  A field with `fields` renders as a repeatable group: `data[name]` becomes an array of items, each shaped by the nested `fields`, with "Add"/"Remove" controls rendered automatically.
@@ -139,6 +157,7 @@ fields: FieldDescription[] = [
139
157
  { name: 'phone', type: 'text', label: 'Phone' },
140
158
  ],
141
159
  defaultItem: { email: '', phone: '' },
160
+ keyField: 'id', // optional: stable trackBy key instead of the array index
142
161
  minItems: 1,
143
162
  maxItems: 5,
144
163
  },
@@ -149,6 +168,34 @@ fields: FieldDescription[] = [
149
168
  <dfk-multi-field-input [fieldDescriptions]="fields"></dfk-multi-field-input>
150
169
  ```
151
170
 
171
+ ## Scoped registries
172
+
173
+ `fieldRegistry` is a process-wide singleton. To give a component or route its own renderers, provide the `FIELD_REGISTRY` token with an isolated `FieldRegistry`. Components without an override keep using the global singleton.
174
+
175
+ ```ts
176
+ import { FieldRegistry, FIELD_REGISTRY } from '@dynamic-field-kit/angular';
177
+
178
+ const registry = new FieldRegistry();
179
+ registry.register('text', TextFieldComponent as any);
180
+
181
+ @Component({
182
+ selector: 'app-scoped-form',
183
+ standalone: true,
184
+ imports: [MultiFieldInput],
185
+ providers: [{ provide: FIELD_REGISTRY, useValue: registry }],
186
+ template: `<dfk-multi-field-input [fieldDescriptions]="fields" />`,
187
+ })
188
+ export class ScopedFormComponent {}
189
+ ```
190
+
191
+ ## Passing renderer-specific props
192
+
193
+ The generic adapter forwards only the shared `FieldRendererProps`. For inputs specific to one renderer (e.g. `acceptFile`, `maxLength`), pass them per field via `FieldDescription.props`; they are set on the renderer instance verbatim.
194
+
195
+ ```ts
196
+ { name: 'avatar', type: 'file', props: { acceptFile: 'image/*' } }
197
+ ```
198
+
152
199
  ## Legacy setup (Angular 14 and earlier with NgModule)
153
200
 
154
201
  ```ts
package/dist/README.md CHANGED
@@ -12,9 +12,7 @@ Demo app: https://github.com/vannt-dev/dynamic-field-kit-demo
12
12
  npm install @dynamic-field-kit/core @dynamic-field-kit/angular
13
13
  ```
14
14
 
15
- Note: Core is shared runtime. Install core separately and ensure a single version is used across adapters to avoid duplicate registries.
16
-
17
- - Install with core: `npm install @dynamic-field-kit/core @dynamic-field-kit/angular`
15
+ Note: `@dynamic-field-kit/core`, `@angular/core`, and `@angular/common` are **peer dependencies** this adapter does not bundle or auto-install them, so add them to your app explicitly (as shown above). Keep a single `@dynamic-field-kit/core` version across all adapters so they share one registry.
18
16
 
19
17
  If you need to pin versions explicitly:
20
18
 
@@ -29,6 +27,9 @@ npm install @dynamic-field-kit/core@^1.0.12 @dynamic-field-kit/angular@^1.2.3
29
27
  - `MultiFieldInput`
30
28
  - `DynamicFieldKitModule`
31
29
  - `fieldRegistry`
30
+ - `FieldRegistry` (class, for scoped registries)
31
+ - `FIELD_REGISTRY` (injection token)
32
+ - `validateField` / `validateFields` / `resolveDisabled` / `resolveReadOnly` / `ValidationResult`
32
33
 
33
34
  ## Basic setup (Angular 19+)
34
35
 
@@ -124,6 +125,23 @@ fields: FieldDescription[] = [
124
125
  ];
125
126
  ```
126
127
 
128
+ ## Validation & conditions
129
+
130
+ Declare a `validate` hook and dynamic `disabledCondition`/`readOnlyCondition`;
131
+ your renderer component receives `error`, `disabled`, and `readOnly` inputs, and
132
+ `dfk-multi-field-input` emits `(validityChange)`:
133
+
134
+ ```html
135
+ <dfk-multi-field-input
136
+ [fieldDescriptions]="fields"
137
+ [properties]="data"
138
+ (onChange)="onChange($event)"
139
+ (validityChange)="canSubmit = $event.valid"
140
+ ></dfk-multi-field-input>
141
+ ```
142
+
143
+ For submit-time whole-form validation, call `validateFields(fields, data)`.
144
+
127
145
  ## Repeatable field groups
128
146
 
129
147
  A field with `fields` renders as a repeatable group: `data[name]` becomes an array of items, each shaped by the nested `fields`, with "Add"/"Remove" controls rendered automatically.
@@ -139,6 +157,7 @@ fields: FieldDescription[] = [
139
157
  { name: 'phone', type: 'text', label: 'Phone' },
140
158
  ],
141
159
  defaultItem: { email: '', phone: '' },
160
+ keyField: 'id', // optional: stable trackBy key instead of the array index
142
161
  minItems: 1,
143
162
  maxItems: 5,
144
163
  },
@@ -149,6 +168,34 @@ fields: FieldDescription[] = [
149
168
  <dfk-multi-field-input [fieldDescriptions]="fields"></dfk-multi-field-input>
150
169
  ```
151
170
 
171
+ ## Scoped registries
172
+
173
+ `fieldRegistry` is a process-wide singleton. To give a component or route its own renderers, provide the `FIELD_REGISTRY` token with an isolated `FieldRegistry`. Components without an override keep using the global singleton.
174
+
175
+ ```ts
176
+ import { FieldRegistry, FIELD_REGISTRY } from '@dynamic-field-kit/angular';
177
+
178
+ const registry = new FieldRegistry();
179
+ registry.register('text', TextFieldComponent as any);
180
+
181
+ @Component({
182
+ selector: 'app-scoped-form',
183
+ standalone: true,
184
+ imports: [MultiFieldInput],
185
+ providers: [{ provide: FIELD_REGISTRY, useValue: registry }],
186
+ template: `<dfk-multi-field-input [fieldDescriptions]="fields" />`,
187
+ })
188
+ export class ScopedFormComponent {}
189
+ ```
190
+
191
+ ## Passing renderer-specific props
192
+
193
+ The generic adapter forwards only the shared `FieldRendererProps`. For inputs specific to one renderer (e.g. `acceptFile`, `maxLength`), pass them per field via `FieldDescription.props`; they are set on the renderer instance verbatim.
194
+
195
+ ```ts
196
+ { name: 'avatar', type: 'file', props: { acceptFile: 'image/*' } }
197
+ ```
198
+
152
199
  ## Legacy setup (Angular 14 and earlier with NgModule)
153
200
 
154
201
  ```ts
@@ -6,14 +6,11 @@ export interface FieldInputProps {
6
6
  placeholder?: string;
7
7
  required?: boolean;
8
8
  disabled?: boolean;
9
+ readOnly?: boolean;
10
+ error?: string | string[];
9
11
  options?: unknown[];
10
12
  className?: string;
11
13
  description?: string;
12
- errorMessage?: string;
13
- acceptFile?: string;
14
- maxLength?: number;
15
- minNumber?: number;
16
- maxNumber?: number;
17
14
  }
18
15
  export declare abstract class BaseInputComponent implements OnChanges {
19
16
  protected cdr: ChangeDetectorRef;
@@ -22,19 +19,16 @@ export declare abstract class BaseInputComponent implements OnChanges {
22
19
  placeholder?: string;
23
20
  required?: boolean;
24
21
  disabled?: boolean;
22
+ readOnly?: boolean;
23
+ error?: string | string[];
25
24
  options?: unknown[];
26
25
  className?: string;
27
26
  description?: string;
28
- errorMessage?: string;
29
- acceptFile?: string;
30
- maxLength?: number;
31
- minNumber?: number;
32
- maxNumber?: number;
33
27
  valueChange: EventEmitter<unknown>;
34
28
  constructor(cdr: ChangeDetectorRef);
35
29
  ngOnChanges(_changes: SimpleChanges): void;
36
30
  protected detectChanges(): void;
37
31
  protected hasChanges(changes: SimpleChanges, prop: string): boolean;
38
32
  static ɵfac: i0.ɵɵFactoryDeclaration<BaseInputComponent, never>;
39
- static ɵcmp: i0.ɵɵComponentDeclaration<BaseInputComponent, "ng-component", never, { "value": { "alias": "value"; "required": false; }; "label": { "alias": "label"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "options": { "alias": "options"; "required": false; }; "className": { "alias": "className"; "required": false; }; "description": { "alias": "description"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; "acceptFile": { "alias": "acceptFile"; "required": false; }; "maxLength": { "alias": "maxLength"; "required": false; }; "minNumber": { "alias": "minNumber"; "required": false; }; "maxNumber": { "alias": "maxNumber"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
33
+ static ɵcmp: i0.ɵɵComponentDeclaration<BaseInputComponent, "ng-component", never, { "value": { "alias": "value"; "required": false; }; "label": { "alias": "label"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "error": { "alias": "error"; "required": false; }; "options": { "alias": "options"; "required": false; }; "className": { "alias": "className"; "required": false; }; "description": { "alias": "description"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
40
34
  }
@@ -1,15 +1,18 @@
1
1
  import { AfterViewInit, EventEmitter, OnChanges, OnDestroy, SimpleChanges, ViewContainerRef } from '@angular/core';
2
- import { FieldTypeKey } from '@dynamic-field-kit/core';
2
+ import { FieldTypeKey, Properties } from '@dynamic-field-kit/core';
3
3
  import { BaseInputComponent } from './BaseInput';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare class DynamicInput extends BaseInputComponent implements OnChanges, AfterViewInit, OnDestroy {
6
6
  type: FieldTypeKey;
7
+ extraProps?: Properties;
7
8
  valueChange: EventEmitter<unknown>;
8
9
  onChange: EventEmitter<unknown>;
10
+ private registry;
9
11
  host: ViewContainerRef;
10
12
  private compRef?;
11
13
  private inputInstance?;
12
14
  private subscriptions;
15
+ private supplied;
13
16
  ngOnChanges(changes: SimpleChanges): void;
14
17
  ngAfterViewInit(): void;
15
18
  ngOnDestroy(): void;
@@ -23,9 +26,10 @@ export declare class DynamicInput extends BaseInputComponent implements OnChange
23
26
  private renderFallback;
24
27
  private getFallbackProps;
25
28
  private applyProps;
29
+ private applyExtraProps;
26
30
  private bindOutputs;
27
31
  private emitValue;
28
32
  private renderError;
29
33
  static ɵfac: i0.ɵɵFactoryDeclaration<DynamicInput, never>;
30
- static ɵcmp: i0.ɵɵComponentDeclaration<DynamicInput, "dfk-dynamic-input", never, { "type": { "alias": "type"; "required": false; }; }, { "valueChange": "valueChange"; "onChange": "onChange"; }, never, never, true, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<DynamicInput, "dfk-dynamic-input", never, { "type": { "alias": "type"; "required": false; }; "extraProps": { "alias": "extraProps"; "required": false; }; }, { "valueChange": "valueChange"; "onChange": "onChange"; }, never, never, true, never>;
31
35
  }
@@ -5,14 +5,18 @@ export declare class FieldInput implements OnChanges {
5
5
  private cdr;
6
6
  fieldDescription?: FieldDescription;
7
7
  value?: unknown;
8
+ options?: Record<string, unknown>[];
9
+ disabled?: boolean;
10
+ readOnly?: boolean;
11
+ error?: string | string[];
8
12
  onValueChangeField: EventEmitter<{
9
13
  value: unknown;
10
14
  key: string;
11
15
  }>;
12
16
  shouldRender: boolean;
17
+ get resolvedOptions(): Record<string, unknown>[] | undefined;
13
18
  constructor(cdr: ChangeDetectorRef);
14
19
  ngOnChanges(_changes: SimpleChanges): void;
15
- getFieldValue(): unknown;
16
20
  static ɵfac: i0.ɵɵFactoryDeclaration<FieldInput, never>;
17
- static ɵcmp: i0.ɵɵComponentDeclaration<FieldInput, "dfk-field-input", never, { "fieldDescription": { "alias": "fieldDescription"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, { "onValueChangeField": "onValueChangeField"; }, never, never, true, never>;
21
+ static ɵcmp: i0.ɵɵComponentDeclaration<FieldInput, "dfk-field-input", never, { "fieldDescription": { "alias": "fieldDescription"; "required": false; }; "value": { "alias": "value"; "required": false; }; "options": { "alias": "options"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "error": { "alias": "error"; "required": false; }; }, { "onValueChangeField": "onValueChangeField"; }, never, never, true, never>;
18
22
  }
@@ -1,5 +1,6 @@
1
1
  import { ChangeDetectorRef, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
2
2
  import { FieldDescription, Properties } from '@dynamic-field-kit/core';
3
+ import type { ValidationResult } from '@dynamic-field-kit/core';
3
4
  import { BaseLayoutConfig, LayoutConfig } from '../types/layout';
4
5
  import * as i0 from "@angular/core";
5
6
  export declare class MultiFieldInput implements OnInit, OnChanges {
@@ -7,7 +8,9 @@ export declare class MultiFieldInput implements OnInit, OnChanges {
7
8
  fieldDescriptions: FieldDescription[];
8
9
  properties?: Properties;
9
10
  onChange: EventEmitter<Properties>;
11
+ validityChange: EventEmitter<ValidationResult>;
10
12
  layout: LayoutConfig;
13
+ rootData?: Properties;
11
14
  data: Properties;
12
15
  visibleFields: FieldDescription[];
13
16
  private isMobile;
@@ -19,6 +22,8 @@ export declare class MultiFieldInput implements OnInit, OnChanges {
19
22
  get columns(): number;
20
23
  trackByFn(index: number, field: FieldDescription): string | number;
21
24
  trackByIndex(index: number): number;
25
+ private groupTrackByCache;
26
+ groupTrackBy(field: FieldDescription): (index: number, item: Properties) => unknown;
22
27
  ngOnInit(): void;
23
28
  ngOnChanges(_changes: SimpleChanges): void;
24
29
  private updateIsMobile;
@@ -29,6 +34,10 @@ export declare class MultiFieldInput implements OnInit, OnChanges {
29
34
  key: string;
30
35
  }): void;
31
36
  getItems(field: FieldDescription): Properties[];
37
+ getResolvedOptions(field: FieldDescription): Properties[] | undefined;
38
+ getDisabled(field: FieldDescription): boolean;
39
+ getReadOnly(field: FieldDescription): boolean;
40
+ getError(field: FieldDescription): string[] | undefined;
32
41
  canAddItem(field: FieldDescription): boolean;
33
42
  canRemoveItem(field: FieldDescription): boolean;
34
43
  onGroupItemAdd(field: FieldDescription): void;
@@ -36,5 +45,5 @@ export declare class MultiFieldInput implements OnInit, OnChanges {
36
45
  onGroupItemChange(field: FieldDescription, index: number, next: Properties): void;
37
46
  private commitData;
38
47
  static ɵfac: i0.ɵɵFactoryDeclaration<MultiFieldInput, never>;
39
- static ɵcmp: i0.ɵɵComponentDeclaration<MultiFieldInput, "dfk-multi-field-input", never, { "fieldDescriptions": { "alias": "fieldDescriptions"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; }, { "onChange": "onChange"; }, never, never, true, never>;
48
+ static ɵcmp: i0.ɵɵComponentDeclaration<MultiFieldInput, "dfk-multi-field-input", never, { "fieldDescriptions": { "alias": "fieldDescriptions"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "rootData": { "alias": "rootData"; "required": false; }; }, { "onChange": "onChange"; "validityChange": "validityChange"; }, never, never, true, never>;
40
49
  }
@@ -7,14 +7,11 @@ export class BaseInputComponent {
7
7
  placeholder;
8
8
  required;
9
9
  disabled;
10
+ readOnly;
11
+ error;
10
12
  options;
11
13
  className;
12
14
  description;
13
- errorMessage;
14
- acceptFile;
15
- maxLength;
16
- minNumber;
17
- maxNumber;
18
15
  valueChange = new EventEmitter();
19
16
  constructor(cdr) {
20
17
  this.cdr = cdr;
@@ -29,7 +26,7 @@ export class BaseInputComponent {
29
26
  return changes[prop] !== undefined;
30
27
  }
31
28
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: BaseInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
32
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: BaseInputComponent, isStandalone: true, selector: "ng-component", inputs: { value: "value", label: "label", placeholder: "placeholder", required: "required", disabled: "disabled", options: "options", className: "className", description: "description", errorMessage: "errorMessage", acceptFile: "acceptFile", maxLength: "maxLength", minNumber: "minNumber", maxNumber: "maxNumber" }, outputs: { valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true });
29
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: BaseInputComponent, isStandalone: true, selector: "ng-component", inputs: { value: "value", label: "label", placeholder: "placeholder", required: "required", disabled: "disabled", readOnly: "readOnly", error: "error", options: "options", className: "className", description: "description" }, outputs: { valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true });
33
30
  }
34
31
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: BaseInputComponent, decorators: [{
35
32
  type: Component,
@@ -46,23 +43,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
46
43
  type: Input
47
44
  }], disabled: [{
48
45
  type: Input
46
+ }], readOnly: [{
47
+ type: Input
48
+ }], error: [{
49
+ type: Input
49
50
  }], options: [{
50
51
  type: Input
51
52
  }], className: [{
52
53
  type: Input
53
54
  }], description: [{
54
55
  type: Input
55
- }], errorMessage: [{
56
- type: Input
57
- }], acceptFile: [{
58
- type: Input
59
- }], maxLength: [{
60
- type: Input
61
- }], minNumber: [{
62
- type: Input
63
- }], maxNumber: [{
64
- type: Input
65
56
  }], valueChange: [{
66
57
  type: Output
67
58
  }] } });
68
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmFzZUlucHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvQmFzZUlucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7O0FBcUJ2QixNQUFNLE9BQWdCLGtCQUFrQjtJQWlCaEI7SUFoQmIsS0FBSyxDQUFXO0lBQ2hCLEtBQUssQ0FBVTtJQUNmLFdBQVcsQ0FBVTtJQUNyQixRQUFRLENBQVc7SUFDbkIsUUFBUSxDQUFXO0lBQ25CLE9BQU8sQ0FBYTtJQUNwQixTQUFTLENBQVU7SUFDbkIsV0FBVyxDQUFVO0lBQ3JCLFlBQVksQ0FBVTtJQUN0QixVQUFVLENBQVU7SUFDcEIsU0FBUyxDQUFVO0lBQ25CLFNBQVMsQ0FBVTtJQUNuQixTQUFTLENBQVU7SUFFbEIsV0FBVyxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7SUFFcEQsWUFBc0IsR0FBc0I7UUFBdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7SUFBRyxDQUFDO0lBRWhELFdBQVcsQ0FBQyxRQUF1QjtRQUNqQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVTLGFBQWE7UUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRVMsVUFBVSxDQUFDLE9BQXNCLEVBQUUsSUFBWTtRQUN2RCxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxTQUFTLENBQUM7SUFDckMsQ0FBQzt3R0E3Qm1CLGtCQUFrQjs0RkFBbEIsa0JBQWtCLGtjQUY1QixFQUFFOzs0RkFFUSxrQkFBa0I7a0JBSHZDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLEVBQUU7aUJBQ2I7c0ZBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFFSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpZWxkSW5wdXRQcm9wcyB7XG4gIHZhbHVlPzogdW5rbm93bjtcbiAgbGFiZWw/OiBzdHJpbmc7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICByZXF1aXJlZD86IGJvb2xlYW47XG4gIGRpc2FibGVkPzogYm9vbGVhbjtcbiAgb3B0aW9ucz86IHVua25vd25bXTtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgZXJyb3JNZXNzYWdlPzogc3RyaW5nO1xuICBhY2NlcHRGaWxlPzogc3RyaW5nO1xuICBtYXhMZW5ndGg/OiBudW1iZXI7XG4gIG1pbk51bWJlcj86IG51bWJlcjtcbiAgbWF4TnVtYmVyPzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGU6ICcnLFxufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlSW5wdXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKSB2YWx1ZT86IHVua25vd247XG4gIEBJbnB1dCgpIGxhYmVsPzogc3RyaW5nO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcj86IHN0cmluZztcbiAgQElucHV0KCkgcmVxdWlyZWQ/OiBib29sZWFuO1xuICBASW5wdXQoKSBkaXNhYmxlZD86IGJvb2xlYW47XG4gIEBJbnB1dCgpIG9wdGlvbnM/OiB1bmtub3duW107XG4gIEBJbnB1dCgpIGNsYXNzTmFtZT86IHN0cmluZztcbiAgQElucHV0KCkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGVycm9yTWVzc2FnZT86IHN0cmluZztcbiAgQElucHV0KCkgYWNjZXB0RmlsZT86IHN0cmluZztcbiAgQElucHV0KCkgbWF4TGVuZ3RoPzogbnVtYmVyO1xuICBASW5wdXQoKSBtaW5OdW1iZXI/OiBudW1iZXI7XG4gIEBJbnB1dCgpIG1heE51bWJlcj86IG51bWJlcjtcblxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHVua25vd24+KCk7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdPbkNoYW5nZXMoX2NoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkZXRlY3RDaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhc0NoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcywgcHJvcDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNoYW5nZXNbcHJvcF0gIT09IHVuZGVmaW5lZDtcbiAgfVxufVxuIl19
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmFzZUlucHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvQmFzZUlucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7O0FBcUJ2QixNQUFNLE9BQWdCLGtCQUFrQjtJQWNoQjtJQWJiLEtBQUssQ0FBVztJQUNoQixLQUFLLENBQVU7SUFDZixXQUFXLENBQVU7SUFDckIsUUFBUSxDQUFXO0lBQ25CLFFBQVEsQ0FBVztJQUNuQixRQUFRLENBQVc7SUFDbkIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQWE7SUFDcEIsU0FBUyxDQUFVO0lBQ25CLFdBQVcsQ0FBVTtJQUVwQixXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztJQUVwRCxZQUFzQixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtJQUFHLENBQUM7SUFFaEQsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRVMsYUFBYTtRQUNyQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFUyxVQUFVLENBQUMsT0FBc0IsRUFBRSxJQUFZO1FBQ3ZELE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLFNBQVMsQ0FBQztJQUNyQyxDQUFDO3dHQTFCbUIsa0JBQWtCOzRGQUFsQixrQkFBa0Isd1dBRjVCLEVBQUU7OzRGQUVRLGtCQUFrQjtrQkFIdkMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsRUFBRTtpQkFDYjtzRkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLy8gTWlycm9ycyB0aGUgZnJhbWV3b3JrLWFnbm9zdGljIEZpZWxkUmVuZGVyZXJQcm9wcy4gRG9tYWluLXNwZWNpZmljIGlucHV0c1xuLy8gKGFjY2VwdEZpbGUsIG1heExlbmd0aCwgLi4uKSBpbnRlbnRpb25hbGx5IGxpdmUgb24gdGhlIGluZGl2aWR1YWwgcmVuZGVyZXIsXG4vLyBub3QgaGVyZSAtIHBhc3MgdGhlbSBwZXIgZmllbGQgdmlhIEZpZWxkRGVzY3JpcHRpb24ucHJvcHMgaW5zdGVhZC5cbmV4cG9ydCBpbnRlcmZhY2UgRmllbGRJbnB1dFByb3BzIHtcbiAgdmFsdWU/OiB1bmtub3duO1xuICBsYWJlbD86IHN0cmluZztcbiAgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XG4gIHJlcXVpcmVkPzogYm9vbGVhbjtcbiAgZGlzYWJsZWQ/OiBib29sZWFuO1xuICByZWFkT25seT86IGJvb2xlYW47XG4gIGVycm9yPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIG9wdGlvbnM/OiB1bmtub3duW107XG4gIGNsYXNzTmFtZT86IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZTogJycsXG59KVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VJbnB1dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIHZhbHVlPzogdW5rbm93bjtcbiAgQElucHV0KCkgbGFiZWw/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICBASW5wdXQoKSByZXF1aXJlZD86IGJvb2xlYW47XG4gIEBJbnB1dCgpIGRpc2FibGVkPzogYm9vbGVhbjtcbiAgQElucHV0KCkgcmVhZE9ubHk/OiBib29sZWFuO1xuICBASW5wdXQoKSBlcnJvcj86IHN0cmluZyB8IHN0cmluZ1tdO1xuICBASW5wdXQoKSBvcHRpb25zPzogdW5rbm93bltdO1xuICBASW5wdXQoKSBjbGFzc05hbWU/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIEBPdXRwdXQoKSB2YWx1ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8dW5rbm93bj4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuICBuZ09uQ2hhbmdlcyhfY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFzQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzLCBwcm9wOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gY2hhbmdlc1twcm9wXSAhPT0gdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=