@websolutespa/bom-mixer-forms 0.0.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/dist/index.mjs ADDED
@@ -0,0 +1,1080 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ var __async = (__this, __arguments, generator) => {
18
+ return new Promise((resolve, reject) => {
19
+ var fulfilled = (value) => {
20
+ try {
21
+ step(generator.next(value));
22
+ } catch (e) {
23
+ reject(e);
24
+ }
25
+ };
26
+ var rejected = (value) => {
27
+ try {
28
+ step(generator.throw(value));
29
+ } catch (e) {
30
+ reject(e);
31
+ }
32
+ };
33
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
34
+ step((generator = generator.apply(__this, __arguments)).next());
35
+ });
36
+ };
37
+
38
+ // src/forms/event-emitter.ts
39
+ var EventEmitter = class {
40
+ constructor() {
41
+ this.events_ = {};
42
+ }
43
+ on(event, listener) {
44
+ if (typeof this.events_[event] !== "object") {
45
+ this.events_[event] = [];
46
+ }
47
+ this.events_[event].push(listener);
48
+ }
49
+ off(event, listener) {
50
+ if (typeof this.events_[event] === "object") {
51
+ const index = this.events_[event].indexOf(listener);
52
+ if (index > -1) {
53
+ this.events_[event].splice(index, 1);
54
+ }
55
+ } else {
56
+ throw new Error(`Can't remove a listener. Event "${event}" doesn't exits.`);
57
+ }
58
+ }
59
+ emit(event, ...args) {
60
+ if (typeof this.events_[event] === "object") {
61
+ this.events_[event].forEach((listener) => listener.apply(this, args));
62
+ }
63
+ }
64
+ once(event, listener) {
65
+ const onceListener = (...args) => {
66
+ this.off(event, onceListener);
67
+ listener.apply(this, args);
68
+ };
69
+ this.on(event, onceListener);
70
+ }
71
+ };
72
+
73
+ // src/forms/utils.ts
74
+ function validValue(value) {
75
+ return value !== void 0 && value !== "" ? value : null;
76
+ }
77
+ function isThenable(result) {
78
+ return result && typeof result.then === "function";
79
+ }
80
+ function mapErrors_(errors) {
81
+ return Object.keys(errors).map((key) => ({ key, value: errors[key] }));
82
+ }
83
+ function deepCopy(source) {
84
+ if (Array.isArray(source)) {
85
+ return source.map((x) => deepCopy(x));
86
+ } else if (source && typeof source === "object") {
87
+ const copy = {};
88
+ Object.keys(source).forEach((key) => {
89
+ copy[key] = deepCopy(source[key]);
90
+ });
91
+ return copy;
92
+ } else {
93
+ return source;
94
+ }
95
+ }
96
+ function valueToString(value) {
97
+ function mapValue(value2) {
98
+ const stringValue = value2 != null ? typeof value2 === "object" ? value2.id.toString() : value2.toString() : void 0;
99
+ return stringValue;
100
+ }
101
+ function mapValues(values) {
102
+ const strings = values.map((x) => mapValue(x)).filter((x) => x !== void 0);
103
+ return strings.length ? strings : void 0;
104
+ }
105
+ return Array.isArray(value) ? mapValues(value) : mapValue(value);
106
+ }
107
+ function stringToValue(value, options, optionsExtra) {
108
+ function findValue(value2) {
109
+ const option = options == null ? void 0 : options.find((x) => x.id.toString() === value2);
110
+ return option ? (optionsExtra == null ? void 0 : optionsExtra.asEquatable) ? option.id : option : null;
111
+ }
112
+ function mapValue(value2) {
113
+ return value2 !== void 0 ? findValue(value2) : null;
114
+ }
115
+ function mapValues(values) {
116
+ const mappedValues = values.map((x) => mapValue(x)).filter((x) => x !== null);
117
+ return mappedValues.length ? mappedValues : null;
118
+ }
119
+ return Array.isArray(value) ? mapValues(value) : mapValue(value);
120
+ }
121
+
122
+ // src/forms/form-abstract.ts
123
+ var FormAbstract = class extends EventEmitter {
124
+ constructor(value, validators) {
125
+ super();
126
+ // new
127
+ this.schema = "text";
128
+ this.markAsDirty_ = false;
129
+ this.errors_ = {};
130
+ this.value_ = validValue(value);
131
+ this.validators_ = validators ? Array.isArray(validators) ? validators : [validators] : [];
132
+ this.state_ = {
133
+ invalid: false,
134
+ disabled: false,
135
+ hidden: false,
136
+ readonly: false,
137
+ dirty: false,
138
+ touched: false,
139
+ submitted: false,
140
+ // derived
141
+ valid: true,
142
+ enabled: true,
143
+ visible: true,
144
+ writeable: true,
145
+ pristine: true,
146
+ untouched: true,
147
+ unsubmitted: true
148
+ };
149
+ }
150
+ setInitialOptions(options) {
151
+ this.initialOptions_ = options;
152
+ if (options) {
153
+ if (options.schema) {
154
+ this.schema = options.schema;
155
+ }
156
+ if (options.name) {
157
+ this.name = options.name;
158
+ }
159
+ if (options.label) {
160
+ this.label = options.label;
161
+ }
162
+ if (options.placeholder) {
163
+ this.placeholder = options.placeholder;
164
+ }
165
+ if (options.options) {
166
+ this.options = options.options;
167
+ }
168
+ if (options.optionsExtra) {
169
+ this.optionsExtra = options.optionsExtra;
170
+ }
171
+ if (options.disabled === true || typeof options.disabled === "function") {
172
+ this.state_.disabled = true;
173
+ }
174
+ if (options.readonly === true || typeof options.readonly === "function") {
175
+ this.state_.readonly = true;
176
+ }
177
+ if (options.hidden === true || typeof options.hidden === "function") {
178
+ this.state_.hidden = true;
179
+ }
180
+ }
181
+ }
182
+ checkAsyncState_(root) {
183
+ return __async(this, null, function* () {
184
+ const options = this.initialOptions_;
185
+ let dirty = false;
186
+ if (options) {
187
+ const disabledDirty = yield this.checkAsyncPropState_("disabled", options.disabled, root);
188
+ const hiddenDirty = yield this.checkAsyncPropState_("hidden", options.hidden, root);
189
+ const readonlyDirty = yield this.checkAsyncPropState_("readonly", options.readonly, root);
190
+ dirty = disabledDirty || hiddenDirty || readonlyDirty;
191
+ }
192
+ return dirty;
193
+ });
194
+ }
195
+ checkAsyncPropState_(key, option, root) {
196
+ return __async(this, null, function* () {
197
+ let dirty = false;
198
+ if (typeof option === "function") {
199
+ let result = option(this.value_, root == null ? void 0 : root.value, this, root);
200
+ result = isThenable(result) ? yield result : result;
201
+ if (this.state_[key] !== result) {
202
+ this.state_[key] = result;
203
+ dirty = true;
204
+ }
205
+ }
206
+ return dirty;
207
+ });
208
+ }
209
+ revalidate_() {
210
+ return __async(this, null, function* () {
211
+ if (this.parent) {
212
+ return yield this.parent.revalidate_();
213
+ }
214
+ yield this.validateAndChange_();
215
+ });
216
+ }
217
+ validate_(root) {
218
+ return __async(this, null, function* () {
219
+ let markAsDirty_ = yield this.checkAsyncState_(root);
220
+ let errors = {};
221
+ if (this.validators.length === 0 || this.disabled || this.submitted) {
222
+ this.state_.invalid = false;
223
+ } else {
224
+ const validations = this.validators_.map((x) => x(this.value_, root == null ? void 0 : root.value, this, root)).filter((x) => x);
225
+ const { results, promises } = validations.reduce((p, c) => {
226
+ isThenable(c) ? p.promises.push(c) : p.results.push(c);
227
+ return p;
228
+ }, { results: [], promises: [] });
229
+ promises.forEach((x) => x.then((result) => {
230
+ if (result) {
231
+ this.state_.invalid = true;
232
+ this.errors_ = Object.assign(this.errors_, result);
233
+ this.markAsDirty_ = true;
234
+ this.updateState_();
235
+ this.change_(true);
236
+ }
237
+ }).catch((error) => {
238
+ console.warn("Validation.async.error", error);
239
+ }));
240
+ this.state_.invalid = results.length > 0;
241
+ errors = Object.assign(errors, ...results);
242
+ }
243
+ markAsDirty_ = markAsDirty_ || Object.keys(this.errors_).join(",") !== Object.keys(errors).join(",");
244
+ this.errors_ = errors;
245
+ this.markAsDirty_ = markAsDirty_;
246
+ this.updateState_();
247
+ });
248
+ }
249
+ validateAndChange_(root) {
250
+ return __async(this, null, function* () {
251
+ yield this.validate_(root);
252
+ this.markAsDirty_ = true;
253
+ this.change_();
254
+ });
255
+ }
256
+ updateStateAndChange_() {
257
+ return __async(this, null, function* () {
258
+ this.updateState_();
259
+ this.markAsDirty_ = true;
260
+ this.change_();
261
+ });
262
+ }
263
+ change_(propagate = false) {
264
+ if (!this.markAsDirty_) {
265
+ return;
266
+ }
267
+ this.markAsDirty_ = false;
268
+ this.emit("change", this.value);
269
+ if (propagate && this.parent) {
270
+ this.parent.markAsDirty_ = true;
271
+ this.parent.change_.call(this.parent);
272
+ }
273
+ }
274
+ updateState_() {
275
+ const state = this.state_;
276
+ state.dirty = this.value_ != null;
277
+ state.valid = !state.invalid;
278
+ state.enabled = !state.disabled;
279
+ state.visible = !state.hidden;
280
+ state.writeable = !state.disabled && !state.readonly;
281
+ state.pristine = !state.dirty;
282
+ state.untouched = !state.touched;
283
+ state.unsubmitted = !state.submitted;
284
+ }
285
+ /*
286
+ set changes$(changes) {
287
+ this.changes$_ = changes;
288
+ }
289
+ */
290
+ /*
291
+ bind(callback) {
292
+ const index = this.callbacks_.indexOf(callback);
293
+ if (index === -1) {
294
+ this.callbacks_.push(callback);
295
+ this.revalidate_();
296
+ }
297
+ }
298
+ unbind(callback) {
299
+ const index = this.callbacks_.indexOf(callback);
300
+ if (index !== -1) {
301
+ this.callbacks_.splice(index, 1);
302
+ }
303
+ }
304
+ once(callback) {
305
+ const this_ = this;
306
+ function once() {
307
+ callback();
308
+ this_.unbind(once);
309
+ }
310
+ this.bind(once);
311
+ }
312
+ bindControl(control) {
313
+ const index = this.binds_.indexOf(control);
314
+ if (index === -1) {
315
+ this.binds_.push(control);
316
+ }
317
+ }
318
+ unbindControl(control) {
319
+ const index = this.binds_.indexOf(control);
320
+ if (index !== -1) {
321
+ this.binds_.splice(index, 1);
322
+ }
323
+ }
324
+ */
325
+ reset() {
326
+ this.value_ = null;
327
+ const state = this.state_;
328
+ state.dirty = false;
329
+ state.touched = false;
330
+ state.submitted = false;
331
+ this.revalidate_();
332
+ }
333
+ patch(value) {
334
+ this.value = value;
335
+ }
336
+ addValidators(...validators) {
337
+ this.validators.push(...validators);
338
+ this.revalidate_();
339
+ }
340
+ replaceValidators(...validators) {
341
+ this.validators = validators;
342
+ }
343
+ clearValidators() {
344
+ this.validators = [];
345
+ }
346
+ // getter & setter
347
+ get path() {
348
+ if (this.name != null) {
349
+ return this.parent ? [...this.parent.path, this.name] : [this.name];
350
+ } else {
351
+ return [];
352
+ }
353
+ }
354
+ get root() {
355
+ let parent = this;
356
+ while (parent.parent) {
357
+ parent = parent.parent;
358
+ }
359
+ return parent;
360
+ }
361
+ get label() {
362
+ var _a;
363
+ return this.label_ || ((_a = this.name) == null ? void 0 : _a.toString()) || "";
364
+ }
365
+ set label(label) {
366
+ this.label_ = label;
367
+ }
368
+ get placeholder() {
369
+ return this.placeholder_ || this.label || "";
370
+ }
371
+ set placeholder(placeholder) {
372
+ this.placeholder_ = placeholder;
373
+ }
374
+ get validators() {
375
+ return this.validators_;
376
+ }
377
+ set validators(validators) {
378
+ if (this.validators_ !== validators) {
379
+ this.validators_ = validators;
380
+ this.revalidate_();
381
+ }
382
+ }
383
+ get state() {
384
+ return this.state_;
385
+ }
386
+ get errors() {
387
+ return this.errors_;
388
+ }
389
+ get invalid() {
390
+ return this.state_.invalid;
391
+ }
392
+ get disabled() {
393
+ return this.state_.disabled;
394
+ }
395
+ // internal disabled type boolean | () => boolean | Promise<boolean>
396
+ set disabled(disabled) {
397
+ if (this.state_.disabled !== disabled) {
398
+ this.state_.disabled = disabled;
399
+ this.revalidate_();
400
+ }
401
+ }
402
+ get hidden() {
403
+ return this.state_.hidden;
404
+ }
405
+ set hidden(hidden) {
406
+ if (this.state_.hidden !== hidden) {
407
+ this.state_.hidden = hidden;
408
+ this.revalidate_();
409
+ }
410
+ }
411
+ get readonly() {
412
+ return this.state_.readonly;
413
+ }
414
+ set readonly(readonly) {
415
+ if (this.state_.readonly !== readonly) {
416
+ this.state_.readonly = readonly;
417
+ this.revalidate_();
418
+ }
419
+ }
420
+ get dirty() {
421
+ return this.state_.dirty;
422
+ }
423
+ set dirty(dirty) {
424
+ if (this.state_.dirty !== dirty) {
425
+ this.state_.dirty = dirty;
426
+ this.updateStateAndChange_();
427
+ }
428
+ }
429
+ get touched() {
430
+ return this.state_.touched;
431
+ }
432
+ set touched(touched) {
433
+ if (this.state_.touched !== touched) {
434
+ this.state_.touched = touched;
435
+ this.updateStateAndChange_();
436
+ }
437
+ }
438
+ get submitted() {
439
+ return this.state_.submitted;
440
+ }
441
+ set submitted(submitted) {
442
+ if (this.state_.submitted !== submitted) {
443
+ this.state_.submitted = submitted;
444
+ this.updateStateAndChange_();
445
+ }
446
+ }
447
+ get valid() {
448
+ return this.state_.valid;
449
+ }
450
+ get enabled() {
451
+ return this.state_.enabled;
452
+ }
453
+ get visible() {
454
+ return this.state_.visible;
455
+ }
456
+ get writeable() {
457
+ return this.state_.writeable;
458
+ }
459
+ get pristine() {
460
+ return this.state_.pristine;
461
+ }
462
+ get untouched() {
463
+ return this.state_.untouched;
464
+ }
465
+ get unsubmitted() {
466
+ return this.state_.unsubmitted;
467
+ }
468
+ get value() {
469
+ return this.value_;
470
+ }
471
+ set value(value) {
472
+ value = validValue(value);
473
+ if (this.value_ !== value) {
474
+ this.value_ = value;
475
+ this.state_.submitted = false;
476
+ this.revalidate_();
477
+ }
478
+ }
479
+ /*
480
+ set invalid(invalid) {
481
+ if (this.state_.invalid !== invalid) {
482
+ this.state_.invalid = invalid;
483
+ this.revalidate_();
484
+ }
485
+ }
486
+ */
487
+ };
488
+
489
+ // src/forms/form-control.ts
490
+ var FormControl = class extends FormAbstract {
491
+ constructor(value = null, validators, initialOptions) {
492
+ super(value, validators);
493
+ this.setInitialOptions(initialOptions);
494
+ }
495
+ };
496
+ function formControl(value = null, validators) {
497
+ return new FormControl(value, validators);
498
+ }
499
+
500
+ // src/forms/form-abstract-collection.ts
501
+ var FormAbstractCollection = class extends FormAbstract {
502
+ constructor(controls, validators) {
503
+ super(null, validators);
504
+ this.controls_ = controls;
505
+ this.forEach_((control, key) => {
506
+ this.controls_[key] = this.initControl_(control, key);
507
+ });
508
+ }
509
+ initControl_(controlOrValue, key) {
510
+ const control = controlOrValue instanceof FormAbstract ? controlOrValue : new FormControl(controlOrValue);
511
+ control.name = key;
512
+ control.parent = this;
513
+ control.validators.push(...this.validators);
514
+ return control;
515
+ }
516
+ setInitialOptions(options) {
517
+ this.initialOptions_ = options;
518
+ if (options) {
519
+ if (options.schema) {
520
+ this.schema = options.schema;
521
+ }
522
+ if (options.name) {
523
+ this.name = options.name;
524
+ }
525
+ if (options.label) {
526
+ this.label = options.label;
527
+ }
528
+ if (options.placeholder) {
529
+ this.placeholder = options.placeholder;
530
+ }
531
+ if (options.options) {
532
+ this.options = options.options;
533
+ }
534
+ if (options.optionsExtra) {
535
+ this.optionsExtra = options.optionsExtra;
536
+ }
537
+ if (options.disabled === true || typeof options.disabled === "function") {
538
+ this.forEach_((control) => {
539
+ control.state_.disabled = true;
540
+ });
541
+ }
542
+ if (options.readonly === true || typeof options.readonly === "function") {
543
+ this.forEach_((control) => {
544
+ control.state_.readonly = true;
545
+ });
546
+ }
547
+ if (options.hidden === true || typeof options.hidden === "function") {
548
+ this.forEach_((control) => {
549
+ control.state_.hidden = true;
550
+ });
551
+ }
552
+ }
553
+ this.updateState_();
554
+ }
555
+ checkAsyncPropState_(key, option, root) {
556
+ return __async(this, null, function* () {
557
+ let dirty = false;
558
+ if (typeof option === "function") {
559
+ let result = option(this.value_, root == null ? void 0 : root.value, this, root);
560
+ result = isThenable(result) ? yield result : result;
561
+ this.forEach_((control) => {
562
+ if (control.state_[key] !== result) {
563
+ control.state_[key] = result;
564
+ dirty = true;
565
+ }
566
+ });
567
+ }
568
+ return dirty;
569
+ });
570
+ }
571
+ updateState_() {
572
+ const state = this.state_;
573
+ let invalid = false;
574
+ let disabled = true;
575
+ let hidden = true;
576
+ let readonly = true;
577
+ let dirty = false;
578
+ let touched = true;
579
+ let submitted = true;
580
+ this.forEach_((control) => {
581
+ invalid = invalid || control.invalid;
582
+ disabled = disabled && control.disabled;
583
+ hidden = hidden && control.hidden;
584
+ readonly = readonly && control.readonly;
585
+ dirty = dirty || control.dirty;
586
+ touched = touched && control.touched;
587
+ submitted = submitted && control.submitted;
588
+ });
589
+ state.invalid = invalid;
590
+ state.disabled = disabled;
591
+ state.hidden = hidden;
592
+ state.readonly = readonly;
593
+ state.dirty = dirty;
594
+ state.touched = touched;
595
+ state.submitted = submitted;
596
+ state.valid = !invalid;
597
+ state.enabled = !disabled;
598
+ state.visible = !hidden;
599
+ state.writeable = !disabled && !readonly;
600
+ state.pristine = !dirty;
601
+ state.untouched = !touched;
602
+ }
603
+ revalidate_() {
604
+ return __async(this, null, function* () {
605
+ if (this.parent) {
606
+ return yield this.parent.revalidate_();
607
+ }
608
+ yield this.validateAndChange_(this);
609
+ });
610
+ }
611
+ validate_(root) {
612
+ return __async(this, null, function* () {
613
+ yield this.checkAsyncState_(root);
614
+ const validations = this.map_().map((x) => x.validateAndChange_(root));
615
+ yield Promise.all(validations);
616
+ this.updateState_();
617
+ });
618
+ }
619
+ reset() {
620
+ this.forEach_((control) => control.reset());
621
+ }
622
+ patch(value) {
623
+ if (value) {
624
+ this.forEach_((control, key) => {
625
+ if (value[key] != null) {
626
+ control.patch(value[key]);
627
+ }
628
+ });
629
+ }
630
+ }
631
+ get(key) {
632
+ const controls = this.controls;
633
+ return controls[key];
634
+ }
635
+ set(control, key) {
636
+ const controls = this.controls;
637
+ delete controls[key];
638
+ controls[key] = this.initControl_(control, key);
639
+ }
640
+ // !!! needed?
641
+ add(control, key) {
642
+ const controls = this.controls;
643
+ controls[key] = this.initControl_(control, key);
644
+ }
645
+ remove(control) {
646
+ this.forEach_((c, k) => {
647
+ if (c === control) {
648
+ this.removeKey(k);
649
+ }
650
+ });
651
+ }
652
+ /*
653
+ remove(control: FormAbstract): void {
654
+ const key = Object.keys(this.controls_).find((key: keyof T) => (this.controls_[key] === control ? key : null));
655
+ if (key) {
656
+ this.removeKey(key);
657
+ }
658
+ }
659
+ */
660
+ removeKey(key) {
661
+ const exhist = this.controls[key] !== void 0;
662
+ delete this.controls_[key];
663
+ }
664
+ addValidators(...validators) {
665
+ this.forEach_((control) => control.addValidators(...validators));
666
+ }
667
+ replaceValidators(...validators) {
668
+ this.forEach_((control) => control.replaceValidators(...validators));
669
+ }
670
+ clearValidators() {
671
+ this.forEach_((control) => control.clearValidators());
672
+ }
673
+ forEach_(callback) {
674
+ const controls = this.controls;
675
+ Object.keys(controls).forEach((key) => callback(controls[key], key));
676
+ }
677
+ reduce_(callback, result) {
678
+ this.forEach_((control, key) => {
679
+ result = callback(result, control, key);
680
+ });
681
+ return result;
682
+ }
683
+ all_(key, value) {
684
+ return this.reduce_((result, control) => {
685
+ return result && control[key] === value;
686
+ }, true);
687
+ }
688
+ any_(key, value) {
689
+ return this.reduce_((result, control) => {
690
+ return result || control[key] === value;
691
+ }, false);
692
+ }
693
+ map_() {
694
+ const controls = this.controls;
695
+ return Object.keys(controls).map((key) => controls[key]);
696
+ }
697
+ // getter & setter
698
+ get controls() {
699
+ return this.controls_;
700
+ }
701
+ set controls(controls) {
702
+ if (this.controls_ !== controls) {
703
+ this.controls_ = controls;
704
+ this.revalidate_();
705
+ }
706
+ }
707
+ set disabled(disabled) {
708
+ this.forEach_((control) => {
709
+ control.disabled = disabled;
710
+ });
711
+ }
712
+ set readonly(readonly) {
713
+ this.forEach_((control) => {
714
+ control.readonly = readonly;
715
+ });
716
+ }
717
+ set hidden(hidden) {
718
+ this.forEach_((control) => {
719
+ control.hidden = hidden;
720
+ });
721
+ }
722
+ set submitted(submitted) {
723
+ this.forEach_((control) => {
724
+ control.submitted = submitted;
725
+ });
726
+ }
727
+ set touched(touched) {
728
+ this.forEach_((control) => {
729
+ control.touched = touched;
730
+ });
731
+ }
732
+ get value() {
733
+ return this.reduce_((result, control, key) => {
734
+ if (control.enabled) {
735
+ result[key] = control.value;
736
+ }
737
+ return result;
738
+ }, {});
739
+ }
740
+ set value(value) {
741
+ this.forEach_((control, key) => {
742
+ control.value = value[key];
743
+ });
744
+ }
745
+ get errors() {
746
+ return this.reduce_((result, control) => {
747
+ return Object.assign(result, control.errors);
748
+ }, {});
749
+ }
750
+ set errors(errors) {
751
+ }
752
+ };
753
+
754
+ // src/forms/form-array.ts
755
+ var FormArray = class extends FormAbstractCollection {
756
+ constructor(controls = [], validators, initialOptions) {
757
+ super(controls, validators);
758
+ this.setInitialOptions(initialOptions);
759
+ }
760
+ forEach_(callback) {
761
+ this.controls.forEach((control, key) => callback(control, key));
762
+ }
763
+ map_() {
764
+ return this.controls;
765
+ }
766
+ get value() {
767
+ return this.reduce_((result, control, key) => {
768
+ result[key] = control.value;
769
+ return result;
770
+ }, []);
771
+ }
772
+ get length() {
773
+ return this.controls.length;
774
+ }
775
+ init(control, key) {
776
+ this.controls.length = Math.max(this.controls.length, key);
777
+ this.controls[key] = this.initControl_(control, key);
778
+ }
779
+ set(control, key) {
780
+ this.controls.splice(key, 1, this.initControl_(control, key));
781
+ }
782
+ add(control, key) {
783
+ this.controls.length = Math.max(this.controls.length, key);
784
+ this.controls[key] = this.initControl_(control, key);
785
+ }
786
+ push(control) {
787
+ this.controls.push(this.initControl_(control, this.controls.length));
788
+ }
789
+ insert(control, key) {
790
+ this.controls.splice(key, 0, this.initControl_(control, key));
791
+ }
792
+ remove(control) {
793
+ const key = this.controls.indexOf(control);
794
+ if (key !== -1) {
795
+ this.removeKey(key);
796
+ }
797
+ }
798
+ removeKey(key) {
799
+ if (this.controls.length > key) {
800
+ this.controls.splice(key, 1);
801
+ }
802
+ }
803
+ at(key) {
804
+ return this.controls[key];
805
+ }
806
+ };
807
+ function formArray(controls = [], validators) {
808
+ return new FormArray(controls, validators);
809
+ }
810
+
811
+ // src/forms/form-group.ts
812
+ var FormGroup = class extends FormAbstractCollection {
813
+ constructor(controls = {}, validators, initialOptions) {
814
+ super(controls, validators);
815
+ this.setInitialOptions(initialOptions);
816
+ }
817
+ };
818
+ function formGroup(controls = {}, validators) {
819
+ return new FormGroup(controls, validators);
820
+ }
821
+
822
+ // src/forms/validators/email.validator.ts
823
+ function EmailValidator() {
824
+ const regex = /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
825
+ return function(value) {
826
+ if (!value) {
827
+ return null;
828
+ }
829
+ return regex.test(value) ? null : { email: true };
830
+ };
831
+ }
832
+
833
+ // src/forms/validators/match.validator.ts
834
+ function MatchValidator(getOtherValue) {
835
+ return function(value, rootValue, control, root) {
836
+ let otherValue = getOtherValue(value, rootValue, control, root);
837
+ otherValue = validValue(otherValue);
838
+ return value !== otherValue ? { match: { value, match: otherValue } } : null;
839
+ };
840
+ }
841
+
842
+ // src/forms/validators/max-length.validator.ts
843
+ function MaxLengthValidator(maxlength) {
844
+ return function(value) {
845
+ if (value == null || maxlength == null) {
846
+ return null;
847
+ }
848
+ const length = value ? value.length : 0;
849
+ return length > maxlength ? { minlength: { requiredLength: maxlength, actualLength: length } } : null;
850
+ };
851
+ }
852
+
853
+ // src/forms/validators/max.validator.ts
854
+ function MaxValidator(max) {
855
+ return function(value) {
856
+ if (value == null || max == null) {
857
+ return null;
858
+ }
859
+ value = parseFloat(value);
860
+ return !isNaN(value) && value > max ? { max: { max, actual: value } } : null;
861
+ };
862
+ }
863
+
864
+ // src/forms/validators/min-length.validator.ts
865
+ function MinLengthValidator(minlength) {
866
+ return function(value) {
867
+ if (value == null || minlength == null) {
868
+ return null;
869
+ }
870
+ const length = value ? value.length : 0;
871
+ return length < minlength ? { minlength: { requiredLength: minlength, actualLength: length } } : null;
872
+ };
873
+ }
874
+
875
+ // src/forms/validators/min.validator.ts
876
+ function MinValidator(min) {
877
+ return function(value) {
878
+ if (value == null || min == null) {
879
+ return null;
880
+ }
881
+ value = parseFloat(value);
882
+ return !isNaN(value) && value < min ? { min: { min, actual: value } } : null;
883
+ };
884
+ }
885
+
886
+ // src/forms/validators/null.validator.ts
887
+ function NullValidator() {
888
+ return function(value) {
889
+ return null;
890
+ };
891
+ }
892
+
893
+ // src/forms/validators/pattern.validator.ts
894
+ function PatternValidator(pattern) {
895
+ return function(value) {
896
+ if (value == null || pattern == null) {
897
+ return null;
898
+ }
899
+ const regex = patternToRegEx(pattern);
900
+ return regex.test(value) ? null : { pattern: { requiredPattern: regex.toString(), actualValue: value } };
901
+ };
902
+ }
903
+ function patternToRegEx(pattern) {
904
+ let regex;
905
+ if (pattern instanceof RegExp) {
906
+ regex = pattern;
907
+ } else if (typeof pattern === "string") {
908
+ pattern = pattern.charAt(0) === "^" ? pattern : `^${pattern}`;
909
+ pattern = pattern.charAt(pattern.length - 1) === "$" ? pattern : `${pattern}$`;
910
+ regex = new RegExp(pattern);
911
+ }
912
+ return regex || new RegExp("");
913
+ }
914
+
915
+ // src/forms/validators/required-if.validator.ts
916
+ function RequiredIfValidator(condition) {
917
+ return function(value, rootValue, control, root) {
918
+ if (Boolean(condition(value, rootValue, control, root)) === true) {
919
+ return value == null || value.length === 0 ? { required: true } : null;
920
+ } else {
921
+ return null;
922
+ }
923
+ };
924
+ }
925
+
926
+ // src/forms/validators/required-true.validator.ts
927
+ function RequiredTrueValidator() {
928
+ return function(value) {
929
+ return value === true ? null : { required: true };
930
+ };
931
+ }
932
+
933
+ // src/forms/validators/required.validator.ts
934
+ function RequiredValidator() {
935
+ return function(value) {
936
+ return value == null || value.length === 0 ? { required: true } : null;
937
+ };
938
+ }
939
+
940
+ // src/hooks/useControl/useControl.ts
941
+ import { useCallback, useEffect, useState } from "react";
942
+ function useControl(control) {
943
+ const [state, setState] = useState({
944
+ value: control.value,
945
+ flags: control.state,
946
+ errors: mapErrors_(control.errors)
947
+ });
948
+ const setValue = useCallback((value) => {
949
+ control.patch(value);
950
+ }, [control]);
951
+ const setTouched = useCallback(() => {
952
+ control.touched = true;
953
+ }, [control]);
954
+ const reset = useCallback(() => {
955
+ control.reset();
956
+ }, [control]);
957
+ useEffect(() => {
958
+ const onChange = (value) => {
959
+ const newState = { value, flags: control.state, errors: mapErrors_(control.errors) };
960
+ setState(newState);
961
+ };
962
+ control.on("change", onChange);
963
+ return () => control.off("change", onChange);
964
+ }, [control]);
965
+ return [state, setValue, setTouched, reset, control];
966
+ }
967
+
968
+ // src/hooks/useForm/useForm.ts
969
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
970
+ function useForm(factory, deps = []) {
971
+ const collection = useMemo(factory, deps);
972
+ const setValue = useCallback2((value) => {
973
+ collection.patch(value);
974
+ }, deps);
975
+ const setTouched = useCallback2(() => {
976
+ collection.touched = true;
977
+ }, deps);
978
+ const reset = useCallback2(() => {
979
+ collection.reset();
980
+ }, deps);
981
+ const [state, setState] = useState2({ value: collection.value, flags: collection.state, errors: mapErrors_(collection.errors) });
982
+ useEffect2(() => {
983
+ const onChange = (value) => {
984
+ const newState = { value, flags: collection.state, errors: mapErrors_(collection.errors) };
985
+ setState(newState);
986
+ };
987
+ collection.on("change", onChange);
988
+ collection.validateAndChange_();
989
+ return () => collection.off("change", onChange);
990
+ }, deps);
991
+ return [state, setValue, setTouched, reset, collection];
992
+ }
993
+
994
+ // src/hooks/useFormBuilder/useFormBuilder.ts
995
+ import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
996
+ function useFormBuilder(schema, deps = []) {
997
+ const collection = useMemo2(() => {
998
+ if (Array.isArray(schema)) {
999
+ return mapArray_(schema);
1000
+ } else {
1001
+ return mapGroup_(schema);
1002
+ }
1003
+ }, deps);
1004
+ const setValue = useCallback3((value) => {
1005
+ collection.patch(value);
1006
+ }, deps);
1007
+ const setTouched = useCallback3(() => {
1008
+ collection.touched = true;
1009
+ }, deps);
1010
+ const reset = useCallback3(() => {
1011
+ collection.reset();
1012
+ }, deps);
1013
+ const [state, setState] = useState3({ value: collection.value, flags: collection.state, errors: mapErrors_(collection.errors) });
1014
+ useEffect3(() => {
1015
+ const onChange = (value) => {
1016
+ const newState = { value, flags: collection.state, errors: mapErrors_(collection.errors) };
1017
+ setState(newState);
1018
+ };
1019
+ collection.on("change", onChange);
1020
+ collection.validateAndChange_();
1021
+ return () => collection.off("change", onChange);
1022
+ }, deps);
1023
+ return [state, setValue, setTouched, reset, collection];
1024
+ }
1025
+ function mapGroup_(children, schema) {
1026
+ const controls = {};
1027
+ Object.keys(children).forEach((key) => {
1028
+ controls[key] = mapSchema_(__spreadValues({ name: key }, children[key]));
1029
+ });
1030
+ const group = new FormGroup(controls, schema == null ? void 0 : schema.validators, schema);
1031
+ return group;
1032
+ }
1033
+ function mapArray_(children, schema) {
1034
+ const controls = children.map((x) => mapSchema_(x));
1035
+ const array = new FormArray(controls, schema == null ? void 0 : schema.validators, schema);
1036
+ return array;
1037
+ }
1038
+ function mapControl_(schema) {
1039
+ return new FormControl(schema.value, schema.validators, schema);
1040
+ }
1041
+ function mapSchema_(schema) {
1042
+ switch (schema.schema) {
1043
+ case "group":
1044
+ return mapGroup_(schema.children || {}, schema);
1045
+ case "array":
1046
+ return mapArray_(schema.children || [], schema);
1047
+ default:
1048
+ return mapControl_(schema);
1049
+ }
1050
+ }
1051
+ export {
1052
+ EmailValidator,
1053
+ FormAbstract,
1054
+ FormAbstractCollection,
1055
+ FormArray,
1056
+ FormControl,
1057
+ FormGroup,
1058
+ MatchValidator,
1059
+ MaxLengthValidator,
1060
+ MaxValidator,
1061
+ MinLengthValidator,
1062
+ MinValidator,
1063
+ NullValidator,
1064
+ PatternValidator,
1065
+ RequiredIfValidator,
1066
+ RequiredTrueValidator,
1067
+ RequiredValidator,
1068
+ deepCopy,
1069
+ formArray,
1070
+ formControl,
1071
+ formGroup,
1072
+ isThenable,
1073
+ mapErrors_,
1074
+ stringToValue,
1075
+ useControl,
1076
+ useForm,
1077
+ useFormBuilder,
1078
+ validValue,
1079
+ valueToString
1080
+ };