@dynamic-field-kit/angular 1.5.1 → 1.7.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.
- package/CHANGELOG.md +224 -0
- package/README.md +146 -23
- package/dist/fesm2022/dynamic-field-kit-angular.mjs +665 -116
- package/dist/types/dynamic-field-kit-angular.d.ts +404 -0
- package/package.json +25 -26
- package/dist/components/BaseInput.d.ts +0 -34
- package/dist/components/DynamicFormDevTools.d.ts +0 -16
- package/dist/components/DynamicInput.d.ts +0 -36
- package/dist/components/FieldInput.d.ts +0 -28
- package/dist/components/MultiFieldInput.d.ts +0 -60
- package/dist/fieldRegistryToken.d.ts +0 -3
- package/dist/index.d.ts +0 -5
- package/dist/layout/defaultLayouts.d.ts +0 -31
- package/dist/layout/index.d.ts +0 -2
- package/dist/layout/layoutRegistry.d.ts +0 -12
- package/dist/lib/dynamic-field-kit.module.d.ts +0 -11
- package/dist/lib/dynamic-form.store.d.ts +0 -23
- package/dist/public-api.d.ts +0 -14
- package/dist/types/layout.d.ts +0 -4
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnChanges, ChangeDetectorRef, EventEmitter, SimpleChanges, AfterViewInit, OnDestroy, ViewContainerRef, OnInit, TemplateRef, Type, InjectionToken } from '@angular/core';
|
|
3
|
+
import { OptionsStatus, FieldTypeKey, Properties, FieldDescription, ResolvedFieldRendererProps, BaseLayout, ResponsiveLayout, ValidationResult, LayoutConfig, MessageCatalog, FieldRegistry } from '@dynamic-field-kit/core';
|
|
4
|
+
export { ColumnLayoutConfig, FIELD_RENDERER_PROP_KEYS, FieldDescription, FieldRegistry, FieldRendererProps, FieldTypeKey, GridLayoutConfig, LayoutConfig, RowLayoutConfig, ValidationContext, ValidationResult, buildFieldRendererProps, collectFieldPaths, fieldRegistry, indexGroupPathMap, makeErrorId, makeFieldId, resolveDisabled, resolveOptions, resolveReadOnly, validateField, validateFieldAsync, validateFields, validateFieldsAsync, validators } from '@dynamic-field-kit/core';
|
|
5
|
+
import * as i1 from '@angular/common';
|
|
6
|
+
|
|
7
|
+
interface FieldInputProps {
|
|
8
|
+
value?: unknown;
|
|
9
|
+
label?: string;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
readOnly?: boolean;
|
|
14
|
+
touched?: boolean;
|
|
15
|
+
dirty?: boolean;
|
|
16
|
+
error?: string | string[];
|
|
17
|
+
options?: unknown[];
|
|
18
|
+
optionsStatus?: OptionsStatus;
|
|
19
|
+
optionsError?: unknown;
|
|
20
|
+
onOptionsQuery?: (query: string) => void;
|
|
21
|
+
className?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
id?: string;
|
|
24
|
+
ariaInvalid?: boolean;
|
|
25
|
+
ariaDescribedBy?: string;
|
|
26
|
+
ariaRequired?: boolean;
|
|
27
|
+
min?: number | string;
|
|
28
|
+
max?: number | string;
|
|
29
|
+
step?: number | string;
|
|
30
|
+
accept?: string;
|
|
31
|
+
multiple?: boolean;
|
|
32
|
+
}
|
|
33
|
+
declare abstract class BaseInputComponent implements OnChanges {
|
|
34
|
+
protected cdr: ChangeDetectorRef;
|
|
35
|
+
value?: unknown;
|
|
36
|
+
label?: string;
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
required?: boolean;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
readOnly?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the field has been blurred (or marked touched by the form store).
|
|
43
|
+
* Renderers gate error display on this to avoid shouting at a user who has
|
|
44
|
+
* not reached the field yet.
|
|
45
|
+
*/
|
|
46
|
+
touched?: boolean;
|
|
47
|
+
/** Whether the value differs from the one the form opened with. */
|
|
48
|
+
dirty?: boolean;
|
|
49
|
+
error?: string | string[];
|
|
50
|
+
options?: unknown[];
|
|
51
|
+
optionsStatus?: OptionsStatus;
|
|
52
|
+
optionsError?: unknown;
|
|
53
|
+
/** Renderer-driven refetch for a search-remote field. */
|
|
54
|
+
onOptionsQuery?: (query: string) => void;
|
|
55
|
+
className?: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
id?: string;
|
|
58
|
+
ariaInvalid?: boolean;
|
|
59
|
+
ariaDescribedBy?: string;
|
|
60
|
+
ariaRequired?: boolean;
|
|
61
|
+
min?: number | string;
|
|
62
|
+
max?: number | string;
|
|
63
|
+
step?: number | string;
|
|
64
|
+
accept?: string;
|
|
65
|
+
multiple?: boolean;
|
|
66
|
+
valueChange: EventEmitter<unknown>;
|
|
67
|
+
constructor(cdr: ChangeDetectorRef);
|
|
68
|
+
ngOnChanges(_changes: SimpleChanges): void;
|
|
69
|
+
protected detectChanges(): void;
|
|
70
|
+
protected hasChanges(changes: SimpleChanges, prop: string): boolean;
|
|
71
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseInputComponent, never>;
|
|
72
|
+
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; }; "touched": { "alias": "touched"; "required": false; }; "dirty": { "alias": "dirty"; "required": false; }; "error": { "alias": "error"; "required": false; }; "options": { "alias": "options"; "required": false; }; "optionsStatus": { "alias": "optionsStatus"; "required": false; }; "optionsError": { "alias": "optionsError"; "required": false; }; "onOptionsQuery": { "alias": "onOptionsQuery"; "required": false; }; "className": { "alias": "className"; "required": false; }; "description": { "alias": "description"; "required": false; }; "id": { "alias": "id"; "required": false; }; "ariaInvalid": { "alias": "ariaInvalid"; "required": false; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; }; "ariaRequired": { "alias": "ariaRequired"; "required": false; }; "min": { "alias": "min"; "required": false; }; "max": { "alias": "max"; "required": false; }; "step": { "alias": "step"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
declare class DynamicInput extends BaseInputComponent implements OnChanges, AfterViewInit, OnDestroy {
|
|
76
|
+
type: FieldTypeKey;
|
|
77
|
+
extraProps?: Properties;
|
|
78
|
+
valueChange: EventEmitter<unknown>;
|
|
79
|
+
onChange: EventEmitter<unknown>;
|
|
80
|
+
private registry;
|
|
81
|
+
host: ViewContainerRef;
|
|
82
|
+
private compRef?;
|
|
83
|
+
private inputInstance?;
|
|
84
|
+
private subscriptions;
|
|
85
|
+
private supplied;
|
|
86
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
87
|
+
ngAfterViewInit(): void;
|
|
88
|
+
ngOnDestroy(): void;
|
|
89
|
+
private syncPropsToInstance;
|
|
90
|
+
private cleanup;
|
|
91
|
+
private cleanupSubscriptions;
|
|
92
|
+
private cleanupRenderedComponent;
|
|
93
|
+
/** The id `ariaDescribedBy` points at. See core's `makeErrorId`. */
|
|
94
|
+
errorNodeId(): string;
|
|
95
|
+
/** `error` may arrive as a bare string, so index 0 would be a character. */
|
|
96
|
+
firstError(): string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Whether the adapter should render the validation message itself.
|
|
99
|
+
*
|
|
100
|
+
* Asks the registry directly rather than reading a flag set by `render()`:
|
|
101
|
+
* `render()` runs in `ngAfterViewInit`, by which point this template's
|
|
102
|
+
* bindings have already been checked for the pass, and under `OnPush`
|
|
103
|
+
* nothing would mark them dirty again. A registered renderer owns its own
|
|
104
|
+
* error presentation, so only the built-in fallback gets a message here.
|
|
105
|
+
*/
|
|
106
|
+
showDefaultError(): boolean;
|
|
107
|
+
private render;
|
|
108
|
+
private isComponentType;
|
|
109
|
+
private renderComponent;
|
|
110
|
+
private renderFallback;
|
|
111
|
+
private getFallbackProps;
|
|
112
|
+
private applyProps;
|
|
113
|
+
/**
|
|
114
|
+
* Props that are callbacks rather than resolved values, so they are not in
|
|
115
|
+
* `KNOWN_PROPS` / `FIELD_RENDERER_PROP_KEYS` and the loop above never sees
|
|
116
|
+
* them. Without this a renderer declaring `onOptionsQuery` always got
|
|
117
|
+
* `undefined` and could never trigger a search-remote refetch.
|
|
118
|
+
*/
|
|
119
|
+
private applyCallbackProps;
|
|
120
|
+
private applyExtraProps;
|
|
121
|
+
private bindOutputs;
|
|
122
|
+
private emitValue;
|
|
123
|
+
/**
|
|
124
|
+
* Puts the aria flags on whatever control the HTML5 fallback just built.
|
|
125
|
+
*
|
|
126
|
+
* Applied here, once, rather than in each of the fallback's branches: they
|
|
127
|
+
* hand-build an input, textarea, checkbox or select, and every one of them
|
|
128
|
+
* would otherwise need the same four lines. Without this the fallback emits
|
|
129
|
+
* the `{id}-error` node with nothing pointing at it, and
|
|
130
|
+
* `focusFirstInvalidField` - which selects `[aria-invalid="true"]` - still
|
|
131
|
+
* finds nothing on this adapter.
|
|
132
|
+
*
|
|
133
|
+
* `render()` re-runs on every ngOnChanges while the fallback is in use (there
|
|
134
|
+
* is no component instance to sync props into), so this stays current as the
|
|
135
|
+
* field's error comes and goes.
|
|
136
|
+
*/
|
|
137
|
+
private applyFallbackAria;
|
|
138
|
+
private renderDefaultFallbackHTML5;
|
|
139
|
+
private renderError;
|
|
140
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicInput, never>;
|
|
141
|
+
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>;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
declare class FieldInput implements OnChanges, OnDestroy {
|
|
145
|
+
private cdr;
|
|
146
|
+
fieldDescription?: FieldDescription;
|
|
147
|
+
/**
|
|
148
|
+
* Data at this field's own level. Preferred over `value`: the shared
|
|
149
|
+
* `buildFieldRendererProps` needs the surrounding data to resolve
|
|
150
|
+
* `appearCondition`, dynamic options and cross-field validation. When only
|
|
151
|
+
* `value` is bound (mounting this component directly), a one-key object is
|
|
152
|
+
* synthesised from it.
|
|
153
|
+
*/
|
|
154
|
+
data?: Properties;
|
|
155
|
+
/** Top-level form data, for fields nested inside a repeatable group. */
|
|
156
|
+
rootData?: Properties;
|
|
157
|
+
value?: unknown;
|
|
158
|
+
options?: Record<string, unknown>[];
|
|
159
|
+
disabled?: boolean;
|
|
160
|
+
readOnly?: boolean;
|
|
161
|
+
error?: string | string[];
|
|
162
|
+
/** Distinguishes a controlled empty error from an omitted error input. */
|
|
163
|
+
validationControlled: boolean;
|
|
164
|
+
/** Whether the field has been blurred, or marked touched by a form store. */
|
|
165
|
+
touched?: boolean;
|
|
166
|
+
/** Whether the value differs from the one the form opened with. */
|
|
167
|
+
dirty?: boolean;
|
|
168
|
+
/** Per-form-instance id namespace; see core's `makeFieldId`. */
|
|
169
|
+
idPrefix: string;
|
|
170
|
+
onValueChangeField: EventEmitter<{
|
|
171
|
+
value: unknown;
|
|
172
|
+
key: string;
|
|
173
|
+
}>;
|
|
174
|
+
/**
|
|
175
|
+
* Emits this field's name when focus leaves it. Driven by `focusout`, which
|
|
176
|
+
* bubbles, so it works for any renderer without the renderer having to
|
|
177
|
+
* declare a blur output of its own.
|
|
178
|
+
*/
|
|
179
|
+
onBlurField: EventEmitter<string>;
|
|
180
|
+
/**
|
|
181
|
+
* The full renderer prop bag, built once per change-detection pass rather
|
|
182
|
+
* than from one getter per binding - `buildFieldRendererProps` validates the
|
|
183
|
+
* field, and running that ~20 times per pass would be wasteful.
|
|
184
|
+
*/
|
|
185
|
+
rendererProps: ResolvedFieldRendererProps | null;
|
|
186
|
+
constructor(cdr: ChangeDetectorRef);
|
|
187
|
+
private loader?;
|
|
188
|
+
private optionsState?;
|
|
189
|
+
/** Bound into the template so a renderer can drive a search-remote refetch. */
|
|
190
|
+
onOptionsQuery: (query: string) => void;
|
|
191
|
+
ngOnChanges(_changes: SimpleChanges): void;
|
|
192
|
+
ngOnDestroy(): void;
|
|
193
|
+
private syncOptionsLoader;
|
|
194
|
+
private buildProps;
|
|
195
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FieldInput, never>;
|
|
196
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FieldInput, "dfk-field-input", never, { "fieldDescription": { "alias": "fieldDescription"; "required": false; }; "data": { "alias": "data"; "required": false; }; "rootData": { "alias": "rootData"; "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; }; "validationControlled": { "alias": "validationControlled"; "required": false; }; "touched": { "alias": "touched"; "required": false; }; "dirty": { "alias": "dirty"; "required": false; }; "idPrefix": { "alias": "idPrefix"; "required": false; }; }, { "onValueChangeField": "onValueChangeField"; "onBlurField": "onBlurField"; }, never, never, true, never>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
type BaseLayoutConfig = BaseLayout;
|
|
200
|
+
type ResponsiveLayoutConfig = ResponsiveLayout;
|
|
201
|
+
|
|
202
|
+
declare class MultiFieldInput implements OnInit, OnChanges {
|
|
203
|
+
private cdr;
|
|
204
|
+
fieldDescriptions: FieldDescription[];
|
|
205
|
+
properties?: Properties;
|
|
206
|
+
/**
|
|
207
|
+
* The values per-field `dirty` is measured against. Defaults to the first
|
|
208
|
+
* non-`undefined` `properties` this component sees. This adapter has no
|
|
209
|
+
* `form` shorthand, so pass `store.baselineValues()` here to keep `dirty`
|
|
210
|
+
* correct across `store.reset(newValues)`.
|
|
211
|
+
*/
|
|
212
|
+
initialProperties?: Properties;
|
|
213
|
+
onChange: EventEmitter<Properties>;
|
|
214
|
+
validityChange: EventEmitter<ValidationResult>;
|
|
215
|
+
/**
|
|
216
|
+
* Emits a field's name when it loses focus. Touched state is tracked
|
|
217
|
+
* internally either way; this is the hook for driving an external form store
|
|
218
|
+
* - pass `createDynamicFormStore`'s `handleBlur` to get its `touched` map and
|
|
219
|
+
* `validateOnBlur` behaviour.
|
|
220
|
+
*/
|
|
221
|
+
onBlurField: EventEmitter<string>;
|
|
222
|
+
/**
|
|
223
|
+
* Controlled touched map. When bound it is the single source of truth and
|
|
224
|
+
* the internal tracker is bypassed, so `createDynamicFormStore`'s `touched`
|
|
225
|
+
* signal (updated by setFieldTouched/touchAll/handleSubmit, cleared by
|
|
226
|
+
* reset) is what renderers actually see. Leave it unbound to keep the
|
|
227
|
+
* internal, blur-only tracker.
|
|
228
|
+
*/
|
|
229
|
+
touched?: Record<string, boolean>;
|
|
230
|
+
/** Controlled error map; bind the form store's `errors()` signal here. */
|
|
231
|
+
errors?: Record<string, string[]>;
|
|
232
|
+
/** Emits the next touched map whenever a field is blurred. */
|
|
233
|
+
touchedChange: EventEmitter<Record<string, boolean>>;
|
|
234
|
+
/**
|
|
235
|
+
* Namespace for generated field ids: a field renders with
|
|
236
|
+
* `${idPrefix}-${name}`. Defaults to a value unique to this component
|
|
237
|
+
* instance, so two forms containing the same field name do not emit
|
|
238
|
+
* duplicate DOM ids. Bind a fixed string to pin ids (`idPrefix="dfk-field"`
|
|
239
|
+
* restores the pre-1.6 ids), or set `FieldDescription.id` per field.
|
|
240
|
+
*/
|
|
241
|
+
idPrefix?: string;
|
|
242
|
+
private touchedFields;
|
|
243
|
+
private readonly instanceId;
|
|
244
|
+
private firstSeenProperties;
|
|
245
|
+
private indexedErrorsSource?;
|
|
246
|
+
private indexedErrors;
|
|
247
|
+
private indexedTouchedSource?;
|
|
248
|
+
private indexedTouched;
|
|
249
|
+
get effectiveIdPrefix(): string;
|
|
250
|
+
/** The touched map in effect: the controlled input, else the internal one. */
|
|
251
|
+
private get effectiveTouched();
|
|
252
|
+
handleBlurField(fieldName: string): void;
|
|
253
|
+
/** Whether this field has been blurred at least once. */
|
|
254
|
+
isTouched(fieldName: string): boolean;
|
|
255
|
+
/** Whether this field's value differs from the one the form opened with. */
|
|
256
|
+
isFieldDirty(fieldName: string): boolean;
|
|
257
|
+
fieldErrors(fieldName: string): string[] | undefined;
|
|
258
|
+
errorsForItem(fieldName: string, index: number): Record<string, string[]> | undefined;
|
|
259
|
+
touchedForItem(fieldName: string, index: number): Record<string, boolean>;
|
|
260
|
+
handleGroupBlur(fieldName: string, index: number, key: string): void;
|
|
261
|
+
/**
|
|
262
|
+
* Clears the internally tracked touched state. Only meaningful in
|
|
263
|
+
* uncontrolled mode - when `touched` is bound, resetting the form store
|
|
264
|
+
* (e.g. `createDynamicFormStore().reset()`) already clears it.
|
|
265
|
+
*/
|
|
266
|
+
resetTouched(): void;
|
|
267
|
+
setFieldTouched(fieldName: string, isTouched?: boolean): void;
|
|
268
|
+
layout: LayoutConfig;
|
|
269
|
+
rootData?: Properties;
|
|
270
|
+
data: Properties;
|
|
271
|
+
visibleFields: FieldDescription[];
|
|
272
|
+
private initialised;
|
|
273
|
+
private isMobile;
|
|
274
|
+
constructor(cdr: ChangeDetectorRef);
|
|
275
|
+
onWindowResize(): void;
|
|
276
|
+
get resolvedLayout(): BaseLayoutConfig;
|
|
277
|
+
get resolvedLayoutType(): string;
|
|
278
|
+
get gap(): number;
|
|
279
|
+
get columns(): number;
|
|
280
|
+
trackByFn(index: number, field: FieldDescription): string | number;
|
|
281
|
+
trackByIndex(index: number): number;
|
|
282
|
+
private groupTrackByCache;
|
|
283
|
+
groupTrackBy(field: FieldDescription): (index: number, item: Properties) => unknown;
|
|
284
|
+
ngOnInit(): void;
|
|
285
|
+
ngOnChanges(_changes: SimpleChanges): void;
|
|
286
|
+
private updateIsMobile;
|
|
287
|
+
private init;
|
|
288
|
+
private updateVisibleFields;
|
|
289
|
+
onFieldChange(event: {
|
|
290
|
+
value: unknown;
|
|
291
|
+
key: string;
|
|
292
|
+
}): void;
|
|
293
|
+
getItems(field: FieldDescription): Properties[];
|
|
294
|
+
canAddItem(field: FieldDescription): boolean;
|
|
295
|
+
canRemoveItem(field: FieldDescription): boolean;
|
|
296
|
+
onGroupItemAdd(field: FieldDescription): void;
|
|
297
|
+
onGroupItemRemove(field: FieldDescription, index: number): void;
|
|
298
|
+
onGroupItemChange(field: FieldDescription, index: number, next: Properties): void;
|
|
299
|
+
private commitData;
|
|
300
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MultiFieldInput, never>;
|
|
301
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MultiFieldInput, "dfk-multi-field-input", never, { "fieldDescriptions": { "alias": "fieldDescriptions"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "initialProperties": { "alias": "initialProperties"; "required": false; }; "touched": { "alias": "touched"; "required": false; }; "errors": { "alias": "errors"; "required": false; }; "idPrefix": { "alias": "idPrefix"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "rootData": { "alias": "rootData"; "required": false; }; }, { "onChange": "onChange"; "validityChange": "validityChange"; "onBlurField": "onBlurField"; "touchedChange": "touchedChange"; }, never, never, true, never>;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
declare class DynamicFormDevToolsComponent {
|
|
305
|
+
data: Properties;
|
|
306
|
+
errors: Record<string, string[]>;
|
|
307
|
+
touched: Record<string, boolean>;
|
|
308
|
+
isDirty: boolean;
|
|
309
|
+
fields: FieldDescription[];
|
|
310
|
+
/** Number of fields carrying errors, mirroring the react and vue overlays. */
|
|
311
|
+
errorCount(): number;
|
|
312
|
+
isOpen: i0.WritableSignal<boolean>;
|
|
313
|
+
activeTab: i0.WritableSignal<"data" | "meta" | "errors" | "fields">;
|
|
314
|
+
tabs: Array<'data' | 'errors' | 'meta' | 'fields'>;
|
|
315
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicFormDevToolsComponent, never>;
|
|
316
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DynamicFormDevToolsComponent, "dfk-dev-tools", never, { "data": { "alias": "data"; "required": false; }; "errors": { "alias": "errors"; "required": false; }; "touched": { "alias": "touched"; "required": false; }; "isDirty": { "alias": "isDirty"; "required": false; }; "fields": { "alias": "fields"; "required": false; }; }, {}, never, never, true, never>;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
interface DynamicFormOptions {
|
|
320
|
+
fields: FieldDescription[];
|
|
321
|
+
initialValues?: Properties;
|
|
322
|
+
validateOnBlur?: boolean;
|
|
323
|
+
validateOnChange?: boolean;
|
|
324
|
+
/**
|
|
325
|
+
* Messages for the built-in validators, set once for the whole form instead
|
|
326
|
+
* of per field. A message passed directly to a validator still wins, and any
|
|
327
|
+
* key omitted here falls back to the validator's English default. See core's
|
|
328
|
+
* `MessageCatalog`.
|
|
329
|
+
*/
|
|
330
|
+
messages?: MessageCatalog;
|
|
331
|
+
}
|
|
332
|
+
declare function createDynamicFormStore(options: DynamicFormOptions): {
|
|
333
|
+
data: i0.WritableSignal<Properties>;
|
|
334
|
+
errors: i0.WritableSignal<Record<string, string[]>>;
|
|
335
|
+
isValid: i0.Signal<boolean>;
|
|
336
|
+
isValidating: i0.WritableSignal<boolean>;
|
|
337
|
+
isValidationComplete: i0.Signal<boolean>;
|
|
338
|
+
validationStatus: i0.Signal<"invalid" | "valid" | "pending">;
|
|
339
|
+
isDirty: i0.WritableSignal<boolean>;
|
|
340
|
+
baselineValues: i0.WritableSignal<Properties>;
|
|
341
|
+
getDirtyValues: () => Properties;
|
|
342
|
+
touched: i0.WritableSignal<Record<string, boolean>>;
|
|
343
|
+
isSubmitting: i0.WritableSignal<boolean>;
|
|
344
|
+
isSubmitted: i0.WritableSignal<boolean>;
|
|
345
|
+
setFieldValue: (name: string, value: unknown) => void;
|
|
346
|
+
setFieldTouched: (name: string, isTouched?: boolean) => void;
|
|
347
|
+
touchAll: () => void;
|
|
348
|
+
resetTouched: () => void;
|
|
349
|
+
handleChange: (newData: Properties) => void;
|
|
350
|
+
handleBlur: (fieldName: string) => void;
|
|
351
|
+
reset: (newValues?: Properties) => void;
|
|
352
|
+
validate: () => boolean;
|
|
353
|
+
validateAsync: () => Promise<boolean>;
|
|
354
|
+
handleSubmit: (onValid: (data: Properties) => void | Promise<void>, onInvalid?: (errors: Record<string, string[]>) => void) => (e?: Event) => Promise<void>;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
declare class ColumnLayout {
|
|
358
|
+
config?: {
|
|
359
|
+
gap?: number;
|
|
360
|
+
};
|
|
361
|
+
template: TemplateRef<unknown>;
|
|
362
|
+
get gap(): number;
|
|
363
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ColumnLayout, never>;
|
|
364
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ColumnLayout, "dfk-column-layout", never, { "config": { "alias": "config"; "required": false; }; "template": { "alias": "template"; "required": false; }; }, {}, never, never, true, never>;
|
|
365
|
+
}
|
|
366
|
+
declare class RowLayout {
|
|
367
|
+
config?: {
|
|
368
|
+
gap?: number;
|
|
369
|
+
};
|
|
370
|
+
template: TemplateRef<unknown>;
|
|
371
|
+
get gap(): number;
|
|
372
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RowLayout, never>;
|
|
373
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RowLayout, "dfk-row-layout", never, { "config": { "alias": "config"; "required": false; }; "template": { "alias": "template"; "required": false; }; }, {}, never, never, true, never>;
|
|
374
|
+
}
|
|
375
|
+
declare class GridLayout {
|
|
376
|
+
config?: {
|
|
377
|
+
columns?: number;
|
|
378
|
+
gap?: number;
|
|
379
|
+
};
|
|
380
|
+
template: TemplateRef<unknown>;
|
|
381
|
+
get columns(): number;
|
|
382
|
+
get gap(): number;
|
|
383
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<GridLayout, never>;
|
|
384
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<GridLayout, "dfk-grid-layout", never, { "config": { "alias": "config"; "required": false; }; "template": { "alias": "template"; "required": false; }; }, {}, never, never, true, never>;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
type AngularLayoutComponent = Type<unknown>;
|
|
388
|
+
declare class LayoutRegistry {
|
|
389
|
+
private layouts;
|
|
390
|
+
register(type: string, component: AngularLayoutComponent): void;
|
|
391
|
+
get(type: string): AngularLayoutComponent | undefined;
|
|
392
|
+
}
|
|
393
|
+
declare const layoutRegistry: LayoutRegistry;
|
|
394
|
+
|
|
395
|
+
declare class DynamicFieldKitModule {
|
|
396
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicFieldKitModule, never>;
|
|
397
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<DynamicFieldKitModule, never, [typeof i1.CommonModule, typeof DynamicInput, typeof FieldInput, typeof MultiFieldInput, typeof ColumnLayout, typeof RowLayout, typeof GridLayout], [typeof DynamicInput, typeof FieldInput, typeof MultiFieldInput, typeof ColumnLayout, typeof RowLayout, typeof GridLayout]>;
|
|
398
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<DynamicFieldKitModule>;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
declare const FIELD_REGISTRY: InjectionToken<FieldRegistry>;
|
|
402
|
+
|
|
403
|
+
export { BaseInputComponent, ColumnLayout, DynamicFieldKitModule, DynamicFormDevToolsComponent, DynamicInput, FIELD_REGISTRY, FieldInput, GridLayout, LayoutRegistry, MultiFieldInput, RowLayout, createDynamicFormStore, layoutRegistry };
|
|
404
|
+
export type { BaseLayoutConfig, DynamicFormOptions, FieldInputProps, ResponsiveLayoutConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-field-kit/angular",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Angular renderer for dynamic-field-kit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -10,7 +10,16 @@
|
|
|
10
10
|
],
|
|
11
11
|
"main": "dist/fesm2022/dynamic-field-kit-angular.mjs",
|
|
12
12
|
"module": "dist/fesm2022/dynamic-field-kit-angular.mjs",
|
|
13
|
-
"types": "dist/
|
|
13
|
+
"types": "dist/types/dynamic-field-kit-angular.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/types/dynamic-field-kit-angular.d.ts",
|
|
17
|
+
"default": "./dist/fesm2022/dynamic-field-kit-angular.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": {
|
|
20
|
+
"default": "./package.json"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
14
23
|
"files": [
|
|
15
24
|
"dist",
|
|
16
25
|
"!dist/README.md",
|
|
@@ -18,8 +27,8 @@
|
|
|
18
27
|
"CHANGELOG.md"
|
|
19
28
|
],
|
|
20
29
|
"peerDependencies": {
|
|
21
|
-
"@angular/common": ">=
|
|
22
|
-
"@angular/core": ">=
|
|
30
|
+
"@angular/common": ">=16 <22",
|
|
31
|
+
"@angular/core": ">=16 <22",
|
|
23
32
|
"@dynamic-field-kit/core": "^1.3.0"
|
|
24
33
|
},
|
|
25
34
|
"publishConfig": {
|
|
@@ -37,24 +46,23 @@
|
|
|
37
46
|
"devDependencies": {
|
|
38
47
|
"@analogjs/vite-plugin-angular": "^2.7.1",
|
|
39
48
|
"@analogjs/vitest-angular": "^2.7.1",
|
|
40
|
-
"@angular-devkit/build-angular": "^
|
|
41
|
-
"@angular/cdk": "^
|
|
42
|
-
"@angular/common": "^
|
|
43
|
-
"@angular/compiler": "^
|
|
44
|
-
"@angular/compiler-cli": "^
|
|
45
|
-
"@angular/core": "^
|
|
46
|
-
"@angular/forms": "^
|
|
47
|
-
"@angular/platform-browser": "^
|
|
48
|
-
"@
|
|
49
|
-
"@dynamic-field-kit/core": "^1.5.1",
|
|
49
|
+
"@angular-devkit/build-angular": "^21.2.0",
|
|
50
|
+
"@angular/cdk": "^21.2.14",
|
|
51
|
+
"@angular/common": "^21.2.0",
|
|
52
|
+
"@angular/compiler": "^21.2.0",
|
|
53
|
+
"@angular/compiler-cli": "^21.2.0",
|
|
54
|
+
"@angular/core": "^21.2.0",
|
|
55
|
+
"@angular/forms": "^21.2.0",
|
|
56
|
+
"@angular/platform-browser": "^21.2.0",
|
|
57
|
+
"@dynamic-field-kit/core": "^1.7.0",
|
|
50
58
|
"@vitest/coverage-istanbul": "^4.1.11",
|
|
51
59
|
"jsdom": "^29.1.1",
|
|
52
|
-
"ng-packagr": "^
|
|
60
|
+
"ng-packagr": "^21.2.0",
|
|
53
61
|
"rimraf": "^6.1.3",
|
|
54
62
|
"rxjs": "^7.8.0",
|
|
55
|
-
"typescript": "~5.
|
|
63
|
+
"typescript": "~5.9.3",
|
|
56
64
|
"vitest": "^4.1.11",
|
|
57
|
-
"zone.js": "
|
|
65
|
+
"zone.js": "~0.16.0"
|
|
58
66
|
},
|
|
59
67
|
"repository": {
|
|
60
68
|
"type": "git",
|
|
@@ -84,14 +92,5 @@
|
|
|
84
92
|
"homepage": "https://vannt-dev.github.io/dynamic-field-kit/",
|
|
85
93
|
"bugs": {
|
|
86
94
|
"url": "https://github.com/vannt-dev/dynamic-field-kit/issues"
|
|
87
|
-
},
|
|
88
|
-
"exports": {
|
|
89
|
-
".": {
|
|
90
|
-
"types": "./dist/index.d.ts",
|
|
91
|
-
"default": "./dist/fesm2022/dynamic-field-kit-angular.mjs"
|
|
92
|
-
},
|
|
93
|
-
"./package.json": {
|
|
94
|
-
"default": "./package.json"
|
|
95
|
-
}
|
|
96
95
|
}
|
|
97
96
|
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectorRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
export interface FieldInputProps {
|
|
4
|
-
value?: unknown;
|
|
5
|
-
label?: string;
|
|
6
|
-
placeholder?: string;
|
|
7
|
-
required?: boolean;
|
|
8
|
-
disabled?: boolean;
|
|
9
|
-
readOnly?: boolean;
|
|
10
|
-
error?: string | string[];
|
|
11
|
-
options?: unknown[];
|
|
12
|
-
className?: string;
|
|
13
|
-
description?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare abstract class BaseInputComponent implements OnChanges {
|
|
16
|
-
protected cdr: ChangeDetectorRef;
|
|
17
|
-
value?: unknown;
|
|
18
|
-
label?: string;
|
|
19
|
-
placeholder?: string;
|
|
20
|
-
required?: boolean;
|
|
21
|
-
disabled?: boolean;
|
|
22
|
-
readOnly?: boolean;
|
|
23
|
-
error?: string | string[];
|
|
24
|
-
options?: unknown[];
|
|
25
|
-
className?: string;
|
|
26
|
-
description?: string;
|
|
27
|
-
valueChange: EventEmitter<unknown>;
|
|
28
|
-
constructor(cdr: ChangeDetectorRef);
|
|
29
|
-
ngOnChanges(_changes: SimpleChanges): void;
|
|
30
|
-
protected detectChanges(): void;
|
|
31
|
-
protected hasChanges(changes: SimpleChanges, prop: string): boolean;
|
|
32
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<BaseInputComponent, 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>;
|
|
34
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { FieldDescription, Properties } from '@dynamic-field-kit/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
export declare class DynamicFormDevToolsComponent {
|
|
4
|
-
data: Properties;
|
|
5
|
-
errors: Record<string, string[]>;
|
|
6
|
-
touched: Record<string, boolean>;
|
|
7
|
-
isDirty: boolean;
|
|
8
|
-
fields: FieldDescription[];
|
|
9
|
-
/** Number of fields carrying errors, mirroring the react and vue overlays. */
|
|
10
|
-
errorCount(): number;
|
|
11
|
-
isOpen: import("@angular/core").WritableSignal<boolean>;
|
|
12
|
-
activeTab: import("@angular/core").WritableSignal<"data" | "meta" | "errors" | "fields">;
|
|
13
|
-
tabs: Array<'data' | 'errors' | 'meta' | 'fields'>;
|
|
14
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicFormDevToolsComponent, never>;
|
|
15
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<DynamicFormDevToolsComponent, "dfk-dev-tools", never, { "data": { "alias": "data"; "required": false; }; "errors": { "alias": "errors"; "required": false; }; "touched": { "alias": "touched"; "required": false; }; "isDirty": { "alias": "isDirty"; "required": false; }; "fields": { "alias": "fields"; "required": false; }; }, {}, never, never, true, never>;
|
|
16
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { AfterViewInit, EventEmitter, OnChanges, OnDestroy, SimpleChanges, ViewContainerRef } from '@angular/core';
|
|
2
|
-
import { FieldTypeKey, Properties } from '@dynamic-field-kit/core';
|
|
3
|
-
import { BaseInputComponent } from './BaseInput.js';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
export declare class DynamicInput extends BaseInputComponent implements OnChanges, AfterViewInit, OnDestroy {
|
|
6
|
-
type: FieldTypeKey;
|
|
7
|
-
extraProps?: Properties;
|
|
8
|
-
valueChange: EventEmitter<unknown>;
|
|
9
|
-
onChange: EventEmitter<unknown>;
|
|
10
|
-
private registry;
|
|
11
|
-
host: ViewContainerRef;
|
|
12
|
-
private compRef?;
|
|
13
|
-
private inputInstance?;
|
|
14
|
-
private subscriptions;
|
|
15
|
-
private supplied;
|
|
16
|
-
ngOnChanges(changes: SimpleChanges): void;
|
|
17
|
-
ngAfterViewInit(): void;
|
|
18
|
-
ngOnDestroy(): void;
|
|
19
|
-
private syncPropsToInstance;
|
|
20
|
-
private cleanup;
|
|
21
|
-
private cleanupSubscriptions;
|
|
22
|
-
private cleanupRenderedComponent;
|
|
23
|
-
private render;
|
|
24
|
-
private isComponentType;
|
|
25
|
-
private renderComponent;
|
|
26
|
-
private renderFallback;
|
|
27
|
-
private getFallbackProps;
|
|
28
|
-
private applyProps;
|
|
29
|
-
private applyExtraProps;
|
|
30
|
-
private bindOutputs;
|
|
31
|
-
private emitValue;
|
|
32
|
-
private renderDefaultFallbackHTML5;
|
|
33
|
-
private renderError;
|
|
34
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicInput, never>;
|
|
35
|
-
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>;
|
|
36
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectorRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
-
import { FieldDescription } from '@dynamic-field-kit/core';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export declare class FieldInput implements OnChanges {
|
|
5
|
-
private cdr;
|
|
6
|
-
fieldDescription?: FieldDescription;
|
|
7
|
-
value?: unknown;
|
|
8
|
-
options?: Record<string, unknown>[];
|
|
9
|
-
disabled?: boolean;
|
|
10
|
-
readOnly?: boolean;
|
|
11
|
-
error?: string | string[];
|
|
12
|
-
onValueChangeField: EventEmitter<{
|
|
13
|
-
value: unknown;
|
|
14
|
-
key: string;
|
|
15
|
-
}>;
|
|
16
|
-
/**
|
|
17
|
-
* Emits this field's name when focus leaves it. Driven by `focusout`, which
|
|
18
|
-
* bubbles, so it works for any renderer without the renderer having to
|
|
19
|
-
* declare a blur output of its own.
|
|
20
|
-
*/
|
|
21
|
-
onBlurField: EventEmitter<string>;
|
|
22
|
-
shouldRender: boolean;
|
|
23
|
-
get resolvedOptions(): Record<string, unknown>[] | undefined;
|
|
24
|
-
constructor(cdr: ChangeDetectorRef);
|
|
25
|
-
ngOnChanges(_changes: SimpleChanges): void;
|
|
26
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<FieldInput, never>;
|
|
27
|
-
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"; "onBlurField": "onBlurField"; }, never, never, true, never>;
|
|
28
|
-
}
|