@rxdi/forms 0.7.215 → 0.7.217

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/README.md CHANGED
@@ -154,6 +154,8 @@ this.form.patchValue({
154
154
  }
155
155
  });
156
156
  // Only updates 'isActive', leaves other fields untouched.
157
+ ````
158
+
157
159
  ### Dynamic Array Inputs (FormArray)
158
160
 
159
161
  For lists of primitive values, use `FormArray` with an `itemFactory` and automatic model binding. This removes the need for manual population.
@@ -88,15 +88,14 @@ class FormArray {
88
88
  unsubscribe() {
89
89
  this.subscriptions.forEach((sub) => sub.unsubscribe());
90
90
  this.subscriptions.clear();
91
- this.controls.forEach((c) => c.unsubscribe && c.unsubscribe());
91
+ this.controls.forEach((c) => { var _a; return (_a = c.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(c); });
92
92
  }
93
93
  updateValue() {
94
94
  this._valueChanges.next(this.value);
95
95
  }
96
96
  requestUpdate() {
97
- if (this.parentElement) {
98
- this.parentElement.requestUpdate();
99
- }
97
+ var _a;
98
+ (_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.requestUpdate();
100
99
  }
101
100
  setParentElement(parent) {
102
101
  this.parentElement = parent;
@@ -118,9 +117,7 @@ class FormArray {
118
117
  return;
119
118
  }
120
119
  values.forEach((v, i) => {
121
- if (this.controls[i]) {
122
- this.controls[i].value = v;
123
- }
120
+ this.controls[i] && (this.controls[i].value = v);
124
121
  });
125
122
  this.updateValue();
126
123
  }
@@ -129,13 +126,9 @@ class FormArray {
129
126
  return;
130
127
  }
131
128
  values.forEach((v, i) => {
132
- if (this.controls[i]) {
133
- if (this.controls[i]['patchValue']) {
134
- this.controls[i]['patchValue'](v);
135
- }
136
- else {
137
- this.controls[i].value = v;
138
- }
129
+ const control = this.controls[i];
130
+ if (control) {
131
+ control.patchValue ? control.patchValue(v) : (control.value = v);
139
132
  }
140
133
  else if (this.options.itemFactory) {
141
134
  this.push(this.options.itemFactory(v));
@@ -1,5 +1,5 @@
1
1
  import { LitElement } from '@rxdi/lit-html';
2
- import { AbstractControl, AbstractInput, ErrorObject, FormInputOptions, FormOptions, NestedKeyOf, UnwrapValue, ValidatorFn, DeepPropType } from './form.tokens';
2
+ import { AbstractControl, AbstractInput, DeepPropType, ErrorObject, FormInputOptions, FormOptions, NestedKeyOf, UnwrapValue, ValidatorFn } from './form.tokens';
3
3
  export declare class FormGroup<T = FormInputOptions, E = {
4
4
  [key: string]: never;
5
5
  }> implements AbstractControl<UnwrapValue<T>> {
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.FormGroup = void 0;
13
13
  const rxjs_1 = require("rxjs");
14
+ const operators_1 = require("rxjs/operators");
14
15
  const form_tokens_1 = require("./form.tokens");
15
16
  class FormGroup {
16
17
  constructor(value, errors) {
@@ -44,12 +45,16 @@ class FormGroup {
44
45
  }
45
46
  });
46
47
  }
48
+ this.prepareValues();
47
49
  }
48
50
  init() {
51
+ if (!this.parentElement) {
52
+ return;
53
+ }
49
54
  this.setFormElement(this.querySelectForm(this.parentElement.shadowRoot || this.parentElement)).setInputs(this.mapEventToInputs(this.querySelectorAllInputs()));
50
55
  this.controls.forEach((c) => {
51
- if (c.init)
52
- c.init();
56
+ var _a;
57
+ (_a = c.init) === null || _a === void 0 ? void 0 : _a.call(c);
53
58
  });
54
59
  }
55
60
  prepareValues() {
@@ -84,9 +89,8 @@ class FormGroup {
84
89
  setParentElement(parent) {
85
90
  this.parentElement = parent;
86
91
  this.controls.forEach((c) => {
87
- if (c.setParentElement) {
88
- c.setParentElement(parent);
89
- }
92
+ var _a;
93
+ (_a = c.setParentElement) === null || _a === void 0 ? void 0 : _a.call(c, parent);
90
94
  });
91
95
  return this;
92
96
  }
@@ -96,9 +100,8 @@ class FormGroup {
96
100
  setOptions(options) {
97
101
  this.options = options;
98
102
  this.controls.forEach((c) => {
99
- if (c.setOptions) {
100
- c.setOptions(Object.assign(Object.assign({}, options), { namespace: this.options.namespace ? `${this.options.namespace}.${c.name}` : c.name }));
101
- }
103
+ var _a;
104
+ (_a = c.setOptions) === null || _a === void 0 ? void 0 : _a.call(c, Object.assign(Object.assign({}, options), { namespace: this.options.namespace ? `${this.options.namespace}.${c.name}` : c.name }));
102
105
  });
103
106
  return this;
104
107
  }
@@ -200,6 +203,9 @@ class FormGroup {
200
203
  if (this.options['form']) {
201
204
  return this.options['form'];
202
205
  }
206
+ if (!(shadowRoot === null || shadowRoot === void 0 ? void 0 : shadowRoot.querySelector)) {
207
+ return null;
208
+ }
203
209
  const form = shadowRoot.querySelector(`form[name="${this.options.name}"]`);
204
210
  if (!form) {
205
211
  throw new Error(`Form element with name "${this.options.name}" not present inside ${this.getParentElement().outerHTML} component`);
@@ -335,11 +341,37 @@ class FormGroup {
335
341
  const names = String(name).split('.');
336
342
  const key = names.shift();
337
343
  const control = this.controls.get(key);
338
- if (control && control.get) {
344
+ if (control === null || control === void 0 ? void 0 : control.get) {
339
345
  return control.get(names.join('.'));
340
346
  }
341
347
  }
342
- return this.inputs.get(name);
348
+ const input = this.inputs.get(name);
349
+ if (input) {
350
+ return input;
351
+ }
352
+ /*
353
+ If a user tries to subscribe on a constructor level or before the inputs are inside the DOM
354
+ We create a fake Virtual Input so later on when elements present on stage to get the same subscription
355
+ */
356
+ const key = name;
357
+ // Check if key exists in the model value even if not in inputs map
358
+ if (this._valueChanges.getValue() && key in this._valueChanges.getValue()) {
359
+ // Create a "Virtual" AbstractInput to prevent crashes and allow subscription even if no DOM element present
360
+ return {
361
+ valueChanges: this._valueChanges.pipe((0, operators_1.map)((value) => value === null || value === void 0 ? void 0 : value[key]), (0, operators_1.distinctUntilChanged)()),
362
+ value: this.getValue(key),
363
+ name: String(key),
364
+ valid: true,
365
+ invalid: false,
366
+ dirty: false,
367
+ touched: false,
368
+ // Mock HTMLInputElement properties to satisfy interface if needed
369
+ type: 'text',
370
+ checked: false,
371
+ disabled: false,
372
+ };
373
+ }
374
+ return undefined;
343
375
  }
344
376
  getError(inputName, errorKey) {
345
377
  return this.errors[inputName][errorKey];
@@ -390,8 +422,9 @@ class FormGroup {
390
422
  return;
391
423
  }
392
424
  Object.keys(value).forEach((key) => {
393
- if (this.controls.has(key) && this.controls.get(key)['patchValue']) {
394
- this.controls.get(key)['patchValue'](value[key]);
425
+ const control = this.controls.get(key);
426
+ if (control === null || control === void 0 ? void 0 : control['patchValue']) {
427
+ control['patchValue'](value[key]);
395
428
  }
396
429
  else {
397
430
  this.setValue(key, value[key]);
@@ -417,8 +450,8 @@ class FormGroup {
417
450
  setFormElement(form) {
418
451
  this.form = form;
419
452
  this.controls.forEach((c) => {
420
- if (c.setFormElement)
421
- c.setFormElement(form);
453
+ var _a;
454
+ (_a = c.setFormElement) === null || _a === void 0 ? void 0 : _a.call(c, form);
422
455
  });
423
456
  return this;
424
457
  }
@@ -426,6 +459,7 @@ class FormGroup {
426
459
  this.inputs = new Map(inputs.map((e) => {
427
460
  const key = this.getModelKeyName(e.name);
428
461
  e.value = this.getValue(key);
462
+ e.valueChanges = this._valueChanges.pipe((0, operators_1.map)((value) => value === null || value === void 0 ? void 0 : value[key]), (0, operators_1.distinctUntilChanged)());
429
463
  return [key, e];
430
464
  }));
431
465
  }
@@ -6,10 +6,10 @@ export type UnwrapValue<T> = T extends AbstractControl<infer U> ? U : T extends
6
6
  [K in keyof T]: UnwrapValue<T[K]>;
7
7
  } : T;
8
8
  type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];
9
- export type NestedKeyOf<T, D extends number = 3> = [D] extends [0] ? never : T extends object ? {
9
+ export type NestedKeyOf<T, D extends number = 3> = [D] extends [0] ? never : T extends Array<any> ? never : T extends object ? {
10
10
  [K in keyof T & (string | number)]: T[K] extends AbstractControl<infer U> ? U extends object ? `${K}` | `${K}.${NestedKeyOf<U, Prev[D]>}` : `${K}` : T[K] extends object ? `${K}` | `${K}.${NestedKeyOf<T[K], Prev[D]>}` : `${K}`;
11
11
  }[keyof T & (string | number)] : never;
12
- export type DeepPropType<T, P extends string> = P extends keyof T ? T[P] : P extends `${infer K}.${infer R}` ? K extends keyof T ? DeepPropType<T[K], R> : any : any;
12
+ export type DeepPropType<T, P extends string> = P extends keyof T ? T[P] extends [infer V, ValidatorFn[]] ? AbstractInput<V> : T[P] extends (infer U)[] ? AbstractInput<U> : T[P] extends string | number | boolean ? AbstractInput<T[P]> : T[P] : P extends `${infer K}.${infer R}` ? K extends keyof T ? DeepPropType<T[K], R> : any : any;
13
13
  export type FormStrategies = keyof WindowEventMap;
14
14
  export interface FormOptions {
15
15
  /** Name of the form element */
@@ -19,7 +19,7 @@ export interface FormOptions {
19
19
  /** Multiple input elements like checkboxes with the same name will be binded together */
20
20
  multi?: boolean;
21
21
  /** When set to true `.valueChanges` will emit values only
22
- * if current input validation passes, default behavior is to emit every change fro */
22
+ * if current input validation passes, default behavior is to emit every change on the form */
23
23
  strict?: boolean;
24
24
  /**
25
25
  * When set form will expand capabilities by selecting another custom element made as a form element
@@ -63,11 +63,12 @@ export interface ErrorObject {
63
63
  element: HTMLInputElement;
64
64
  errors: InputErrorMessage[];
65
65
  }
66
- export interface AbstractInput extends HTMLInputElement {
66
+ export interface AbstractInput<T = any> extends HTMLInputElement {
67
67
  valid?: boolean;
68
68
  invalid?: boolean;
69
69
  dirty?: boolean;
70
70
  touched?: boolean;
71
+ valueChanges?: Observable<any>;
71
72
  }
72
73
  export declare const InputValidityState: {
73
74
  badInput: "badInput";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxdi/forms",
3
- "version": "0.7.215",
3
+ "version": "0.7.217",
4
4
  "main": "./dist/index.js",
5
5
  "author": "Kristiyan Tachev",
6
6
  "license": "MIT",
@@ -12,7 +12,7 @@
12
12
  "build": "tsc"
13
13
  },
14
14
  "devDependencies": {
15
- "@rxdi/lit-html": "^0.7.214",
15
+ "@rxdi/lit-html": "^0.7.216",
16
16
  "@types/node": "^25.0.3",
17
17
  "rxjs": "^7.8.2",
18
18
  "typescript": "^5.9.3"