@rxdi/forms 0.7.214 → 0.7.216
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 +105 -40
- package/dist/form.array.d.ts +6 -2
- package/dist/form.array.js +27 -9
- package/dist/form.group.d.ts +2 -2
- package/dist/form.group.js +18 -13
- package/dist/form.tokens.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ interface UserParams {
|
|
|
29
29
|
address: {
|
|
30
30
|
city: string;
|
|
31
31
|
street: string;
|
|
32
|
-
}
|
|
32
|
+
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
@Component({
|
|
@@ -37,14 +37,13 @@ interface UserParams {
|
|
|
37
37
|
template(this: UserProfile) {
|
|
38
38
|
return html`
|
|
39
39
|
<form name="user-form" @submit=${this.onSubmit}>
|
|
40
|
-
|
|
41
40
|
<!-- Deep Binding with Dot Notation -->
|
|
42
41
|
<input
|
|
43
42
|
name="firstName"
|
|
44
43
|
.value=${this.form.value.firstName}
|
|
45
44
|
@blur=${() => this.requestUpdate()}
|
|
46
45
|
/>
|
|
47
|
-
|
|
46
|
+
|
|
48
47
|
<!-- Nested Group Binding -->
|
|
49
48
|
<input
|
|
50
49
|
name="address.city"
|
|
@@ -55,33 +54,32 @@ interface UserParams {
|
|
|
55
54
|
<button type="submit">Save</button>
|
|
56
55
|
</form>
|
|
57
56
|
`;
|
|
58
|
-
}
|
|
57
|
+
},
|
|
59
58
|
})
|
|
60
59
|
export class UserProfile extends LitElement {
|
|
61
|
-
|
|
62
60
|
// Model to bind
|
|
63
61
|
@property({ type: Object })
|
|
64
62
|
user: UserParams = {
|
|
65
63
|
firstName: 'John',
|
|
66
|
-
address: { city: 'New York', street: '5th Ave' }
|
|
64
|
+
address: { city: 'New York', street: '5th Ave' },
|
|
67
65
|
};
|
|
68
66
|
|
|
69
67
|
@Form({
|
|
70
68
|
name: 'user-form',
|
|
71
69
|
strategy: 'change',
|
|
72
|
-
model: 'user' // Automatic Model Binding!
|
|
70
|
+
model: 'user', // Automatic Model Binding!
|
|
73
71
|
})
|
|
74
72
|
form = new FormGroup({
|
|
75
73
|
firstName: '',
|
|
76
74
|
address: new FormGroup({
|
|
77
75
|
city: '',
|
|
78
|
-
street: ''
|
|
79
|
-
})
|
|
76
|
+
street: '',
|
|
77
|
+
}),
|
|
80
78
|
});
|
|
81
79
|
|
|
82
80
|
onSubmit(e: Event) {
|
|
83
81
|
e.preventDefault();
|
|
84
|
-
console.log(this.form.value);
|
|
82
|
+
console.log(this.form.value);
|
|
85
83
|
// Output: { firstName: 'John', address: { city: 'New York', street: '5th Ave' } }
|
|
86
84
|
}
|
|
87
85
|
}
|
|
@@ -90,6 +88,7 @@ export class UserProfile extends LitElement {
|
|
|
90
88
|
## New Features
|
|
91
89
|
|
|
92
90
|
### Automatic Model Binding
|
|
91
|
+
|
|
93
92
|
Use the `model` property in the `@Form` decorator to automatically populate the form from a component property.
|
|
94
93
|
|
|
95
94
|
```typescript
|
|
@@ -99,9 +98,11 @@ Use the `model` property in the `@Form` decorator to automatically populate the
|
|
|
99
98
|
})
|
|
100
99
|
form = new FormGroup({ ... });
|
|
101
100
|
```
|
|
101
|
+
|
|
102
102
|
The library reads `this.myData` during initialization and calls `form.patchValue(this.myData)`.
|
|
103
103
|
|
|
104
104
|
### Nested FormGroups & FormArray
|
|
105
|
+
|
|
105
106
|
You can nest `FormGroup`s arbitrarily deep.
|
|
106
107
|
|
|
107
108
|
```typescript
|
|
@@ -110,25 +111,28 @@ form = new FormGroup({
|
|
|
110
111
|
id: 1,
|
|
111
112
|
flags: new FormGroup({
|
|
112
113
|
isActive: true,
|
|
113
|
-
isAdmin: false
|
|
114
|
-
})
|
|
114
|
+
isAdmin: false,
|
|
115
|
+
}),
|
|
115
116
|
}),
|
|
116
|
-
tags: new FormArray([
|
|
117
|
-
new FormGroup({ label: 'red' })
|
|
118
|
-
])
|
|
117
|
+
tags: new FormArray([new FormGroup({ label: 'red' })]),
|
|
119
118
|
});
|
|
120
119
|
```
|
|
121
120
|
|
|
122
121
|
**Template Binding:**
|
|
123
122
|
Use dot notation for nested controls:
|
|
123
|
+
|
|
124
124
|
```html
|
|
125
125
|
<input name="meta.flags.isActive" type="checkbox" />
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
### Type Safety & Autosuggestion
|
|
129
|
+
|
|
129
130
|
The library now extensively uses advanced TypeScript features:
|
|
131
|
+
|
|
130
132
|
- **`form.value`**: Returns the unwrapped pure object type (e.g., `{ meta: { flags: { isActive: boolean } } }`).
|
|
131
|
-
- **`form.get('path.to.prop')`**: Provides autocomplete for deep paths!
|
|
133
|
+
- **`form.get('path.to.prop')`**: Provides autocomplete for deep paths and infers return types!
|
|
134
|
+
- `form.get('key')` returns exact control type (e.g. `FormArray`) without casting.
|
|
135
|
+
|
|
132
136
|
```typescript
|
|
133
137
|
// TypeScript knows this is valid:
|
|
134
138
|
this.form.get('meta.flags.isActive');
|
|
@@ -138,9 +142,10 @@ this.form.get('meta.flags.wrongProp'); // Error!
|
|
|
138
142
|
```
|
|
139
143
|
|
|
140
144
|
### Recursive PatchValue
|
|
145
|
+
|
|
141
146
|
Update multiple fields deeply at once:
|
|
142
147
|
|
|
143
|
-
|
|
148
|
+
````typescript
|
|
144
149
|
this.form.patchValue({
|
|
145
150
|
meta: {
|
|
146
151
|
flags: {
|
|
@@ -149,11 +154,79 @@ this.form.patchValue({
|
|
|
149
154
|
}
|
|
150
155
|
});
|
|
151
156
|
// Only updates 'isActive', leaves other fields untouched.
|
|
152
|
-
|
|
157
|
+
````
|
|
158
|
+
|
|
159
|
+
### Dynamic Array Inputs (FormArray)
|
|
160
|
+
|
|
161
|
+
For lists of primitive values, use `FormArray` with an `itemFactory` and automatic model binding. This removes the need for manual population.
|
|
162
|
+
|
|
163
|
+
#### Full Working Example
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { Component, html, LitElement, property } from '@rxdi/lit-html';
|
|
167
|
+
import { Form, FormGroup, FormArray } from '@rxdi/forms';
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@Component({
|
|
171
|
+
selector: 'tags-component',
|
|
172
|
+
template(this: TagsComponent) {
|
|
173
|
+
return html`
|
|
174
|
+
<form @submit=${(e) => e.preventDefault()}>
|
|
175
|
+
<h3>Tags</h3>
|
|
176
|
+
|
|
177
|
+
<!-- List Tags -->
|
|
178
|
+
${this.form.get('tags').controls.map(
|
|
179
|
+
(control, index) => html`
|
|
180
|
+
<div class="tag-row">
|
|
181
|
+
<input name="tags[${index}].value" .value=${control.value.value} @blur=${() => this.requestUpdate()} />
|
|
182
|
+
<button type="button" @click=${() => this.removeTag(index)}>Remove</button>
|
|
183
|
+
</div>
|
|
184
|
+
`
|
|
185
|
+
)}
|
|
186
|
+
|
|
187
|
+
<button type="button" @click=${() => this.addTag()}>Add Tag</button>
|
|
188
|
+
<button type="button" @click=${() => this.onSubmit()}>Submit</button>
|
|
189
|
+
</form>
|
|
190
|
+
`;
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
export class TagsComponent extends LitElement {
|
|
194
|
+
// Model automatically binds to 'tags' in form
|
|
195
|
+
@property({ type: Array })
|
|
196
|
+
tags = ['news', 'tech'];
|
|
197
|
+
|
|
198
|
+
@Form({
|
|
199
|
+
name: 'tags-form',
|
|
200
|
+
model: 'tags', // Triggers form.patchValue(this.tags) on INIT
|
|
201
|
+
})
|
|
202
|
+
form = new FormGroup({
|
|
203
|
+
tags: new FormArray<{ value: string }>([], {
|
|
204
|
+
name: 'tags',
|
|
205
|
+
// Factory describes how to create new controls from model data
|
|
206
|
+
itemFactory: (value) => new FormGroup({ value: value.value || value }),
|
|
207
|
+
}),
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
addTag() {
|
|
211
|
+
this.form.get('tags').push(new FormGroup({ value: '' }));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
removeTag(index: number) {
|
|
215
|
+
this.form.get('tags').removeAt(index);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
onSubmit() {
|
|
219
|
+
const dirtyTags = this.form.value.tags;
|
|
220
|
+
console.log(dirtyTags.map((t) => t.value));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
````
|
|
153
225
|
|
|
154
226
|
## API Reference
|
|
155
227
|
|
|
156
228
|
### Validators
|
|
229
|
+
|
|
157
230
|
Validators are async functions returning `InputErrorMessage` or `void`.
|
|
158
231
|
|
|
159
232
|
```typescript
|
|
@@ -165,11 +238,12 @@ export function CustomValidator(element: AbstractInput) {
|
|
|
165
238
|
|
|
166
239
|
// Usage
|
|
167
240
|
new FormGroup({
|
|
168
|
-
field: ['', [CustomValidator]]
|
|
169
|
-
})
|
|
241
|
+
field: ['', [CustomValidator]],
|
|
242
|
+
});
|
|
170
243
|
```
|
|
171
244
|
|
|
172
245
|
### Error Display Information
|
|
246
|
+
|
|
173
247
|
Use the `touched` and `validity.valid` properties for clean UI.
|
|
174
248
|
|
|
175
249
|
```typescript
|
|
@@ -200,15 +274,9 @@ form = new FormGroup({
|
|
|
200
274
|
```
|
|
201
275
|
|
|
202
276
|
```html
|
|
203
|
-
<label>
|
|
204
|
-
|
|
205
|
-
</label>
|
|
206
|
-
<label>
|
|
207
|
-
<input name="roles" type="checkbox" value="editor" /> Editor
|
|
208
|
-
</label>
|
|
209
|
-
<label>
|
|
210
|
-
<input name="roles" type="checkbox" value="viewer" /> Viewer
|
|
211
|
-
</label>
|
|
277
|
+
<label> <input name="roles" type="checkbox" value="admin" /> Admin </label>
|
|
278
|
+
<label> <input name="roles" type="checkbox" value="editor" /> Editor </label>
|
|
279
|
+
<label> <input name="roles" type="checkbox" value="viewer" /> Viewer </label>
|
|
212
280
|
```
|
|
213
281
|
|
|
214
282
|
If the user checks "Admin" and "Viewer", `form.value.roles` will be `['admin', 'viewer']`.
|
|
@@ -228,13 +296,10 @@ form = new FormGroup({
|
|
|
228
296
|
```
|
|
229
297
|
|
|
230
298
|
```html
|
|
231
|
-
<label>
|
|
232
|
-
|
|
233
|
-
</label>
|
|
234
|
-
<label>
|
|
235
|
-
<input name="mode" type="checkbox" value="light" /> Light
|
|
236
|
-
</label>
|
|
299
|
+
<label> <input name="mode" type="checkbox" value="dark" /> Dark </label>
|
|
300
|
+
<label> <input name="mode" type="checkbox" value="light" /> Light </label>
|
|
237
301
|
```
|
|
302
|
+
|
|
238
303
|
Checking "Dark" unchecks "Light" automatically.
|
|
239
304
|
|
|
240
305
|
### 3. Framework-Agnostic Usage (Vanilla JS)
|
|
@@ -246,7 +311,7 @@ import { FormGroup } from '@rxdi/forms';
|
|
|
246
311
|
|
|
247
312
|
const form = new FormGroup({
|
|
248
313
|
email: '',
|
|
249
|
-
password: ''
|
|
314
|
+
password: '',
|
|
250
315
|
});
|
|
251
316
|
|
|
252
317
|
// manually attach to DOM
|
|
@@ -259,7 +324,7 @@ form
|
|
|
259
324
|
.setInputs(form.mapEventToInputs(form.querySelectorAllInputs()));
|
|
260
325
|
|
|
261
326
|
// Listen to changes
|
|
262
|
-
form.valueChanges.subscribe(val => console.log(val));
|
|
327
|
+
form.valueChanges.subscribe((val) => console.log(val));
|
|
263
328
|
```
|
|
264
329
|
|
|
265
330
|
### 4. Custom Error Handling Strategies
|
|
@@ -284,7 +349,7 @@ async validateEmail(element: HTMLInputElement) {
|
|
|
284
349
|
}
|
|
285
350
|
|
|
286
351
|
// In Template
|
|
287
|
-
${this.form.hasError('email', 'emailExists')
|
|
288
|
-
? html`<div class="error">Email taken!</div>`
|
|
352
|
+
${this.form.hasError('email', 'emailExists')
|
|
353
|
+
? html`<div class="error">Email taken!</div>`
|
|
289
354
|
: ''}
|
|
290
|
-
```
|
|
355
|
+
```
|
package/dist/form.array.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { LitElement } from '@rxdi/lit-html';
|
|
2
2
|
import { BehaviorSubject } from 'rxjs';
|
|
3
3
|
import { AbstractControl, FormOptions } from './form.tokens';
|
|
4
|
+
export interface FormArrayOptions<T = any> extends FormOptions {
|
|
5
|
+
itemFactory?: (value: T) => AbstractControl;
|
|
6
|
+
}
|
|
4
7
|
export declare class FormArray<T = any> implements AbstractControl<T[]> {
|
|
5
8
|
controls: AbstractControl<T>[];
|
|
6
9
|
readonly valueChanges: BehaviorSubject<T[]>;
|
|
@@ -13,9 +16,9 @@ export declare class FormArray<T = any> implements AbstractControl<T[]> {
|
|
|
13
16
|
private form;
|
|
14
17
|
private options;
|
|
15
18
|
private subscriptions;
|
|
16
|
-
constructor(controls?: AbstractControl<T>[],
|
|
19
|
+
constructor(controls?: AbstractControl<T>[], nameOrOptions?: string | FormArrayOptions<T>);
|
|
17
20
|
get value(): T[];
|
|
18
|
-
getOptions():
|
|
21
|
+
getOptions(): FormArrayOptions<T>;
|
|
19
22
|
setOptions(options: FormOptions): void;
|
|
20
23
|
push(control: AbstractControl<T>): Promise<void>;
|
|
21
24
|
removeAt(index: number): void;
|
|
@@ -28,4 +31,5 @@ export declare class FormArray<T = any> implements AbstractControl<T[]> {
|
|
|
28
31
|
init(): void;
|
|
29
32
|
getParentElement(): LitElement;
|
|
30
33
|
set value(values: T[]);
|
|
34
|
+
patchValue(values: T[]): void;
|
|
31
35
|
}
|
package/dist/form.array.js
CHANGED
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.FormArray = void 0;
|
|
13
13
|
const rxjs_1 = require("rxjs");
|
|
14
14
|
class FormArray {
|
|
15
|
-
constructor(controls = [],
|
|
15
|
+
constructor(controls = [], nameOrOptions = '') {
|
|
16
16
|
this.controls = [];
|
|
17
17
|
this.valid = true;
|
|
18
18
|
this.invalid = false;
|
|
@@ -20,7 +20,13 @@ class FormArray {
|
|
|
20
20
|
this.options = {};
|
|
21
21
|
this.subscriptions = new Map();
|
|
22
22
|
this.controls = controls;
|
|
23
|
-
|
|
23
|
+
if (typeof nameOrOptions === 'string') {
|
|
24
|
+
this.name = nameOrOptions;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.name = nameOrOptions.name || '';
|
|
28
|
+
this.options = nameOrOptions;
|
|
29
|
+
}
|
|
24
30
|
this._valueChanges = new rxjs_1.BehaviorSubject(this.value);
|
|
25
31
|
this.valueChanges = this._valueChanges;
|
|
26
32
|
this.controls.forEach((c) => this.subscribeToControl(c));
|
|
@@ -32,7 +38,7 @@ class FormArray {
|
|
|
32
38
|
return this.options;
|
|
33
39
|
}
|
|
34
40
|
setOptions(options) {
|
|
35
|
-
this.options = options;
|
|
41
|
+
this.options = Object.assign(Object.assign({}, this.options), options);
|
|
36
42
|
this.controls.forEach((c, index) => {
|
|
37
43
|
c.setOptions(Object.assign(Object.assign({}, options), { namespace: `${this.name}[${index}]` }));
|
|
38
44
|
});
|
|
@@ -82,15 +88,14 @@ class FormArray {
|
|
|
82
88
|
unsubscribe() {
|
|
83
89
|
this.subscriptions.forEach((sub) => sub.unsubscribe());
|
|
84
90
|
this.subscriptions.clear();
|
|
85
|
-
this.controls.forEach((c) => c.unsubscribe
|
|
91
|
+
this.controls.forEach((c) => { var _a; return (_a = c.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(c); });
|
|
86
92
|
}
|
|
87
93
|
updateValue() {
|
|
88
94
|
this._valueChanges.next(this.value);
|
|
89
95
|
}
|
|
90
96
|
requestUpdate() {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
97
|
+
var _a;
|
|
98
|
+
(_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.requestUpdate();
|
|
94
99
|
}
|
|
95
100
|
setParentElement(parent) {
|
|
96
101
|
this.parentElement = parent;
|
|
@@ -112,8 +117,21 @@ class FormArray {
|
|
|
112
117
|
return;
|
|
113
118
|
}
|
|
114
119
|
values.forEach((v, i) => {
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
this.controls[i] && (this.controls[i].value = v);
|
|
121
|
+
});
|
|
122
|
+
this.updateValue();
|
|
123
|
+
}
|
|
124
|
+
patchValue(values) {
|
|
125
|
+
if (!Array.isArray(values)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
values.forEach((v, i) => {
|
|
129
|
+
const control = this.controls[i];
|
|
130
|
+
if (control) {
|
|
131
|
+
control.patchValue ? control.patchValue(v) : (control.value = v);
|
|
132
|
+
}
|
|
133
|
+
else if (this.options.itemFactory) {
|
|
134
|
+
this.push(this.options.itemFactory(v));
|
|
117
135
|
}
|
|
118
136
|
});
|
|
119
137
|
this.updateValue();
|
package/dist/form.group.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement } from '@rxdi/lit-html';
|
|
2
|
-
import { AbstractControl, AbstractInput, ErrorObject, FormInputOptions, FormOptions, NestedKeyOf, UnwrapValue, ValidatorFn } 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>> {
|
|
@@ -38,7 +38,7 @@ export declare class FormGroup<T = FormInputOptions, E = {
|
|
|
38
38
|
private getModelKeyName;
|
|
39
39
|
validate(element: AbstractInput): Promise<ErrorObject>;
|
|
40
40
|
private mapInputErrors;
|
|
41
|
-
get<K extends NestedKeyOf<T>>(name: K):
|
|
41
|
+
get<K extends NestedKeyOf<T>>(name: K): DeepPropType<T, K>;
|
|
42
42
|
getError(inputName: keyof T, errorKey: string): never;
|
|
43
43
|
hasError(inputName: keyof T, errorKey: string): boolean;
|
|
44
44
|
reset(): void;
|
package/dist/form.group.js
CHANGED
|
@@ -46,10 +46,13 @@ class FormGroup {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
init() {
|
|
49
|
+
if (!this.parentElement) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
49
52
|
this.setFormElement(this.querySelectForm(this.parentElement.shadowRoot || this.parentElement)).setInputs(this.mapEventToInputs(this.querySelectorAllInputs()));
|
|
50
53
|
this.controls.forEach((c) => {
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
var _a;
|
|
55
|
+
(_a = c.init) === null || _a === void 0 ? void 0 : _a.call(c);
|
|
53
56
|
});
|
|
54
57
|
}
|
|
55
58
|
prepareValues() {
|
|
@@ -84,9 +87,8 @@ class FormGroup {
|
|
|
84
87
|
setParentElement(parent) {
|
|
85
88
|
this.parentElement = parent;
|
|
86
89
|
this.controls.forEach((c) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
+
var _a;
|
|
91
|
+
(_a = c.setParentElement) === null || _a === void 0 ? void 0 : _a.call(c, parent);
|
|
90
92
|
});
|
|
91
93
|
return this;
|
|
92
94
|
}
|
|
@@ -96,9 +98,8 @@ class FormGroup {
|
|
|
96
98
|
setOptions(options) {
|
|
97
99
|
this.options = options;
|
|
98
100
|
this.controls.forEach((c) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
101
|
+
var _a;
|
|
102
|
+
(_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
103
|
});
|
|
103
104
|
return this;
|
|
104
105
|
}
|
|
@@ -200,6 +201,9 @@ class FormGroup {
|
|
|
200
201
|
if (this.options['form']) {
|
|
201
202
|
return this.options['form'];
|
|
202
203
|
}
|
|
204
|
+
if (!(shadowRoot === null || shadowRoot === void 0 ? void 0 : shadowRoot.querySelector)) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
203
207
|
const form = shadowRoot.querySelector(`form[name="${this.options.name}"]`);
|
|
204
208
|
if (!form) {
|
|
205
209
|
throw new Error(`Form element with name "${this.options.name}" not present inside ${this.getParentElement().outerHTML} component`);
|
|
@@ -335,7 +339,7 @@ class FormGroup {
|
|
|
335
339
|
const names = String(name).split('.');
|
|
336
340
|
const key = names.shift();
|
|
337
341
|
const control = this.controls.get(key);
|
|
338
|
-
if (control
|
|
342
|
+
if (control === null || control === void 0 ? void 0 : control.get) {
|
|
339
343
|
return control.get(names.join('.'));
|
|
340
344
|
}
|
|
341
345
|
}
|
|
@@ -390,8 +394,9 @@ class FormGroup {
|
|
|
390
394
|
return;
|
|
391
395
|
}
|
|
392
396
|
Object.keys(value).forEach((key) => {
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
const control = this.controls.get(key);
|
|
398
|
+
if (control === null || control === void 0 ? void 0 : control['patchValue']) {
|
|
399
|
+
control['patchValue'](value[key]);
|
|
395
400
|
}
|
|
396
401
|
else {
|
|
397
402
|
this.setValue(key, value[key]);
|
|
@@ -417,8 +422,8 @@ class FormGroup {
|
|
|
417
422
|
setFormElement(form) {
|
|
418
423
|
this.form = form;
|
|
419
424
|
this.controls.forEach((c) => {
|
|
420
|
-
|
|
421
|
-
|
|
425
|
+
var _a;
|
|
426
|
+
(_a = c.setFormElement) === null || _a === void 0 ? void 0 : _a.call(c, form);
|
|
422
427
|
});
|
|
423
428
|
return this;
|
|
424
429
|
}
|
package/dist/form.tokens.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];
|
|
|
9
9
|
export type NestedKeyOf<T, D extends number = 3> = [D] extends [0] ? 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
13
|
export type FormStrategies = keyof WindowEventMap;
|
|
13
14
|
export interface FormOptions {
|
|
14
15
|
/** Name of the form element */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rxdi/forms",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.216",
|
|
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.
|
|
15
|
+
"@rxdi/lit-html": "^0.7.215",
|
|
16
16
|
"@types/node": "^25.0.3",
|
|
17
17
|
"rxjs": "^7.8.2",
|
|
18
18
|
"typescript": "^5.9.3"
|