@reactables/forms 0.6.0-alpha.0 → 0.7.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -33
- package/dist/Helpers/buildHub2Source.d.ts +2 -2
- package/dist/Models/Configs.d.ts +1 -0
- package/dist/Models/Payloads.d.ts +4 -4
- package/dist/Models/index.d.ts +1 -1
- package/dist/Reducers/Hub1/addControl.d.ts +2 -2
- package/dist/Reducers/Hub1/markControlAsTouched.d.ts +2 -2
- package/dist/Reducers/Hub1/pushControl.d.ts +2 -2
- package/dist/Reducers/Hub1/updateAncestorValues.d.ts +2 -2
- package/dist/Reducers/Hub1/updateAncestorValuesAddControl.d.ts +2 -2
- package/dist/Reducers/Hub1/updateValues.d.ts +2 -2
- package/dist/RxForm/RxForm.d.ts +19 -15
- package/dist/RxForm/Tests/customReducers.test.d.ts +1 -0
- package/dist/RxForm/Tests/initialization.test.d.ts +1 -0
- package/dist/RxForm/Tests/markControlAsPristine.test.d.ts +1 -0
- package/dist/RxForm/Tests/markControlTouchStatus.test.d.ts +1 -0
- package/dist/RxForm/Tests/pushControl.test.d.ts +1 -0
- package/dist/RxForm/Tests/removeControl.test.d.ts +1 -0
- package/dist/RxForm/Tests/resetControl.test.d.ts +1 -0
- package/dist/RxForm/Tests/updateValues.test.d.ts +1 -0
- package/dist/index.js +47 -37
- package/package.json +2 -2
- /package/dist/RxForm/{RxForm.test.d.ts → Tests/addControl.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,25 +1,33 @@
|
|
|
1
|
-
# Reactable Forms
|
|
1
|
+
# Reactable Forms
|
|
2
2
|
|
|
3
3
|
## Description
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Reactive forms with [Reactables](https://github.com/reactables/reactables/tree/main/packages/core).
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
9
|
1. [Installation](#installation)
|
|
10
|
-
1. [Examples](#examples)
|
|
11
|
-
1. [Form Control](#form-control)
|
|
12
|
-
1. [Form Array](#form-array)
|
|
13
|
-
1. [Form Group](#form-group)
|
|
14
|
-
|
|
15
10
|
1. [API](#api)
|
|
16
11
|
1. [RxActions](#api-actions)
|
|
12
|
+
1. [updateValues](#api-actions-update-values)
|
|
13
|
+
1. [addControl](#api-actions-add-conrtrol)
|
|
14
|
+
1. [pushControl](#api-actions-push-control)
|
|
15
|
+
1. [removeControl](#api-actions-remove-control)
|
|
16
|
+
1. [markControlAsPristine](#api-actions-mark-as-pristine)
|
|
17
|
+
1. [markControlAsTouched](#api-actions-mark-as-touched)
|
|
18
|
+
1. [markControlAsUntouched](#api-actions-mark-as-untouched)
|
|
19
|
+
1. [resetControl](#api-actions-resetControl)
|
|
17
20
|
1. [build](#api-build)
|
|
21
|
+
1. [RxFormOptions](#api-form-options)
|
|
18
22
|
1. [control](#api-control)
|
|
19
23
|
1. [group](#api-group)
|
|
20
24
|
1. [array](#api-array)
|
|
21
|
-
1. [Other Interfaces](#interfaces)
|
|
22
|
-
1. [
|
|
25
|
+
1. [Other Interfaces](#api-interfaces)
|
|
26
|
+
1. [Form](#api-form)
|
|
27
|
+
1. [FormControl](#api-form-control)
|
|
28
|
+
1. [ControlRef](#api-control-ref)
|
|
29
|
+
1. [FormErrors](#api-form-errors)
|
|
30
|
+
1. [FormReducers](#api-form-reducers)
|
|
23
31
|
|
|
24
32
|
|
|
25
33
|
## Installation <a name="installation"></a>
|
|
@@ -28,10 +36,6 @@ Installation will require [RxJS](https://rxjs.dev/) if not already installed.
|
|
|
28
36
|
|
|
29
37
|
`npm i rxjs @reactables/forms`
|
|
30
38
|
|
|
31
|
-
## Examples <a name="examples"></a>
|
|
32
|
-
|
|
33
|
-
WIP
|
|
34
|
-
|
|
35
39
|
## API <a name="api"></a>
|
|
36
40
|
|
|
37
41
|
The API for building Reactable Forms is very similar to [Angular FormBuilder](https://angular.io/api/forms/FormBuilder). It has been adapted to support Reactable features.
|
|
@@ -40,28 +44,130 @@ The API for building Reactable Forms is very similar to [Angular FormBuilder](ht
|
|
|
40
44
|
|
|
41
45
|
Actions available to trigger state changes on Reactable.
|
|
42
46
|
|
|
47
|
+
#### `updateValues` <a name="api-actions-update-values"></a>
|
|
48
|
+
|
|
49
|
+
Updates value of a [`FormControl`](#api-form-control). For form group and form arrays, update will only occur if specified descendant controls exists. Otherwise it will throw an error.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
type updateValues = <T>(payload: UpdateValuesPayload<T>) => void;
|
|
53
|
+
|
|
54
|
+
export interface UpdateValuesPayload<T> {
|
|
55
|
+
value: T;
|
|
56
|
+
controlRef: ControlRef;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### `addControl` <a name="api-actions-add-control"></a>
|
|
62
|
+
|
|
63
|
+
Adds a control to a form group.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
type addControl = (payload: AddControlPayload) => void;
|
|
67
|
+
|
|
68
|
+
export interface AddControlPayload {
|
|
69
|
+
config: AbstractControlConfig;
|
|
70
|
+
controlRef: ControlRef;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### `pushControl` <a name="api-actions-push-control"></a>
|
|
76
|
+
|
|
77
|
+
Pushes a control to a form array.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
type pushControl = (payload: PushControlPayload) => void;
|
|
81
|
+
|
|
82
|
+
export interface PushControlPayload {
|
|
83
|
+
config: AbstractControlConfig;
|
|
84
|
+
controlRef: ControlRef;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `removeControl` <a name="api-actions-remove-control"></a>
|
|
90
|
+
|
|
91
|
+
Removes a specified control from form.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
type removeControl = (payload: ControlRef) => void;
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### `markControlAsPristine` <a name="api-actions-mark-as-pristine"></a>
|
|
99
|
+
|
|
100
|
+
Marks a control and all descendant controls as pristine.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
type markControlAsPristine = (payload: ControlRef) => void;
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### `markControlAsTouched` <a name="api-actions-mark-as-touched"></a>
|
|
108
|
+
|
|
109
|
+
Marks a control and all ancestors as touched. Can pass a `markAll` true to mark all descendants as touched as well.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
type markControlAsTouched = (payload: MarkTouchedPayload) => void;
|
|
113
|
+
|
|
114
|
+
export interface MarkTouchedPayload {
|
|
115
|
+
controlRef: ControlRef;
|
|
116
|
+
markAll?: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### `markControlAsUntouched` <a name="api-actions-mark-as-untouched"></a>
|
|
122
|
+
|
|
123
|
+
Marks a control and all descendants as untouched. Will recheck ancestors controls and update touched status.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
type markControlAsUnTouched = (payload: ControlRef) => void;
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### `resetControl` <a name="api-actions-resetControl"></a>
|
|
131
|
+
|
|
132
|
+
Marks a control and all descendants as untouched. Will recheck ancestors controls and update touched status.
|
|
133
|
+
|
|
43
134
|
```typescript
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
addControl: (payload: AddControl) => void;
|
|
47
|
-
pushControl: (payload: PushControl) => void;
|
|
48
|
-
removeControl: (payload: ControlRef) => void;
|
|
49
|
-
markControlAsPristine: (payload: ControlRef) => void;
|
|
50
|
-
markControlAsTouched: (payload: MarkTouched) => void;
|
|
51
|
-
markControlAsUntouched: (payload: ControlRef) => void;
|
|
52
|
-
resetControl: (payload: ControlRef) => void;
|
|
53
|
-
};
|
|
135
|
+
type resetControls = (payload: ControlRef) => void;
|
|
136
|
+
|
|
54
137
|
```
|
|
55
138
|
|
|
56
139
|
### `build` <a name="api-build"></a>
|
|
57
140
|
|
|
58
141
|
```typescript
|
|
59
|
-
type build = (config: AbstractControlConfig, options?:
|
|
142
|
+
type build = (config: AbstractControlConfig, options?: RxFormOptions) => Reactable<Form<unknown>, RxFormActions>
|
|
60
143
|
```
|
|
61
144
|
|
|
62
|
-
Factory method for creating a form Reactable. Accepts a configuration object generated by one or more helper methods - [`control`](#api-control), [`group`](#api-group), [`array`](#api-array).
|
|
145
|
+
Factory method for creating a form Reactable. Accepts a configuration object generated by one or more helper methods - [`control`](#api-control), [`group`](#api-group), [`array`](#api-array). Also accepts an `RxFormOptions` object.
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
#### `RxFormOptions` <a name="api-form-options"></a>
|
|
149
|
+
|
|
150
|
+
Options to customize RxForm behaviour.
|
|
63
151
|
|
|
64
|
-
|
|
152
|
+
```typescript
|
|
153
|
+
interface RxFormOptions {
|
|
154
|
+
reducers?: { [key:string]: CustomReducer }
|
|
155
|
+
effects?: Effect<unknown, unknown>[];
|
|
156
|
+
sources?: Observable<Action<unknown>>[] | { [key: string]: Observable<unknown> };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
type CustomReducer = (
|
|
160
|
+
reducers: FormReducers,
|
|
161
|
+
state: BaseFormState<unknown>,
|
|
162
|
+
action: Action<unknown>,
|
|
163
|
+
) => BaseFormState<unknown>;
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
| Property | Description |
|
|
167
|
+
| -------- | ----------- |
|
|
168
|
+
| reducers (optional) | Dictionary of `CustomReducer`s to implement custom form behaviour. The `CustomReducer` provides built in [`FormReducers`](#api-form-reducers). **Form state updates need to be made with [`FormReducers`](#api-form-reducers) to maintain integrity of the form state tree (i.e validation states of parent and child controls)**. |
|
|
169
|
+
| effects (optional) | Array of [Effects](https://github.com/reactables/reactables/tree/main/packages/core#api-effect) to be registered to the Reactable. |
|
|
170
|
+
| sources (optional) | Additional [Action](https://github.com/reactables/reactables/tree/main/packages/core#action-) Observables the Reactable is listening to. Can be an array or a dictionary where key is the action type and value is the Observable emitting the payload. |
|
|
65
171
|
|
|
66
172
|
### `control` <a name="api-control"></a>
|
|
67
173
|
|
|
@@ -105,16 +211,85 @@ interface FormArrayConfig {
|
|
|
105
211
|
}
|
|
106
212
|
```
|
|
107
213
|
|
|
108
|
-
### Other Interfaces <a name="interfaces"></a>
|
|
214
|
+
### Other Interfaces <a name="api-interfaces"></a>
|
|
215
|
+
|
|
216
|
+
#### `Form` <a name="api-form"></a>
|
|
217
|
+
Form state. Dictionary of [`FormControl`](#api-form-control)(s) where the key is a period separated representation of the [`ControlRef`](#api-control-ref) tuple.
|
|
109
218
|
|
|
110
|
-
#### EffectsAndSources <a name="effects-sources"></a>
|
|
111
219
|
```typescript
|
|
112
|
-
interface
|
|
113
|
-
|
|
114
|
-
|
|
220
|
+
export interface Form<T> {
|
|
221
|
+
root?: FormControl<T>;
|
|
222
|
+
[key: string]: FormControl<unknown>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### `FormControl` <a name="api-form-control"></a>
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
|
|
231
|
+
export interface FormControl<T> extends BaseControl<T>, Hub2Fields {
|
|
232
|
+
pristineValue: T;
|
|
233
|
+
controlRef: ControlRef;
|
|
234
|
+
value: T;
|
|
235
|
+
dirty: boolean;
|
|
236
|
+
touched: boolean;
|
|
237
|
+
validatorErrors: FormErrors;
|
|
238
|
+
key: string;
|
|
239
|
+
asyncValidatorErrors: FormErrors;
|
|
240
|
+
asyncValidateInProgress: { [key: string | number]: boolean };
|
|
241
|
+
errors: FormErrors;
|
|
242
|
+
valid: boolean;
|
|
243
|
+
childrenValid: boolean;
|
|
244
|
+
pending?: boolean;
|
|
245
|
+
config: AbstractControlConfig;
|
|
115
246
|
}
|
|
116
247
|
```
|
|
117
248
|
| Property | Description |
|
|
118
249
|
| -------- | ----------- |
|
|
119
|
-
|
|
|
120
|
-
|
|
|
250
|
+
| pristineValue | Original value of control. Use to determine if control is dirty. |
|
|
251
|
+
| controlRef | Controls [`ControlRef`](#api-control-ref). |
|
|
252
|
+
| value | Control value. |
|
|
253
|
+
| touched | Touched status of control |
|
|
254
|
+
| validatorErrors | [`FormErrors`](#api-form-errors) from validators (non-async) |
|
|
255
|
+
| asyncValidatorErrors | [`FormErrors`](#api-form-errors) from async validators |
|
|
256
|
+
| errors | [`FormErrors`](#api-form-errors) validatorErrors and asyncValidatorErrors merged. |
|
|
257
|
+
| valid | Valid status of control. Also checks descendants.
|
|
258
|
+
| childrenValid | Valid status of direct child controls.
|
|
259
|
+
| config | Original config for form control |
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
#### `ControlRef` <a name="api-control-ref"></a>
|
|
264
|
+
|
|
265
|
+
Control Reference represented as a tuple for the [`FormControl`](#api-form-control)
|
|
266
|
+
|
|
267
|
+
#### `FormErrors` <a name="api-form-errors"></a>
|
|
268
|
+
|
|
269
|
+
Dictionary of errors for the control.
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
export interface FormErrors {
|
|
273
|
+
[key: string]: boolean;
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
#### `FormReducers` <a name="api-form-reducers"></a>
|
|
278
|
+
|
|
279
|
+
Built in reducers to be used to update state of form tree. Payload and behaviour is same and descrbed in [`RxActions`](#api-actions);
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
|
|
283
|
+
export interface FormReducers {
|
|
284
|
+
updateValues: <T>(state: BaseFormState<T>, payload: UpdateValuesPayload<unknown>,
|
|
285
|
+
) => BaseFormState<T>;
|
|
286
|
+
removeControl: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
287
|
+
pushControl: <T>(state: BaseFormState<T>, payload: PushControlPayload) => BaseFormState<T>;
|
|
288
|
+
addControl: <T>(state: BaseFormState<T>, payload: AddControlPayload) => BaseFormState<T>;
|
|
289
|
+
markControlAsPristine: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
290
|
+
markControlAsTouched: <T>(state: BaseFormState<T>, payload: MarkTouchedPayload) => BaseFormState<T>;
|
|
291
|
+
markControlAsUntouched: <T>(state: BaseFormState<T>, payload: ControlRef,
|
|
292
|
+
) => BaseFormState<T>;
|
|
293
|
+
resetControl: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
294
|
+
}
|
|
295
|
+
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
|
-
import { Action
|
|
2
|
+
import { Action } from '@reactables/core';
|
|
3
3
|
import { BaseFormState } from '../Models/Controls';
|
|
4
|
-
export declare const buildHub2Source: <T, S>(
|
|
4
|
+
export declare const buildHub2Source: <T, S>(hub1State$: Observable<BaseFormState<T>>) => Observable<Action<T>>;
|
package/dist/Models/Configs.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface FormArrayConfig extends ValidatorConfigs {
|
|
|
13
13
|
}
|
|
14
14
|
export interface FormControlConfig<T> extends ValidatorConfigs {
|
|
15
15
|
initialValue: T;
|
|
16
|
+
normalizers?: ((value: T) => T)[];
|
|
16
17
|
}
|
|
17
18
|
export type AbstractControlConfig = (FormControlConfig<unknown> | FormArrayConfig | FormGroupConfig) & {
|
|
18
19
|
controls?: AbstractControlConfig[] | {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { ControlRef } from './ControlRef';
|
|
2
2
|
import { AbstractControlConfig } from './Configs';
|
|
3
3
|
import { FormErrors } from './FormErrors';
|
|
4
|
-
export interface
|
|
4
|
+
export interface UpdateValuesPayload<T> {
|
|
5
5
|
value: T;
|
|
6
6
|
controlRef: ControlRef;
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
8
|
+
export interface AddControlPayload {
|
|
9
9
|
config: AbstractControlConfig;
|
|
10
10
|
controlRef: ControlRef;
|
|
11
11
|
}
|
|
12
|
-
export interface
|
|
12
|
+
export interface PushControlPayload {
|
|
13
13
|
config: AbstractControlConfig;
|
|
14
14
|
controlRef: ControlRef;
|
|
15
15
|
}
|
|
@@ -18,7 +18,7 @@ export interface ControlAsyncValidationResponse {
|
|
|
18
18
|
validatorIndex: number;
|
|
19
19
|
errors: FormErrors;
|
|
20
20
|
}
|
|
21
|
-
export interface
|
|
21
|
+
export interface MarkTouchedPayload {
|
|
22
22
|
controlRef: ControlRef;
|
|
23
23
|
markAll?: boolean;
|
|
24
24
|
}
|
package/dist/Models/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { AbstractControlConfig, FormArrayConfig, FormGroupConfig, FormControlCon
|
|
|
2
2
|
export { ControlRef } from './ControlRef';
|
|
3
3
|
export * as ControlModels from './Controls';
|
|
4
4
|
export { FormErrors } from './FormErrors';
|
|
5
|
-
export {
|
|
5
|
+
export { UpdateValuesPayload, AddControlPayload, ControlAsyncValidationResponse, MarkTouchedPayload, } from './Payloads';
|
|
6
6
|
export { ValidatorAsyncFn, ValidatorFn } from './Validators';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Action } from '@reactables/core';
|
|
2
2
|
import { BaseFormState } from '../../Models/Controls';
|
|
3
|
-
import {
|
|
4
|
-
export declare const addControl: <T>(state: BaseFormState<T>, action: Action<
|
|
3
|
+
import { AddControlPayload } from '../../Models/Payloads';
|
|
4
|
+
export declare const addControl: <T>(state: BaseFormState<T>, action: Action<AddControlPayload>, mergeChanges?: boolean) => BaseFormState<T>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Action } from '@reactables/core';
|
|
2
2
|
import { BaseFormState } from '../../Models/Controls';
|
|
3
|
-
import {
|
|
4
|
-
export declare const markControlAsTouched: <T>(state: BaseFormState<T>, action: Action<
|
|
3
|
+
import { MarkTouchedPayload } from '../../Models/Payloads';
|
|
4
|
+
export declare const markControlAsTouched: <T>(state: BaseFormState<T>, action: Action<MarkTouchedPayload>, mergeChanges?: boolean) => BaseFormState<T>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Action } from '@reactables/core';
|
|
2
2
|
import { BaseFormState } from '../../Models/Controls';
|
|
3
|
-
import {
|
|
4
|
-
export declare const pushControl: <T>(state: BaseFormState<T>, action: Action<
|
|
3
|
+
import { AddControlPayload } from '../../Models/Payloads';
|
|
4
|
+
export declare const pushControl: <T>(state: BaseFormState<T>, action: Action<AddControlPayload>, mergeChanges?: boolean) => BaseFormState<T>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Action } from '@reactables/core';
|
|
2
2
|
import { BaseForm } from '../../Models/Controls';
|
|
3
|
-
import {
|
|
3
|
+
import { UpdateValuesPayload } from '../../Models/Payloads';
|
|
4
4
|
export declare const UPDATE_ANCESTOR_VALUES = "UPDATE_ANCESTOR_VALUES";
|
|
5
|
-
export declare const updateAncestorValues: <T>(form: BaseForm<T>, { payload: { controlRef, value } }: Action<
|
|
5
|
+
export declare const updateAncestorValues: <T>(form: BaseForm<T>, { payload: { controlRef, value } }: Action<UpdateValuesPayload<unknown>>) => BaseForm<T>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Action } from '@reactables/core';
|
|
2
2
|
import { BaseForm } from '../../Models/Controls';
|
|
3
|
-
import {
|
|
3
|
+
import { UpdateValuesPayload } from '../../Models/Payloads';
|
|
4
4
|
export declare const UPDATE_ANCESTOR_VALUES_ADD_CONTROL = "UPDATE_ANCESTOR_VALUES_ADD_CONTROL";
|
|
5
|
-
export declare const updateAncestorValuesAddControl: <T>(form: BaseForm<T>, { payload: { controlRef, value } }: Action<
|
|
5
|
+
export declare const updateAncestorValuesAddControl: <T>(form: BaseForm<T>, { payload: { controlRef, value } }: Action<UpdateValuesPayload<unknown>>) => BaseForm<T>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Action } from '@reactables/core';
|
|
2
2
|
import { BaseFormState } from '../../Models/Controls';
|
|
3
|
-
import {
|
|
4
|
-
export declare const updateValues: <T>({ form, changedControls, removedControls }: BaseFormState<T>, action: Action<
|
|
3
|
+
import { UpdateValuesPayload } from '../../Models/Payloads';
|
|
4
|
+
export declare const updateValues: <T>({ form, changedControls, removedControls }: BaseFormState<T>, action: Action<UpdateValuesPayload<unknown>>, mergeChanges?: boolean) => BaseFormState<T>;
|
package/dist/RxForm/RxForm.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Reactable, EffectsAndSources, Action } from '@reactables/core';
|
|
2
|
-
import {
|
|
1
|
+
import { Reactable, EffectsAndSources, Action, Effect, ScopedEffects } from '@reactables/core';
|
|
2
|
+
import { UpdateValuesPayload, AddControlPayload, MarkTouchedPayload, PushControlPayload } from '../Models/Payloads';
|
|
3
3
|
import { ControlRef } from '../Models';
|
|
4
4
|
import { FormControlConfig, FormArrayConfig, FormGroupConfig, AbstractControlConfig } from '../Models/Configs';
|
|
5
5
|
import { ValidatorFn, ValidatorAsyncFn } from '../Models/Validators';
|
|
@@ -9,27 +9,31 @@ export declare const control: <T>(config: FormControlConfig<T> | FbControl<T>) =
|
|
|
9
9
|
export declare const array: (config: FormArrayConfig) => FormArrayConfig;
|
|
10
10
|
export declare const group: (config: FormGroupConfig) => FormGroupConfig;
|
|
11
11
|
export type RxFormActions = {
|
|
12
|
-
updateValues: <T>(payload:
|
|
13
|
-
addControl: (payload:
|
|
14
|
-
pushControl: (payload:
|
|
12
|
+
updateValues: <T>(payload: UpdateValuesPayload<T>) => void;
|
|
13
|
+
addControl: (payload: AddControlPayload) => void;
|
|
14
|
+
pushControl: (payload: PushControlPayload) => void;
|
|
15
15
|
removeControl: (payload: ControlRef) => void;
|
|
16
16
|
markControlAsPristine: (payload: ControlRef) => void;
|
|
17
|
-
markControlAsTouched: (payload:
|
|
17
|
+
markControlAsTouched: (payload: MarkTouchedPayload) => void;
|
|
18
18
|
markControlAsUntouched: (payload: ControlRef) => void;
|
|
19
19
|
resetControl: (payload: ControlRef) => void;
|
|
20
20
|
};
|
|
21
21
|
export interface FormReducers {
|
|
22
|
-
updateValues: <T>(state: BaseFormState<T>,
|
|
23
|
-
removeControl: <T>(state: BaseFormState<T>,
|
|
24
|
-
pushControl: <T>(state: BaseFormState<T>,
|
|
25
|
-
addControl: <T>(state: BaseFormState<T>,
|
|
26
|
-
markControlAsPristine: <T>(state: BaseFormState<T>,
|
|
27
|
-
markControlAsTouched: <T>(state: BaseFormState<T>,
|
|
28
|
-
markControlAsUntouched: <T>(state: BaseFormState<T>,
|
|
29
|
-
resetControl: <T>(state: BaseFormState<T>,
|
|
22
|
+
updateValues: <T>(state: BaseFormState<T>, payload: UpdateValuesPayload<unknown>) => BaseFormState<T>;
|
|
23
|
+
removeControl: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
24
|
+
pushControl: <T>(state: BaseFormState<T>, payload: PushControlPayload) => BaseFormState<T>;
|
|
25
|
+
addControl: <T>(state: BaseFormState<T>, payload: AddControlPayload) => BaseFormState<T>;
|
|
26
|
+
markControlAsPristine: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
27
|
+
markControlAsTouched: <T>(state: BaseFormState<T>, payload: MarkTouchedPayload) => BaseFormState<T>;
|
|
28
|
+
markControlAsUntouched: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
29
|
+
resetControl: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
|
|
30
30
|
}
|
|
31
|
+
type CustomReducer = (reducers: FormReducers, state: BaseFormState<unknown>, action: Action<unknown>) => BaseFormState<unknown>;
|
|
31
32
|
export interface CustomReducers {
|
|
32
|
-
[key: string]:
|
|
33
|
+
[key: string]: CustomReducer | {
|
|
34
|
+
reducer: CustomReducer;
|
|
35
|
+
effects?: ((payload?: unknown) => ScopedEffects<unknown>) | Effect<unknown, unknown>[];
|
|
36
|
+
};
|
|
33
37
|
}
|
|
34
38
|
export interface RxFormOptions<T extends CustomReducers> extends EffectsAndSources {
|
|
35
39
|
reducers?: T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -221,8 +221,8 @@ var getAsyncValidationActions = function (formControls) {
|
|
|
221
221
|
}, []);
|
|
222
222
|
};
|
|
223
223
|
|
|
224
|
-
var buildHub2Source = function (
|
|
225
|
-
var hub1StateMapped$ =
|
|
224
|
+
var buildHub2Source = function (hub1State$) {
|
|
225
|
+
var hub1StateMapped$ = hub1State$.pipe(operators.map(function (payload) { return ({ type: 'formChange', payload: payload }); }));
|
|
226
226
|
var sourceForHub2$ = hub1StateMapped$.pipe(operators.mergeMap(function (formChangeAction) {
|
|
227
227
|
var changedControls = formChangeAction.payload.changedControls;
|
|
228
228
|
var controlsToCheck = changedControls ? Object.values(changedControls) : [];
|
|
@@ -351,7 +351,7 @@ var updateDescendants = function (state, _a) {
|
|
|
351
351
|
};
|
|
352
352
|
};
|
|
353
353
|
// Will only update child controls that are present.
|
|
354
|
-
// Use
|
|
354
|
+
// Use AddControlPayload/RemoveControl action reducers to add/remove control
|
|
355
355
|
var updateValues = function (_a, action, mergeChanges) {
|
|
356
356
|
var _b, _c;
|
|
357
357
|
var form = _a.form, _d = _a.changedControls, changedControls = _d === void 0 ? {} : _d, _e = _a.removedControls, removedControls = _e === void 0 ? {} : _e;
|
|
@@ -359,20 +359,25 @@ var updateValues = function (_a, action, mergeChanges) {
|
|
|
359
359
|
var _f = action.payload, controlRef = _f.controlRef, value = _f.value;
|
|
360
360
|
// Update its own value
|
|
361
361
|
var ctrlKey = getFormKey(controlRef);
|
|
362
|
-
var
|
|
363
|
-
var
|
|
362
|
+
var newValue = value;
|
|
363
|
+
var config = form[ctrlKey].config;
|
|
364
|
+
if (config.normalizers) {
|
|
365
|
+
newValue = config.normalizers.reduce(function (acc, normalizer) { return normalizer(acc); }, value);
|
|
366
|
+
}
|
|
367
|
+
var validatorErrors = getErrors(form[ctrlKey], newValue);
|
|
368
|
+
var newControl = __assign(__assign({}, form[ctrlKey]), { validatorErrors: validatorErrors, dirty: !isEqual__default["default"](value, form[ctrlKey].pristineValue), value: newValue });
|
|
364
369
|
var result = {
|
|
365
370
|
form: __assign(__assign({}, form), (_b = {}, _b[ctrlKey] = newControl, _b)),
|
|
366
371
|
changedControls: (_c = {}, _c[newControl.key] = newControl, _c)
|
|
367
372
|
};
|
|
368
|
-
var configControls =
|
|
373
|
+
var configControls = config.controls;
|
|
369
374
|
// Update its children
|
|
370
375
|
if (configControls) {
|
|
371
376
|
result = updateDescendants(result, {
|
|
372
377
|
type: UPDATE_DESCENDANT_VALUES,
|
|
373
378
|
payload: {
|
|
374
379
|
controlRef: controlRef,
|
|
375
|
-
value:
|
|
380
|
+
value: newValue
|
|
376
381
|
}
|
|
377
382
|
});
|
|
378
383
|
}
|
|
@@ -380,7 +385,7 @@ var updateValues = function (_a, action, mergeChanges) {
|
|
|
380
385
|
if (controlRef.length) {
|
|
381
386
|
result = __assign(__assign({}, result), { form: updateAncestorValues(result.form, {
|
|
382
387
|
type: UPDATE_ANCESTOR_VALUES,
|
|
383
|
-
payload: { controlRef: controlRef, value:
|
|
388
|
+
payload: { controlRef: controlRef, value: newValue }
|
|
384
389
|
}) });
|
|
385
390
|
}
|
|
386
391
|
var changedAncestorControls = getAncestorControls(controlRef, result.form).reduce(function (acc, control) {
|
|
@@ -989,29 +994,29 @@ var control = function (config) {
|
|
|
989
994
|
var array = function (config) { return config; };
|
|
990
995
|
var group = function (config) { return config; };
|
|
991
996
|
var reducerTools = {
|
|
992
|
-
updateValues: function (state,
|
|
993
|
-
return updateValues(state,
|
|
997
|
+
updateValues: function (state, payload) {
|
|
998
|
+
return updateValues(state, { payload: payload }, true);
|
|
994
999
|
},
|
|
995
|
-
removeControl: function (state,
|
|
996
|
-
return removeControl(state,
|
|
1000
|
+
removeControl: function (state, payload) {
|
|
1001
|
+
return removeControl(state, { payload: payload }, true);
|
|
997
1002
|
},
|
|
998
|
-
pushControl: function (state,
|
|
999
|
-
return pushControl(state,
|
|
1003
|
+
pushControl: function (state, payload) {
|
|
1004
|
+
return pushControl(state, { payload: payload }, true);
|
|
1000
1005
|
},
|
|
1001
|
-
addControl: function (state,
|
|
1002
|
-
return addControl(state,
|
|
1006
|
+
addControl: function (state, payload) {
|
|
1007
|
+
return addControl(state, { payload: payload }, true);
|
|
1003
1008
|
},
|
|
1004
|
-
markControlAsPristine: function (state,
|
|
1005
|
-
return markControlAsPristine(state,
|
|
1009
|
+
markControlAsPristine: function (state, payload) {
|
|
1010
|
+
return markControlAsPristine(state, { payload: payload }, true);
|
|
1006
1011
|
},
|
|
1007
|
-
markControlAsTouched: function (state,
|
|
1008
|
-
return markControlAsTouched(state,
|
|
1012
|
+
markControlAsTouched: function (state, payload) {
|
|
1013
|
+
return markControlAsTouched(state, { payload: payload }, true);
|
|
1009
1014
|
},
|
|
1010
|
-
markControlAsUntouched: function (state,
|
|
1011
|
-
return markControlAsUntouched(state,
|
|
1015
|
+
markControlAsUntouched: function (state, payload) {
|
|
1016
|
+
return markControlAsUntouched(state, { payload: payload }, true);
|
|
1012
1017
|
},
|
|
1013
|
-
resetControl: function (state,
|
|
1014
|
-
return resetControl(state,
|
|
1018
|
+
resetControl: function (state, payload) {
|
|
1019
|
+
return resetControl(state, { payload: payload }, true);
|
|
1015
1020
|
}
|
|
1016
1021
|
};
|
|
1017
1022
|
var build = function (config, options) {
|
|
@@ -1020,15 +1025,20 @@ var build = function (config, options) {
|
|
|
1020
1025
|
var reducers = options.reducers, otherOptions = __rest(options, ["reducers"]);
|
|
1021
1026
|
var customReducers = Object.entries(reducers || {}).reduce(function (acc, _a) {
|
|
1022
1027
|
var _b;
|
|
1023
|
-
var key = _a[0],
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
+
var key = _a[0], _case = _a[1];
|
|
1029
|
+
var _reducer = typeof _case === 'function' ? _case : _case.reducer;
|
|
1030
|
+
var effects = typeof _case === 'function' ? [] : _case.effects;
|
|
1031
|
+
return __assign(__assign({}, acc), (_b = {}, _b[key] = {
|
|
1032
|
+
reducer: function (_a, action) {
|
|
1033
|
+
var form = _a.form;
|
|
1034
|
+
return _reducer(reducerTools, { form: form }, action);
|
|
1035
|
+
},
|
|
1036
|
+
effects: effects
|
|
1037
|
+
}, _b));
|
|
1028
1038
|
}, {});
|
|
1029
|
-
var
|
|
1030
|
-
var
|
|
1031
|
-
sources: [buildHub2Source(
|
|
1039
|
+
var _a = core.RxBuilder(__assign({ initialState: initialState, reducers: __assign({ updateValues: updateValues, removeControl: removeControl, addControl: addControl, pushControl: pushControl, markControlAsPristine: markControlAsPristine, markControlAsTouched: markControlAsTouched, markControlAsUntouched: markControlAsUntouched, resetControl: resetControl }, customReducers) }, otherOptions)), hub1State$ = _a[0], hub1Actions = _a[1];
|
|
1040
|
+
var state$ = core.RxBuilder({
|
|
1041
|
+
sources: [buildHub2Source(hub1State$)],
|
|
1032
1042
|
initialState: null,
|
|
1033
1043
|
reducers: {
|
|
1034
1044
|
formChange: formChange,
|
|
@@ -1041,11 +1051,11 @@ var build = function (config, options) {
|
|
|
1041
1051
|
},
|
|
1042
1052
|
asyncValidationResponseSuccess: asyncValidationResponseSuccess
|
|
1043
1053
|
}
|
|
1044
|
-
});
|
|
1045
|
-
return
|
|
1046
|
-
state
|
|
1047
|
-
|
|
1048
|
-
|
|
1054
|
+
})[0];
|
|
1055
|
+
return [
|
|
1056
|
+
state$.pipe(operators.filter(function (form) { return form !== null; })),
|
|
1057
|
+
hub1Actions,
|
|
1058
|
+
];
|
|
1049
1059
|
};
|
|
1050
1060
|
|
|
1051
1061
|
var getArrayItems = function (controlRef, form) {
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"author": "David Lai",
|
|
15
15
|
"license": "ISC",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@reactables/core": "^0.
|
|
17
|
+
"@reactables/core": "^0.7.0-alpha.0",
|
|
18
18
|
"lodash.isequal": "^4.5.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
@@ -23,5 +23,5 @@
|
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"lodash.clonedeep": "^4.5.0"
|
|
25
25
|
},
|
|
26
|
-
"version": "0.
|
|
26
|
+
"version": "0.7.0-alpha.0"
|
|
27
27
|
}
|
|
File without changes
|