@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,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, Output, Input, Component, InjectionToken, inject, ViewContainerRef, ViewChild, ChangeDetectionStrategy, HostListener, NgModule } from '@angular/core';
|
|
2
|
+
import { EventEmitter, Output, Input, Component, InjectionToken, inject, ViewContainerRef, ViewChild, ChangeDetectionStrategy, HostListener, signal, computed, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
|
-
import { CommonModule, NgIf, NgClass, NgFor } from '@angular/common';
|
|
4
|
+
import { CommonModule, NgIf, NgClass, NgFor, JsonPipe } from '@angular/common';
|
|
5
5
|
import { fieldRegistry, applyComputedValues, validateFields, resolveOptions, resolveDisabled, resolveReadOnly, validateField, canAddGroupItem, canRemoveGroupItem, createGroupItem } from '@dynamic-field-kit/core';
|
|
6
6
|
export { FieldRegistry, fieldRegistry, resolveDisabled, resolveOptions, resolveReadOnly, validateField, validateFieldAsync, validateFields, validateFieldsAsync, validators } from '@dynamic-field-kit/core';
|
|
7
7
|
|
|
@@ -30,10 +30,10 @@ class BaseInputComponent {
|
|
|
30
30
|
hasChanges(changes, prop) {
|
|
31
31
|
return changes[prop] !== undefined;
|
|
32
32
|
}
|
|
33
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
34
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
33
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: BaseInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
34
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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 });
|
|
35
35
|
}
|
|
36
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
36
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: BaseInputComponent, decorators: [{
|
|
37
37
|
type: Component,
|
|
38
38
|
args: [{
|
|
39
39
|
template: '',
|
|
@@ -155,6 +155,9 @@ class DynamicInput extends BaseInputComponent {
|
|
|
155
155
|
this.cleanup();
|
|
156
156
|
this.host.clear();
|
|
157
157
|
if (!Renderer) {
|
|
158
|
+
if (this.renderDefaultFallbackHTML5(this.type)) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
158
161
|
this.renderError(`Unknown field type: ${this.type}`);
|
|
159
162
|
return;
|
|
160
163
|
}
|
|
@@ -280,16 +283,128 @@ class DynamicInput extends BaseInputComponent {
|
|
|
280
283
|
this.valueChange.emit(value);
|
|
281
284
|
this.onChange.emit(value);
|
|
282
285
|
}
|
|
286
|
+
renderDefaultFallbackHTML5(type) {
|
|
287
|
+
const nativeEl = this.host.element.nativeElement;
|
|
288
|
+
if (type === 'text' ||
|
|
289
|
+
type === 'password' ||
|
|
290
|
+
type === 'email' ||
|
|
291
|
+
type === 'number') {
|
|
292
|
+
const input = document.createElement('input');
|
|
293
|
+
input.type = type;
|
|
294
|
+
if (this.className) {
|
|
295
|
+
input.className = this.className;
|
|
296
|
+
}
|
|
297
|
+
if (this.placeholder) {
|
|
298
|
+
input.placeholder = this.placeholder;
|
|
299
|
+
}
|
|
300
|
+
if (this.disabled) {
|
|
301
|
+
input.disabled = true;
|
|
302
|
+
}
|
|
303
|
+
if (this.readOnly) {
|
|
304
|
+
input.readOnly = true;
|
|
305
|
+
}
|
|
306
|
+
if (this.required) {
|
|
307
|
+
input.required = true;
|
|
308
|
+
}
|
|
309
|
+
input.value = (this.value ?? '').toString();
|
|
310
|
+
input.addEventListener('input', (e) => {
|
|
311
|
+
const raw = e.target.value;
|
|
312
|
+
const val = type === 'number' ? (raw === '' ? undefined : Number(raw)) : raw;
|
|
313
|
+
this.emitValue(val);
|
|
314
|
+
});
|
|
315
|
+
nativeEl.appendChild(input);
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
if (type === 'textarea') {
|
|
319
|
+
const textarea = document.createElement('textarea');
|
|
320
|
+
if (this.className) {
|
|
321
|
+
textarea.className = this.className;
|
|
322
|
+
}
|
|
323
|
+
if (this.placeholder) {
|
|
324
|
+
textarea.placeholder = this.placeholder;
|
|
325
|
+
}
|
|
326
|
+
if (this.disabled) {
|
|
327
|
+
textarea.disabled = true;
|
|
328
|
+
}
|
|
329
|
+
if (this.readOnly) {
|
|
330
|
+
textarea.readOnly = true;
|
|
331
|
+
}
|
|
332
|
+
if (this.required) {
|
|
333
|
+
textarea.required = true;
|
|
334
|
+
}
|
|
335
|
+
textarea.value = this.value ?? '';
|
|
336
|
+
textarea.addEventListener('input', (e) => {
|
|
337
|
+
this.emitValue(e.target.value);
|
|
338
|
+
});
|
|
339
|
+
nativeEl.appendChild(textarea);
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
if (type === 'checkbox') {
|
|
343
|
+
const checkbox = document.createElement('input');
|
|
344
|
+
checkbox.type = 'checkbox';
|
|
345
|
+
if (this.className) {
|
|
346
|
+
checkbox.className = this.className;
|
|
347
|
+
}
|
|
348
|
+
if (this.disabled || this.readOnly) {
|
|
349
|
+
checkbox.disabled = true;
|
|
350
|
+
}
|
|
351
|
+
if (this.required) {
|
|
352
|
+
checkbox.required = true;
|
|
353
|
+
}
|
|
354
|
+
checkbox.checked = Boolean(this.value);
|
|
355
|
+
checkbox.addEventListener('change', (e) => {
|
|
356
|
+
this.emitValue(e.target.checked);
|
|
357
|
+
});
|
|
358
|
+
nativeEl.appendChild(checkbox);
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
if (type === 'select') {
|
|
362
|
+
const select = document.createElement('select');
|
|
363
|
+
if (this.className) {
|
|
364
|
+
select.className = this.className;
|
|
365
|
+
}
|
|
366
|
+
if (this.disabled || this.readOnly) {
|
|
367
|
+
select.disabled = true;
|
|
368
|
+
}
|
|
369
|
+
if (this.required) {
|
|
370
|
+
select.required = true;
|
|
371
|
+
}
|
|
372
|
+
const defaultOpt = document.createElement('option');
|
|
373
|
+
defaultOpt.value = '';
|
|
374
|
+
defaultOpt.disabled = true;
|
|
375
|
+
defaultOpt.textContent = '-- Select --';
|
|
376
|
+
select.appendChild(defaultOpt);
|
|
377
|
+
const options = this.options || [];
|
|
378
|
+
options.forEach((opt) => {
|
|
379
|
+
const optObj = opt;
|
|
380
|
+
const optVal = optObj['value'] ?? optObj['id'] ?? opt;
|
|
381
|
+
const optLabel = optObj['label'] ?? optObj['name'] ?? String(optVal);
|
|
382
|
+
const optionEl = document.createElement('option');
|
|
383
|
+
optionEl.value = String(optVal);
|
|
384
|
+
optionEl.textContent = String(optLabel);
|
|
385
|
+
if (String(optVal) === String(this.value)) {
|
|
386
|
+
optionEl.selected = true;
|
|
387
|
+
}
|
|
388
|
+
select.appendChild(optionEl);
|
|
389
|
+
});
|
|
390
|
+
select.addEventListener('change', (e) => {
|
|
391
|
+
this.emitValue(e.target.value);
|
|
392
|
+
});
|
|
393
|
+
nativeEl.appendChild(select);
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
283
398
|
renderError(message) {
|
|
284
399
|
const el = document.createElement('div');
|
|
285
400
|
el.textContent = message;
|
|
286
401
|
el.style.color = 'red';
|
|
287
402
|
this.host.element.nativeElement.appendChild(el);
|
|
288
403
|
}
|
|
289
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
290
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
404
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicInput, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
405
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: DynamicInput, isStandalone: true, selector: "dfk-dynamic-input", inputs: { type: "type", extraProps: "extraProps" }, outputs: { valueChange: "valueChange", onChange: "onChange" }, viewQueries: [{ propertyName: "host", first: true, predicate: ["host"], descendants: true, read: ViewContainerRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `<div #host style="display: contents;"></div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
291
406
|
}
|
|
292
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
407
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicInput, decorators: [{
|
|
293
408
|
type: Component,
|
|
294
409
|
args: [{
|
|
295
410
|
selector: 'dfk-dynamic-input',
|
|
@@ -320,6 +435,12 @@ class FieldInput {
|
|
|
320
435
|
readOnly;
|
|
321
436
|
error;
|
|
322
437
|
onValueChangeField = new EventEmitter();
|
|
438
|
+
/**
|
|
439
|
+
* Emits this field's name when focus leaves it. Driven by `focusout`, which
|
|
440
|
+
* bubbles, so it works for any renderer without the renderer having to
|
|
441
|
+
* declare a blur output of its own.
|
|
442
|
+
*/
|
|
443
|
+
onBlurField = new EventEmitter();
|
|
323
444
|
shouldRender = false;
|
|
324
445
|
get resolvedOptions() {
|
|
325
446
|
if (this.options) {
|
|
@@ -340,8 +461,8 @@ class FieldInput {
|
|
|
340
461
|
this.shouldRender = !!this.fieldDescription;
|
|
341
462
|
this.cdr.markForCheck();
|
|
342
463
|
}
|
|
343
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
344
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
464
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldInput, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
465
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: FieldInput, isStandalone: true, selector: "dfk-field-input", inputs: { fieldDescription: "fieldDescription", value: "value", options: "options", disabled: "disabled", readOnly: "readOnly", error: "error" }, outputs: { onValueChangeField: "onValueChangeField", onBlurField: "onBlurField" }, usesOnChanges: true, ngImport: i0, template: `
|
|
345
466
|
<dfk-dynamic-input
|
|
346
467
|
*ngIf="shouldRender"
|
|
347
468
|
[type]="fieldDescription!.type"
|
|
@@ -355,6 +476,7 @@ class FieldInput {
|
|
|
355
476
|
(valueChange)="
|
|
356
477
|
onValueChangeField.emit({ value: $event, key: fieldDescription!.name })
|
|
357
478
|
"
|
|
479
|
+
(focusout)="onBlurField.emit(fieldDescription!.name)"
|
|
358
480
|
[disabled]="disabled"
|
|
359
481
|
[readOnly]="readOnly"
|
|
360
482
|
[error]="$any(error)"
|
|
@@ -362,7 +484,7 @@ class FieldInput {
|
|
|
362
484
|
></dfk-dynamic-input>
|
|
363
485
|
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DynamicInput, selector: "dfk-dynamic-input", inputs: ["type", "extraProps"], outputs: ["valueChange", "onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
364
486
|
}
|
|
365
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
487
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldInput, decorators: [{
|
|
366
488
|
type: Component,
|
|
367
489
|
args: [{
|
|
368
490
|
selector: 'dfk-field-input',
|
|
@@ -383,6 +505,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
383
505
|
(valueChange)="
|
|
384
506
|
onValueChangeField.emit({ value: $event, key: fieldDescription!.name })
|
|
385
507
|
"
|
|
508
|
+
(focusout)="onBlurField.emit(fieldDescription!.name)"
|
|
386
509
|
[disabled]="disabled"
|
|
387
510
|
[readOnly]="readOnly"
|
|
388
511
|
[error]="$any(error)"
|
|
@@ -404,6 +527,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
404
527
|
type: Input
|
|
405
528
|
}], onValueChangeField: [{
|
|
406
529
|
type: Output
|
|
530
|
+
}], onBlurField: [{
|
|
531
|
+
type: Output
|
|
407
532
|
}] } });
|
|
408
533
|
|
|
409
534
|
const DEFAULT_BREAKPOINT = 768;
|
|
@@ -413,6 +538,22 @@ class MultiFieldInput {
|
|
|
413
538
|
properties;
|
|
414
539
|
onChange = new EventEmitter();
|
|
415
540
|
validityChange = new EventEmitter();
|
|
541
|
+
/**
|
|
542
|
+
* Emits a field's name when it loses focus. Touched state is tracked
|
|
543
|
+
* internally either way; this is the hook for driving an external form store
|
|
544
|
+
* - pass `createDynamicFormStore`'s `handleBlur` to get its `touched` map and
|
|
545
|
+
* `validateOnBlur` behaviour.
|
|
546
|
+
*/
|
|
547
|
+
onBlurField = new EventEmitter();
|
|
548
|
+
touchedFields = {};
|
|
549
|
+
handleBlurField(fieldName) {
|
|
550
|
+
this.touchedFields = { ...this.touchedFields, [fieldName]: true };
|
|
551
|
+
this.onBlurField.emit(fieldName);
|
|
552
|
+
}
|
|
553
|
+
/** Whether this field has been blurred at least once. */
|
|
554
|
+
isTouched(fieldName) {
|
|
555
|
+
return Boolean(this.touchedFields[fieldName]);
|
|
556
|
+
}
|
|
416
557
|
layout = 'column';
|
|
417
558
|
// Top-level form data, threaded down through repeatable groups so a nested
|
|
418
559
|
// field's appearCondition/computeValue can read the root form. Omitted at
|
|
@@ -468,7 +609,7 @@ class MultiFieldInput {
|
|
|
468
609
|
groupTrackBy(field) {
|
|
469
610
|
let fn = this.groupTrackByCache.get(field);
|
|
470
611
|
if (!fn) {
|
|
471
|
-
fn = (index, item) => field.keyField ? item[field.keyField] ?? index : index;
|
|
612
|
+
fn = (index, item) => field.keyField ? (item[field.keyField] ?? index) : index;
|
|
472
613
|
this.groupTrackByCache.set(field, fn);
|
|
473
614
|
}
|
|
474
615
|
return fn;
|
|
@@ -482,7 +623,7 @@ class MultiFieldInput {
|
|
|
482
623
|
}
|
|
483
624
|
updateIsMobile() {
|
|
484
625
|
const breakpoint = typeof this.layout === 'object' && this.layout.type === 'responsive'
|
|
485
|
-
? this.layout.breakpoint ?? DEFAULT_BREAKPOINT
|
|
626
|
+
? (this.layout.breakpoint ?? DEFAULT_BREAKPOINT)
|
|
486
627
|
: DEFAULT_BREAKPOINT;
|
|
487
628
|
if (typeof window !== 'undefined' &&
|
|
488
629
|
typeof window.matchMedia === 'function') {
|
|
@@ -562,14 +703,14 @@ class MultiFieldInput {
|
|
|
562
703
|
this.validityChange.emit(validateFields(this.fieldDescriptions, this.data, this.rootData));
|
|
563
704
|
this.cdr.markForCheck();
|
|
564
705
|
}
|
|
565
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
566
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
706
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MultiFieldInput, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
707
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: MultiFieldInput, isStandalone: true, selector: "dfk-multi-field-input", inputs: { fieldDescriptions: "fieldDescriptions", properties: "properties", layout: "layout", rootData: "rootData" }, outputs: { onChange: "onChange", validityChange: "validityChange", onBlurField: "onBlurField" }, host: { listeners: { "window:resize": "onWindowResize()" } }, usesOnChanges: true, ngImport: i0, template: `
|
|
567
708
|
<div
|
|
568
709
|
class="p-4 border rounded-lg bg-gray-50"
|
|
569
710
|
[ngClass]="{
|
|
570
711
|
'flex flex-col': resolvedLayoutType === 'column',
|
|
571
712
|
'flex flex-row': resolvedLayoutType === 'row',
|
|
572
|
-
grid: resolvedLayoutType === 'grid'
|
|
713
|
+
grid: resolvedLayoutType === 'grid',
|
|
573
714
|
}"
|
|
574
715
|
[style.gap.px]="gap"
|
|
575
716
|
[style.gridTemplateColumns]="
|
|
@@ -586,6 +727,7 @@ class MultiFieldInput {
|
|
|
586
727
|
[readOnly]="getReadOnly(field)"
|
|
587
728
|
[error]="getError(field)"
|
|
588
729
|
(onValueChangeField)="onFieldChange($event)"
|
|
730
|
+
(onBlurField)="handleBlurField($event)"
|
|
589
731
|
></dfk-field-input>
|
|
590
732
|
|
|
591
733
|
<div *ngIf="field.fields" [class]="field.className">
|
|
@@ -634,9 +776,9 @@ class MultiFieldInput {
|
|
|
634
776
|
</div>
|
|
635
777
|
</ng-container>
|
|
636
778
|
</div>
|
|
637
|
-
`, isInline: true, dependencies: [{ kind: "component", type: MultiFieldInput, selector: "dfk-multi-field-input", inputs: ["fieldDescriptions", "properties", "layout", "rootData"], outputs: ["onChange", "validityChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FieldInput, selector: "dfk-field-input", inputs: ["fieldDescription", "value", "options", "disabled", "readOnly", "error"], outputs: ["onValueChangeField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
779
|
+
`, isInline: true, dependencies: [{ kind: "component", type: MultiFieldInput, selector: "dfk-multi-field-input", inputs: ["fieldDescriptions", "properties", "layout", "rootData"], outputs: ["onChange", "validityChange", "onBlurField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FieldInput, selector: "dfk-field-input", inputs: ["fieldDescription", "value", "options", "disabled", "readOnly", "error"], outputs: ["onValueChangeField", "onBlurField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
638
780
|
}
|
|
639
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
781
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MultiFieldInput, decorators: [{
|
|
640
782
|
type: Component,
|
|
641
783
|
args: [{
|
|
642
784
|
selector: 'dfk-multi-field-input',
|
|
@@ -655,7 +797,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
655
797
|
[ngClass]="{
|
|
656
798
|
'flex flex-col': resolvedLayoutType === 'column',
|
|
657
799
|
'flex flex-row': resolvedLayoutType === 'row',
|
|
658
|
-
grid: resolvedLayoutType === 'grid'
|
|
800
|
+
grid: resolvedLayoutType === 'grid',
|
|
659
801
|
}"
|
|
660
802
|
[style.gap.px]="gap"
|
|
661
803
|
[style.gridTemplateColumns]="
|
|
@@ -672,6 +814,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
672
814
|
[readOnly]="getReadOnly(field)"
|
|
673
815
|
[error]="getError(field)"
|
|
674
816
|
(onValueChangeField)="onFieldChange($event)"
|
|
817
|
+
(onBlurField)="handleBlurField($event)"
|
|
675
818
|
></dfk-field-input>
|
|
676
819
|
|
|
677
820
|
<div *ngIf="field.fields" [class]="field.className">
|
|
@@ -730,6 +873,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
730
873
|
type: Output
|
|
731
874
|
}], validityChange: [{
|
|
732
875
|
type: Output
|
|
876
|
+
}], onBlurField: [{
|
|
877
|
+
type: Output
|
|
733
878
|
}], layout: [{
|
|
734
879
|
type: Input
|
|
735
880
|
}], rootData: [{
|
|
@@ -739,6 +884,406 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
739
884
|
args: ['window:resize']
|
|
740
885
|
}] } });
|
|
741
886
|
|
|
887
|
+
class DynamicFormDevToolsComponent {
|
|
888
|
+
data = {};
|
|
889
|
+
errors = {};
|
|
890
|
+
touched = {};
|
|
891
|
+
isDirty = false;
|
|
892
|
+
fields = [];
|
|
893
|
+
/** Number of fields carrying errors, mirroring the react and vue overlays. */
|
|
894
|
+
errorCount() {
|
|
895
|
+
return Object.keys(this.errors || {}).length;
|
|
896
|
+
}
|
|
897
|
+
isOpen = signal(false);
|
|
898
|
+
activeTab = signal('data');
|
|
899
|
+
tabs = [
|
|
900
|
+
'data',
|
|
901
|
+
'errors',
|
|
902
|
+
'meta',
|
|
903
|
+
'fields',
|
|
904
|
+
];
|
|
905
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicFormDevToolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
906
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: DynamicFormDevToolsComponent, isStandalone: true, selector: "dfk-dev-tools", inputs: { data: "data", errors: "errors", touched: "touched", isDirty: "isDirty", fields: "fields" }, ngImport: i0, template: `
|
|
907
|
+
<button
|
|
908
|
+
*ngIf="!isOpen()"
|
|
909
|
+
type="button"
|
|
910
|
+
(click)="isOpen.set(true)"
|
|
911
|
+
style="
|
|
912
|
+
position: fixed;
|
|
913
|
+
right: 16px;
|
|
914
|
+
bottom: 16px;
|
|
915
|
+
z-index: 99999;
|
|
916
|
+
background: #1e293b;
|
|
917
|
+
color: #f8fafc;
|
|
918
|
+
border: 1px solid #334155;
|
|
919
|
+
border-radius: 20px;
|
|
920
|
+
padding: 8px 14px;
|
|
921
|
+
font-size: 12px;
|
|
922
|
+
font-weight: 600;
|
|
923
|
+
cursor: pointer;
|
|
924
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
925
|
+
display: flex;
|
|
926
|
+
align-items: center;
|
|
927
|
+
gap: 6px;
|
|
928
|
+
"
|
|
929
|
+
>
|
|
930
|
+
<span>🔍 DevTools</span>
|
|
931
|
+
<span
|
|
932
|
+
*ngIf="errorCount() > 0"
|
|
933
|
+
class="dfk-devtools-badge"
|
|
934
|
+
style="
|
|
935
|
+
background: #ef4444;
|
|
936
|
+
color: #fff;
|
|
937
|
+
border-radius: 10px;
|
|
938
|
+
padding: 2px 6px;
|
|
939
|
+
font-size: 10px;
|
|
940
|
+
"
|
|
941
|
+
>{{ errorCount() }}</span
|
|
942
|
+
>
|
|
943
|
+
</button>
|
|
944
|
+
|
|
945
|
+
<div
|
|
946
|
+
*ngIf="isOpen()"
|
|
947
|
+
style="
|
|
948
|
+
position: fixed;
|
|
949
|
+
right: 16px;
|
|
950
|
+
bottom: 16px;
|
|
951
|
+
z-index: 99999;
|
|
952
|
+
width: 360px;
|
|
953
|
+
max-height: 420px;
|
|
954
|
+
background: #0f172a;
|
|
955
|
+
color: #f8fafc;
|
|
956
|
+
border: 1px solid #334155;
|
|
957
|
+
border-radius: 12px;
|
|
958
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
|
|
959
|
+
display: flex;
|
|
960
|
+
flex-direction: column;
|
|
961
|
+
font-family: monospace, sans-serif;
|
|
962
|
+
font-size: 12px;
|
|
963
|
+
overflow: hidden;
|
|
964
|
+
"
|
|
965
|
+
>
|
|
966
|
+
<div
|
|
967
|
+
style="
|
|
968
|
+
padding: 10px 14px;
|
|
969
|
+
background: #1e293b;
|
|
970
|
+
display: flex;
|
|
971
|
+
justify-content: space-between;
|
|
972
|
+
align-items: center;
|
|
973
|
+
border-bottom: 1px solid #334155;
|
|
974
|
+
"
|
|
975
|
+
>
|
|
976
|
+
<span style="font-weight: bold; color: #38bdf8;">🛠️ Form DevTools</span>
|
|
977
|
+
<button
|
|
978
|
+
type="button"
|
|
979
|
+
(click)="isOpen.set(false)"
|
|
980
|
+
style="background: transparent; border: none; color: #94a3b8; font-size: 14px; cursor: pointer;"
|
|
981
|
+
>
|
|
982
|
+
✕
|
|
983
|
+
</button>
|
|
984
|
+
</div>
|
|
985
|
+
|
|
986
|
+
<div
|
|
987
|
+
style="display: flex; background: #1e293b; border-bottom: 1px solid #334155;"
|
|
988
|
+
>
|
|
989
|
+
<button
|
|
990
|
+
type="button"
|
|
991
|
+
*ngFor="let tab of tabs"
|
|
992
|
+
(click)="activeTab.set(tab)"
|
|
993
|
+
[style.background]="activeTab() === tab ? '#0f172a' : 'transparent'"
|
|
994
|
+
[style.color]="activeTab() === tab ? '#38bdf8' : '#94a3b8'"
|
|
995
|
+
style="flex: 1; padding: 6px 0; border: none; cursor: pointer; text-transform: capitalize; font-size: 11px;"
|
|
996
|
+
>
|
|
997
|
+
{{ tab
|
|
998
|
+
}}{{
|
|
999
|
+
tab === 'errors' && errorCount() > 0
|
|
1000
|
+
? ' (' + errorCount() + ')'
|
|
1001
|
+
: ''
|
|
1002
|
+
}}
|
|
1003
|
+
</button>
|
|
1004
|
+
</div>
|
|
1005
|
+
|
|
1006
|
+
<div style="padding: 12px; overflow-y: auto; flex: 1;">
|
|
1007
|
+
<pre
|
|
1008
|
+
*ngIf="activeTab() === 'data'"
|
|
1009
|
+
style="margin: 0; white-space: pre-wrap; word-break: break-all; color: #a7f3d0;"
|
|
1010
|
+
>
|
|
1011
|
+
{{ data | json }}
|
|
1012
|
+
</pre>
|
|
1013
|
+
<pre
|
|
1014
|
+
*ngIf="activeTab() === 'errors'"
|
|
1015
|
+
style="margin: 0; white-space: pre-wrap; word-break: break-all; color: #f87171;"
|
|
1016
|
+
>
|
|
1017
|
+
{{ errors | json }}
|
|
1018
|
+
</pre>
|
|
1019
|
+
<div *ngIf="activeTab() === 'meta'">
|
|
1020
|
+
<div>isDirty: {{ isDirty }}</div>
|
|
1021
|
+
<pre style="margin: 4px 0 0 0; color: #cbd5e1;">{{
|
|
1022
|
+
touched | json
|
|
1023
|
+
}}</pre>
|
|
1024
|
+
</div>
|
|
1025
|
+
<div *ngIf="activeTab() === 'fields'">
|
|
1026
|
+
<div
|
|
1027
|
+
*ngFor="let f of fields"
|
|
1028
|
+
style="padding: 6px; margin-bottom: 6px; background: #1e293b; border-radius: 4px;"
|
|
1029
|
+
>
|
|
1030
|
+
<div style="color: #38bdf8; font-weight: bold;">{{ f.name }}</div>
|
|
1031
|
+
<div style="color: #94a3b8; font-size: 10px;">
|
|
1032
|
+
type: {{ f.type }}
|
|
1033
|
+
</div>
|
|
1034
|
+
</div>
|
|
1035
|
+
</div>
|
|
1036
|
+
</div>
|
|
1037
|
+
</div>
|
|
1038
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1039
|
+
}
|
|
1040
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicFormDevToolsComponent, decorators: [{
|
|
1041
|
+
type: Component,
|
|
1042
|
+
args: [{
|
|
1043
|
+
selector: 'dfk-dev-tools',
|
|
1044
|
+
standalone: true,
|
|
1045
|
+
imports: [NgIf, NgFor, JsonPipe],
|
|
1046
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1047
|
+
template: `
|
|
1048
|
+
<button
|
|
1049
|
+
*ngIf="!isOpen()"
|
|
1050
|
+
type="button"
|
|
1051
|
+
(click)="isOpen.set(true)"
|
|
1052
|
+
style="
|
|
1053
|
+
position: fixed;
|
|
1054
|
+
right: 16px;
|
|
1055
|
+
bottom: 16px;
|
|
1056
|
+
z-index: 99999;
|
|
1057
|
+
background: #1e293b;
|
|
1058
|
+
color: #f8fafc;
|
|
1059
|
+
border: 1px solid #334155;
|
|
1060
|
+
border-radius: 20px;
|
|
1061
|
+
padding: 8px 14px;
|
|
1062
|
+
font-size: 12px;
|
|
1063
|
+
font-weight: 600;
|
|
1064
|
+
cursor: pointer;
|
|
1065
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
1066
|
+
display: flex;
|
|
1067
|
+
align-items: center;
|
|
1068
|
+
gap: 6px;
|
|
1069
|
+
"
|
|
1070
|
+
>
|
|
1071
|
+
<span>🔍 DevTools</span>
|
|
1072
|
+
<span
|
|
1073
|
+
*ngIf="errorCount() > 0"
|
|
1074
|
+
class="dfk-devtools-badge"
|
|
1075
|
+
style="
|
|
1076
|
+
background: #ef4444;
|
|
1077
|
+
color: #fff;
|
|
1078
|
+
border-radius: 10px;
|
|
1079
|
+
padding: 2px 6px;
|
|
1080
|
+
font-size: 10px;
|
|
1081
|
+
"
|
|
1082
|
+
>{{ errorCount() }}</span
|
|
1083
|
+
>
|
|
1084
|
+
</button>
|
|
1085
|
+
|
|
1086
|
+
<div
|
|
1087
|
+
*ngIf="isOpen()"
|
|
1088
|
+
style="
|
|
1089
|
+
position: fixed;
|
|
1090
|
+
right: 16px;
|
|
1091
|
+
bottom: 16px;
|
|
1092
|
+
z-index: 99999;
|
|
1093
|
+
width: 360px;
|
|
1094
|
+
max-height: 420px;
|
|
1095
|
+
background: #0f172a;
|
|
1096
|
+
color: #f8fafc;
|
|
1097
|
+
border: 1px solid #334155;
|
|
1098
|
+
border-radius: 12px;
|
|
1099
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
|
|
1100
|
+
display: flex;
|
|
1101
|
+
flex-direction: column;
|
|
1102
|
+
font-family: monospace, sans-serif;
|
|
1103
|
+
font-size: 12px;
|
|
1104
|
+
overflow: hidden;
|
|
1105
|
+
"
|
|
1106
|
+
>
|
|
1107
|
+
<div
|
|
1108
|
+
style="
|
|
1109
|
+
padding: 10px 14px;
|
|
1110
|
+
background: #1e293b;
|
|
1111
|
+
display: flex;
|
|
1112
|
+
justify-content: space-between;
|
|
1113
|
+
align-items: center;
|
|
1114
|
+
border-bottom: 1px solid #334155;
|
|
1115
|
+
"
|
|
1116
|
+
>
|
|
1117
|
+
<span style="font-weight: bold; color: #38bdf8;">🛠️ Form DevTools</span>
|
|
1118
|
+
<button
|
|
1119
|
+
type="button"
|
|
1120
|
+
(click)="isOpen.set(false)"
|
|
1121
|
+
style="background: transparent; border: none; color: #94a3b8; font-size: 14px; cursor: pointer;"
|
|
1122
|
+
>
|
|
1123
|
+
✕
|
|
1124
|
+
</button>
|
|
1125
|
+
</div>
|
|
1126
|
+
|
|
1127
|
+
<div
|
|
1128
|
+
style="display: flex; background: #1e293b; border-bottom: 1px solid #334155;"
|
|
1129
|
+
>
|
|
1130
|
+
<button
|
|
1131
|
+
type="button"
|
|
1132
|
+
*ngFor="let tab of tabs"
|
|
1133
|
+
(click)="activeTab.set(tab)"
|
|
1134
|
+
[style.background]="activeTab() === tab ? '#0f172a' : 'transparent'"
|
|
1135
|
+
[style.color]="activeTab() === tab ? '#38bdf8' : '#94a3b8'"
|
|
1136
|
+
style="flex: 1; padding: 6px 0; border: none; cursor: pointer; text-transform: capitalize; font-size: 11px;"
|
|
1137
|
+
>
|
|
1138
|
+
{{ tab
|
|
1139
|
+
}}{{
|
|
1140
|
+
tab === 'errors' && errorCount() > 0
|
|
1141
|
+
? ' (' + errorCount() + ')'
|
|
1142
|
+
: ''
|
|
1143
|
+
}}
|
|
1144
|
+
</button>
|
|
1145
|
+
</div>
|
|
1146
|
+
|
|
1147
|
+
<div style="padding: 12px; overflow-y: auto; flex: 1;">
|
|
1148
|
+
<pre
|
|
1149
|
+
*ngIf="activeTab() === 'data'"
|
|
1150
|
+
style="margin: 0; white-space: pre-wrap; word-break: break-all; color: #a7f3d0;"
|
|
1151
|
+
>
|
|
1152
|
+
{{ data | json }}
|
|
1153
|
+
</pre>
|
|
1154
|
+
<pre
|
|
1155
|
+
*ngIf="activeTab() === 'errors'"
|
|
1156
|
+
style="margin: 0; white-space: pre-wrap; word-break: break-all; color: #f87171;"
|
|
1157
|
+
>
|
|
1158
|
+
{{ errors | json }}
|
|
1159
|
+
</pre>
|
|
1160
|
+
<div *ngIf="activeTab() === 'meta'">
|
|
1161
|
+
<div>isDirty: {{ isDirty }}</div>
|
|
1162
|
+
<pre style="margin: 4px 0 0 0; color: #cbd5e1;">{{
|
|
1163
|
+
touched | json
|
|
1164
|
+
}}</pre>
|
|
1165
|
+
</div>
|
|
1166
|
+
<div *ngIf="activeTab() === 'fields'">
|
|
1167
|
+
<div
|
|
1168
|
+
*ngFor="let f of fields"
|
|
1169
|
+
style="padding: 6px; margin-bottom: 6px; background: #1e293b; border-radius: 4px;"
|
|
1170
|
+
>
|
|
1171
|
+
<div style="color: #38bdf8; font-weight: bold;">{{ f.name }}</div>
|
|
1172
|
+
<div style="color: #94a3b8; font-size: 10px;">
|
|
1173
|
+
type: {{ f.type }}
|
|
1174
|
+
</div>
|
|
1175
|
+
</div>
|
|
1176
|
+
</div>
|
|
1177
|
+
</div>
|
|
1178
|
+
</div>
|
|
1179
|
+
`,
|
|
1180
|
+
}]
|
|
1181
|
+
}], propDecorators: { data: [{
|
|
1182
|
+
type: Input
|
|
1183
|
+
}], errors: [{
|
|
1184
|
+
type: Input
|
|
1185
|
+
}], touched: [{
|
|
1186
|
+
type: Input
|
|
1187
|
+
}], isDirty: [{
|
|
1188
|
+
type: Input
|
|
1189
|
+
}], fields: [{
|
|
1190
|
+
type: Input
|
|
1191
|
+
}] } });
|
|
1192
|
+
|
|
1193
|
+
function createDynamicFormStore(options) {
|
|
1194
|
+
const fields = options.fields;
|
|
1195
|
+
const initialValues = options.initialValues || {};
|
|
1196
|
+
const validateOnBlur = options.validateOnBlur ?? true;
|
|
1197
|
+
const validateOnChange = options.validateOnChange ?? false;
|
|
1198
|
+
const data = signal(applyComputedValues(fields, initialValues));
|
|
1199
|
+
const errors = signal({});
|
|
1200
|
+
const isDirty = signal(false);
|
|
1201
|
+
const touched = signal({});
|
|
1202
|
+
const isSubmitting = signal(false);
|
|
1203
|
+
const isSubmitted = signal(false);
|
|
1204
|
+
const isValid = computed(() => Object.keys(errors()).length === 0);
|
|
1205
|
+
function validate() {
|
|
1206
|
+
const res = validateFields(fields, data());
|
|
1207
|
+
errors.set(res.errors);
|
|
1208
|
+
return res.valid;
|
|
1209
|
+
}
|
|
1210
|
+
function handleChange(newData) {
|
|
1211
|
+
const next = applyComputedValues(fields, newData);
|
|
1212
|
+
data.set(next);
|
|
1213
|
+
isDirty.set(true);
|
|
1214
|
+
if (validateOnChange) {
|
|
1215
|
+
const res = validateFields(fields, next);
|
|
1216
|
+
errors.set(res.errors);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function setFieldValue(name, value) {
|
|
1220
|
+
handleChange({ ...data(), [name]: value });
|
|
1221
|
+
}
|
|
1222
|
+
function setFieldTouched(name, isTouched = true) {
|
|
1223
|
+
touched.set({ ...touched(), [name]: isTouched });
|
|
1224
|
+
}
|
|
1225
|
+
function handleBlur(fieldName) {
|
|
1226
|
+
setFieldTouched(fieldName, true);
|
|
1227
|
+
if (validateOnBlur) {
|
|
1228
|
+
const res = validateFields(fields, data());
|
|
1229
|
+
errors.set(res.errors);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
function reset(newValues) {
|
|
1233
|
+
const seed = newValues ?? initialValues;
|
|
1234
|
+
const next = applyComputedValues(fields, seed);
|
|
1235
|
+
data.set(next);
|
|
1236
|
+
errors.set({});
|
|
1237
|
+
isDirty.set(false);
|
|
1238
|
+
touched.set({});
|
|
1239
|
+
isSubmitting.set(false);
|
|
1240
|
+
isSubmitted.set(false);
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Returns a submit handler, mirroring the React and Vue `useDynamicForm`
|
|
1244
|
+
* hooks. Bind it once and use it as the `(ngSubmit)` handler:
|
|
1245
|
+
* `onSubmit = this.store.handleSubmit(data => ...)`.
|
|
1246
|
+
*/
|
|
1247
|
+
function handleSubmit(onValid, onInvalid) {
|
|
1248
|
+
return async (e) => {
|
|
1249
|
+
if (e && typeof e.preventDefault === 'function') {
|
|
1250
|
+
e.preventDefault();
|
|
1251
|
+
}
|
|
1252
|
+
isSubmitting.set(true);
|
|
1253
|
+
try {
|
|
1254
|
+
const res = validateFields(fields, data());
|
|
1255
|
+
errors.set(res.errors);
|
|
1256
|
+
isSubmitted.set(true);
|
|
1257
|
+
if (res.valid) {
|
|
1258
|
+
await onValid(data());
|
|
1259
|
+
}
|
|
1260
|
+
else if (onInvalid) {
|
|
1261
|
+
onInvalid(res.errors);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
finally {
|
|
1265
|
+
isSubmitting.set(false);
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
return {
|
|
1270
|
+
data,
|
|
1271
|
+
errors,
|
|
1272
|
+
isValid,
|
|
1273
|
+
isDirty,
|
|
1274
|
+
touched,
|
|
1275
|
+
isSubmitting,
|
|
1276
|
+
isSubmitted,
|
|
1277
|
+
setFieldValue,
|
|
1278
|
+
setFieldTouched,
|
|
1279
|
+
handleChange,
|
|
1280
|
+
handleBlur,
|
|
1281
|
+
reset,
|
|
1282
|
+
validate,
|
|
1283
|
+
handleSubmit,
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
|
|
742
1287
|
class LayoutRegistry {
|
|
743
1288
|
layouts = new Map();
|
|
744
1289
|
register(type, component) {
|
|
@@ -759,8 +1304,8 @@ class ColumnLayout {
|
|
|
759
1304
|
get gap() {
|
|
760
1305
|
return this.config?.gap ?? 12;
|
|
761
1306
|
}
|
|
762
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
763
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
1307
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ColumnLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1308
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: ColumnLayout, isStandalone: true, selector: "dfk-column-layout", inputs: { config: "config", template: "template" }, ngImport: i0, template: `<div
|
|
764
1309
|
[style.display]="'flex'"
|
|
765
1310
|
[style.flexDirection]="'column'"
|
|
766
1311
|
[style.gap]="gap + 'px'"
|
|
@@ -768,7 +1313,7 @@ class ColumnLayout {
|
|
|
768
1313
|
<ng-container *ngTemplateOutlet="template"></ng-container>
|
|
769
1314
|
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
770
1315
|
}
|
|
771
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
1316
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ColumnLayout, decorators: [{
|
|
772
1317
|
type: Component,
|
|
773
1318
|
args: [{
|
|
774
1319
|
selector: 'dfk-column-layout',
|
|
@@ -793,8 +1338,8 @@ class RowLayout {
|
|
|
793
1338
|
get gap() {
|
|
794
1339
|
return this.config?.gap ?? 12;
|
|
795
1340
|
}
|
|
796
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
797
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
1341
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: RowLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1342
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: RowLayout, isStandalone: true, selector: "dfk-row-layout", inputs: { config: "config", template: "template" }, ngImport: i0, template: `<div
|
|
798
1343
|
[style.display]="'flex'"
|
|
799
1344
|
[style.flexDirection]="'row'"
|
|
800
1345
|
[style.gap]="gap + 'px'"
|
|
@@ -802,7 +1347,7 @@ class RowLayout {
|
|
|
802
1347
|
<ng-container *ngTemplateOutlet="template"></ng-container>
|
|
803
1348
|
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
804
1349
|
}
|
|
805
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
1350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: RowLayout, decorators: [{
|
|
806
1351
|
type: Component,
|
|
807
1352
|
args: [{
|
|
808
1353
|
selector: 'dfk-row-layout',
|
|
@@ -830,8 +1375,8 @@ class GridLayout {
|
|
|
830
1375
|
get gap() {
|
|
831
1376
|
return this.config?.gap ?? 12;
|
|
832
1377
|
}
|
|
833
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
834
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.
|
|
1378
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: GridLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1379
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: GridLayout, isStandalone: true, selector: "dfk-grid-layout", inputs: { config: "config", template: "template" }, ngImport: i0, template: `<div
|
|
835
1380
|
[style.display]="'grid'"
|
|
836
1381
|
[style.gridTemplateColumns]="'repeat(' + columns + ', 1fr)'"
|
|
837
1382
|
[style.gap]="gap + 'px'"
|
|
@@ -839,7 +1384,7 @@ class GridLayout {
|
|
|
839
1384
|
<ng-container *ngTemplateOutlet="template"></ng-container>
|
|
840
1385
|
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
841
1386
|
}
|
|
842
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
1387
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: GridLayout, decorators: [{
|
|
843
1388
|
type: Component,
|
|
844
1389
|
args: [{
|
|
845
1390
|
selector: 'dfk-grid-layout',
|
|
@@ -863,8 +1408,8 @@ layoutRegistry.register('row', RowLayout);
|
|
|
863
1408
|
layoutRegistry.register('grid', GridLayout);
|
|
864
1409
|
|
|
865
1410
|
class DynamicFieldKitModule {
|
|
866
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.
|
|
867
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.
|
|
1411
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicFieldKitModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1412
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.25", ngImport: i0, type: DynamicFieldKitModule, imports: [CommonModule,
|
|
868
1413
|
DynamicInput,
|
|
869
1414
|
FieldInput,
|
|
870
1415
|
MultiFieldInput,
|
|
@@ -876,7 +1421,7 @@ class DynamicFieldKitModule {
|
|
|
876
1421
|
ColumnLayout,
|
|
877
1422
|
RowLayout,
|
|
878
1423
|
GridLayout] });
|
|
879
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.
|
|
1424
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicFieldKitModule, imports: [CommonModule,
|
|
880
1425
|
DynamicInput,
|
|
881
1426
|
FieldInput,
|
|
882
1427
|
MultiFieldInput,
|
|
@@ -884,7 +1429,7 @@ class DynamicFieldKitModule {
|
|
|
884
1429
|
RowLayout,
|
|
885
1430
|
GridLayout] });
|
|
886
1431
|
}
|
|
887
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.
|
|
1432
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicFieldKitModule, decorators: [{
|
|
888
1433
|
type: NgModule,
|
|
889
1434
|
args: [{
|
|
890
1435
|
imports: [
|
|
@@ -914,5 +1459,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
914
1459
|
* Generated bundle index. Do not edit.
|
|
915
1460
|
*/
|
|
916
1461
|
|
|
917
|
-
export { BaseInputComponent, ColumnLayout, DynamicFieldKitModule, DynamicInput, FIELD_REGISTRY, FieldInput, GridLayout, LayoutRegistry, MultiFieldInput, RowLayout, layoutRegistry };
|
|
918
|
-
//# sourceMappingURL=dynamic-field-kit-angular.mjs.map
|
|
1462
|
+
export { BaseInputComponent, ColumnLayout, DynamicFieldKitModule, DynamicFormDevToolsComponent, DynamicInput, FIELD_REGISTRY, FieldInput, GridLayout, LayoutRegistry, MultiFieldInput, RowLayout, createDynamicFormStore, layoutRegistry };
|