@goodie-forms/core 1.0.0-alpha → 1.1.0-alpha
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.js +757 -646
- package/dist/index.js.map +1 -1
- package/dist/src/form/CustomValidation.d.ts +10 -0
- package/dist/src/form/CustomValidation.d.ts.map +1 -0
- package/dist/src/form/Field.d.ts +31 -0
- package/dist/src/form/Field.d.ts.map +1 -0
- package/dist/src/form/FormController.d.ts +68 -0
- package/dist/src/form/FormController.d.ts.map +1 -0
- package/dist/{form → src/form}/FormField.d.ts +6 -3
- package/dist/src/form/FormField.d.ts.map +1 -0
- package/dist/src/form/NonullFormField.d.ts +10 -0
- package/dist/src/form/NonullFormField.d.ts.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/types/DeepPartial.d.ts +6 -0
- package/dist/src/types/DeepPartial.d.ts.map +1 -0
- package/dist/src/types/Mixin.d.ts +2 -0
- package/dist/src/types/Mixin.d.ts.map +1 -0
- package/dist/src/utils/ensureImmerability.d.ts +2 -0
- package/dist/src/utils/ensureImmerability.d.ts.map +1 -0
- package/dist/src/utils/getId.d.ts.map +1 -0
- package/dist/src/utils/removeBy.d.ts.map +1 -0
- package/dist/test/test1.d.ts +2 -0
- package/dist/test/test1.d.ts.map +1 -0
- package/package.json +27 -27
- package/src/form/CustomValidation.ts +52 -0
- package/src/form/Field.ts +334 -194
- package/src/form/FormController.ts +310 -290
- package/src/form/FormField.ts +202 -199
- package/src/form/NonullFormField.ts +21 -0
- package/src/index.ts +5 -3
- package/src/types/DeepPartial.ts +7 -3
- package/src/types/Mixin.ts +2 -0
- package/src/utils/ensureImmerability.ts +30 -0
- package/src/utils/getId.ts +5 -5
- package/src/utils/removeBy.ts +11 -11
- package/test/test1.ts +52 -0
- package/tsconfig.json +7 -7
- package/vite.config.ts +18 -18
- package/dist/form/Field.d.ts +0 -17
- package/dist/form/Field.d.ts.map +0 -1
- package/dist/form/FormController.d.ts +0 -62
- package/dist/form/FormController.d.ts.map +0 -1
- package/dist/form/FormField.d.ts.map +0 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/types/DeepPartial.d.ts +0 -4
- package/dist/types/DeepPartial.d.ts.map +0 -1
- package/dist/utils/getId.d.ts.map +0 -1
- package/dist/utils/removeBy.d.ts.map +0 -1
- /package/dist/{utils → src/utils}/getId.d.ts +0 -0
- /package/dist/{utils → src/utils}/removeBy.d.ts +0 -0
package/src/form/FormField.ts
CHANGED
|
@@ -1,199 +1,202 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
protected
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
public readonly
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this._isDirty
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
1
|
+
import { produce } from "immer";
|
|
2
|
+
import { ensureImmerability } from "../utils/ensureImmerability";
|
|
3
|
+
import { getId } from "../utils/getId";
|
|
4
|
+
import { Field } from "./Field";
|
|
5
|
+
import { FormController } from "./FormController";
|
|
6
|
+
|
|
7
|
+
export class FormField<
|
|
8
|
+
TShape extends object,
|
|
9
|
+
TPath extends Field.Paths<TShape>
|
|
10
|
+
> {
|
|
11
|
+
public readonly id = getId();
|
|
12
|
+
|
|
13
|
+
protected target?: HTMLElement;
|
|
14
|
+
|
|
15
|
+
protected _isTouched = false;
|
|
16
|
+
protected _isDirty = false;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
public readonly controller: FormController<TShape>,
|
|
20
|
+
public readonly path: TPath,
|
|
21
|
+
initialState?: {
|
|
22
|
+
isTouched?: boolean;
|
|
23
|
+
isDirty?: boolean;
|
|
24
|
+
}
|
|
25
|
+
) {
|
|
26
|
+
if (initialState?.isTouched) this._setTouched(true);
|
|
27
|
+
if (initialState?.isDirty) this._setDirty(true);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get value(): Field.GetValue<TShape, TPath> | undefined {
|
|
31
|
+
return Field.getValue<TShape, TPath>(
|
|
32
|
+
this.controller._data as TShape,
|
|
33
|
+
this.path
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get initialValue(): Field.GetValue<TShape, TPath> | undefined {
|
|
38
|
+
return Field.getValue<TShape, TPath>(
|
|
39
|
+
this.controller._initialData as TShape,
|
|
40
|
+
this.path
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get boundElement() {
|
|
45
|
+
return this.target;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get issues() {
|
|
49
|
+
return this.controller._issues.filter(
|
|
50
|
+
(issue) => Field.parsePath(issue.path ?? []) === this.path
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get isTouched() {
|
|
55
|
+
return this._isTouched;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get isDirty() {
|
|
59
|
+
return this._isDirty;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get isValid() {
|
|
63
|
+
return this.issues.length === 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected _setTouched(isTouched: boolean) {
|
|
67
|
+
const changed = this._isTouched !== isTouched;
|
|
68
|
+
this._isTouched = isTouched;
|
|
69
|
+
|
|
70
|
+
if (changed) {
|
|
71
|
+
const ascendantFields = this.controller.getAscendantFields(this.path);
|
|
72
|
+
for (let i = ascendantFields.length - 1; i >= 0; i--) {
|
|
73
|
+
const field = ascendantFields[i];
|
|
74
|
+
if (field == null) continue;
|
|
75
|
+
this.controller.events.emit("fieldTouchUpdated", field.path);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected _setDirty(isDirty: boolean) {
|
|
81
|
+
const changed = this._isDirty !== isDirty;
|
|
82
|
+
this._isDirty = isDirty;
|
|
83
|
+
|
|
84
|
+
if (changed) {
|
|
85
|
+
const ascendantFields = this.controller.getAscendantFields(this.path);
|
|
86
|
+
for (let i = ascendantFields.length - 1; i >= 0; i--) {
|
|
87
|
+
const field = ascendantFields[i];
|
|
88
|
+
if (field == null) continue;
|
|
89
|
+
this.controller.events.emit("fieldDirtyUpdated", field.path);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
bindElement(el: HTMLElement | undefined) {
|
|
95
|
+
if (el != null) this.controller.events.emit("elementBound", this.path, el);
|
|
96
|
+
else this.controller.events.emit("elementUnbound", this.path);
|
|
97
|
+
this.target = el;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setValue(
|
|
101
|
+
value: Field.GetValue<TShape, TPath>,
|
|
102
|
+
opts?: Parameters<typeof this.modifyValue>[1]
|
|
103
|
+
) {
|
|
104
|
+
return this.modifyValue(() => value, opts);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
modifyValue(
|
|
108
|
+
modifier: (
|
|
109
|
+
currentValue: Field.GetValue<TShape, TPath> | undefined
|
|
110
|
+
) => Field.GetValue<TShape, TPath> | void,
|
|
111
|
+
opts?: {
|
|
112
|
+
shouldTouch?: boolean;
|
|
113
|
+
shouldMarkDirty?: boolean;
|
|
114
|
+
}
|
|
115
|
+
): void {
|
|
116
|
+
if (opts?.shouldTouch == null || opts?.shouldTouch) {
|
|
117
|
+
this.touch();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const ascendantFields = this.controller.getAscendantFields(this.path);
|
|
121
|
+
|
|
122
|
+
const initialValues = ascendantFields.map((field) => field?.initialValue);
|
|
123
|
+
initialValues.forEach((v) => ensureImmerability(v));
|
|
124
|
+
|
|
125
|
+
const oldValues = ascendantFields.map((field) => field?.value);
|
|
126
|
+
oldValues.forEach((v) => ensureImmerability(v));
|
|
127
|
+
|
|
128
|
+
this.controller._data = produce(this.controller._data, (draft) => {
|
|
129
|
+
Field.modifyValue(draft as TShape, this.path, (oldValue) => {
|
|
130
|
+
return modifier(oldValue);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const newValues = ascendantFields.map((field) => field?.value);
|
|
135
|
+
newValues.forEach((v) => ensureImmerability(v));
|
|
136
|
+
|
|
137
|
+
const compareCustom = (a: any, b: any) => {
|
|
138
|
+
if (typeof a !== "object") return;
|
|
139
|
+
if (typeof b !== "object") return;
|
|
140
|
+
const ctorA = a.constructor;
|
|
141
|
+
const ctorB = b.constructor;
|
|
142
|
+
if (ctorA !== ctorB) return;
|
|
143
|
+
return this.controller.equalityComparators?.[ctorA]?.(a, b);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const valueChanged = !Field.deepEqual(
|
|
147
|
+
oldValues[oldValues.length - 1],
|
|
148
|
+
newValues[newValues.length - 1],
|
|
149
|
+
compareCustom
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
if (valueChanged) {
|
|
153
|
+
for (let i = ascendantFields.length - 1; i >= 0; i--) {
|
|
154
|
+
const field = ascendantFields[i];
|
|
155
|
+
this.controller.events.emit(
|
|
156
|
+
"valueChanged",
|
|
157
|
+
field.path,
|
|
158
|
+
newValues[i],
|
|
159
|
+
oldValues[i]
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (opts?.shouldMarkDirty == null || opts?.shouldMarkDirty) {
|
|
165
|
+
const gotDirty = !Field.deepEqual(
|
|
166
|
+
initialValues[initialValues.length - 1],
|
|
167
|
+
newValues[newValues.length - 1],
|
|
168
|
+
compareCustom
|
|
169
|
+
);
|
|
170
|
+
this._setDirty(gotDirty);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
reset() {
|
|
175
|
+
this._setTouched(false);
|
|
176
|
+
this._setDirty(false);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
touch() {
|
|
180
|
+
this._setTouched(true);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
markDirty() {
|
|
184
|
+
this.touch();
|
|
185
|
+
this._setDirty(true);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
triggerValidation() {
|
|
189
|
+
this.controller.validateField(this.path);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
focus(opts?: { shouldTouch?: boolean }) {
|
|
193
|
+
if (opts?.shouldTouch == null || opts.shouldTouch) {
|
|
194
|
+
this.target?.addEventListener("focus", () => this.touch(), {
|
|
195
|
+
once: true,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
this.target?.scrollIntoView();
|
|
200
|
+
this.target?.focus();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Field } from "../form/Field";
|
|
2
|
+
import { FormField } from "../form/FormField";
|
|
3
|
+
import { Mixin } from "../types/Mixin";
|
|
4
|
+
|
|
5
|
+
export type NonnullFormField<
|
|
6
|
+
TShape extends object,
|
|
7
|
+
TPath extends Field.Paths<TShape>,
|
|
8
|
+
> = Mixin<
|
|
9
|
+
FormField<TShape, TPath>,
|
|
10
|
+
{
|
|
11
|
+
modifyValue: (
|
|
12
|
+
modifier: (
|
|
13
|
+
currentValue: Field.GetValue<TShape, TPath>,
|
|
14
|
+
) => Field.GetValue<TShape, TPath> | void,
|
|
15
|
+
opts?: {
|
|
16
|
+
shouldTouch?: boolean;
|
|
17
|
+
shouldMarkDirty?: boolean;
|
|
18
|
+
},
|
|
19
|
+
) => void;
|
|
20
|
+
}
|
|
21
|
+
>;
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export * from "./form/Field";
|
|
2
|
-
export * from "./form/FormField";
|
|
3
|
-
export * from "./form/
|
|
1
|
+
export * from "./form/Field";
|
|
2
|
+
export * from "./form/FormField";
|
|
3
|
+
export * from "./form/NonullFormField";
|
|
4
|
+
export * from "./form/FormController";
|
|
5
|
+
export * from "./form/CustomValidation";
|
package/src/types/DeepPartial.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
export type DeepPartial<T
|
|
2
|
-
[K in keyof T
|
|
3
|
-
}
|
|
1
|
+
export type DeepPartial<T> = {
|
|
2
|
+
[K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K];
|
|
3
|
+
} & {
|
|
4
|
+
[K in keyof T as T[K] extends (...args: any[]) => any
|
|
5
|
+
? never
|
|
6
|
+
: K]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
|
|
7
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { immerable } from "immer";
|
|
2
|
+
|
|
3
|
+
export function ensureImmerability(value: any) {
|
|
4
|
+
if (typeof value !== "object" || value === null) return;
|
|
5
|
+
|
|
6
|
+
// Skip plain objects
|
|
7
|
+
const proto = Object.getPrototypeOf(value);
|
|
8
|
+
if (proto === Object.prototype || proto === null) return;
|
|
9
|
+
|
|
10
|
+
const ctor = proto.constructor;
|
|
11
|
+
if (typeof ctor !== "function") return;
|
|
12
|
+
|
|
13
|
+
// Skip known built-ins
|
|
14
|
+
if (
|
|
15
|
+
value instanceof Date ||
|
|
16
|
+
value instanceof RegExp ||
|
|
17
|
+
value instanceof Map ||
|
|
18
|
+
value instanceof Set ||
|
|
19
|
+
value instanceof WeakMap ||
|
|
20
|
+
value instanceof WeakSet ||
|
|
21
|
+
ArrayBuffer.isView(value)
|
|
22
|
+
) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (ctor[immerable] === true) return;
|
|
27
|
+
|
|
28
|
+
// Define non-enumerable immerable flag
|
|
29
|
+
ctor[immerable] = true;
|
|
30
|
+
}
|
package/src/utils/getId.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
let id = 0;
|
|
2
|
-
|
|
3
|
-
export function getId() {
|
|
4
|
-
return id++;
|
|
5
|
-
}
|
|
1
|
+
let id = 0;
|
|
2
|
+
|
|
3
|
+
export function getId() {
|
|
4
|
+
return id++;
|
|
5
|
+
}
|
package/src/utils/removeBy.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export function removeBy<T>(arr: T[], predicate: (item: T) => boolean) {
|
|
2
|
-
let indices: number[] = [];
|
|
3
|
-
|
|
4
|
-
for (let i = arr.length - 1; i >= 0; i--) {
|
|
5
|
-
if (predicate(arr[i])) {
|
|
6
|
-
indices.push(i);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
indices.forEach((i) => arr.splice(i, 1));
|
|
11
|
-
}
|
|
1
|
+
export function removeBy<T>(arr: T[], predicate: (item: T) => boolean) {
|
|
2
|
+
let indices: number[] = [];
|
|
3
|
+
|
|
4
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
5
|
+
if (predicate(arr[i])) {
|
|
6
|
+
indices.push(i);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
indices.forEach((i) => arr.splice(i, 1));
|
|
11
|
+
}
|
package/test/test1.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Field, FormController } from "@goodie-forms/core";
|
|
2
|
+
|
|
3
|
+
class Inventory {
|
|
4
|
+
contents: string[] = [];
|
|
5
|
+
|
|
6
|
+
push(item: string) {
|
|
7
|
+
this.contents.push(item);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface UserForm {
|
|
12
|
+
name: string;
|
|
13
|
+
surname: string;
|
|
14
|
+
address: {
|
|
15
|
+
city: string;
|
|
16
|
+
street: string;
|
|
17
|
+
};
|
|
18
|
+
scores: string[];
|
|
19
|
+
friends: {
|
|
20
|
+
name: string;
|
|
21
|
+
friendshipPoints: number;
|
|
22
|
+
}[];
|
|
23
|
+
inventory?: Inventory;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const formController = new FormController<UserForm>({});
|
|
27
|
+
|
|
28
|
+
const nameField = formController.bindField("name", {
|
|
29
|
+
defaultValue: "Foo",
|
|
30
|
+
overrideInitialValue: true,
|
|
31
|
+
});
|
|
32
|
+
console.log(nameField.isTouched);
|
|
33
|
+
console.log(nameField.isDirty);
|
|
34
|
+
|
|
35
|
+
const addressField = formController.bindField("address", {
|
|
36
|
+
defaultValue: { city: "", street: "" },
|
|
37
|
+
overrideInitialValue: true,
|
|
38
|
+
});
|
|
39
|
+
addressField.modifyValue((address) => {
|
|
40
|
+
address!.city = "Foo City";
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(addressField.value);
|
|
44
|
+
|
|
45
|
+
const inventoryField = formController.bindField("inventory");
|
|
46
|
+
inventoryField.modifyValue((inventory) => {});
|
|
47
|
+
|
|
48
|
+
const inventory1Field = formController.bindField("inventory.contents[1]");
|
|
49
|
+
inventory1Field.setValue("Sword");
|
|
50
|
+
|
|
51
|
+
console.log("Data =", formController._data);
|
|
52
|
+
console.log("Initial Data =", formController._initialData);
|
package/tsconfig.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "dist"
|
|
5
|
-
},
|
|
6
|
-
"include": ["src"]
|
|
7
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist"
|
|
5
|
+
},
|
|
6
|
+
"include": ["src","test"]
|
|
7
|
+
}
|
package/vite.config.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
|
|
3
|
-
import dts from "vite-plugin-dts";
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
plugins: [dts()],
|
|
7
|
-
build: {
|
|
8
|
-
lib: {
|
|
9
|
-
entry: "src/index.ts",
|
|
10
|
-
formats: ["es"],
|
|
11
|
-
fileName: "index",
|
|
12
|
-
},
|
|
13
|
-
rollupOptions: {
|
|
14
|
-
external: [],
|
|
15
|
-
},
|
|
16
|
-
sourcemap: true,
|
|
17
|
-
},
|
|
18
|
-
});
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
|
|
3
|
+
import dts from "vite-plugin-dts";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [dts()],
|
|
7
|
+
build: {
|
|
8
|
+
lib: {
|
|
9
|
+
entry: "src/index.ts",
|
|
10
|
+
formats: ["es"],
|
|
11
|
+
fileName: "index",
|
|
12
|
+
},
|
|
13
|
+
rollupOptions: {
|
|
14
|
+
external: [],
|
|
15
|
+
},
|
|
16
|
+
sourcemap: true,
|
|
17
|
+
},
|
|
18
|
+
});
|
package/dist/form/Field.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare namespace Field {
|
|
2
|
-
type Paths<TShape extends object> = {
|
|
3
|
-
[K in keyof TShape & string]: NonNullable<TShape[K]> extends (...args: any[]) => any ? never : NonNullable<TShape[K]> extends object ? K | `${K}.${Paths<NonNullable<TShape[K]>>}` : K;
|
|
4
|
-
}[keyof TShape & string];
|
|
5
|
-
type GetValue<TShape extends object, TPath extends string> = TPath extends `${infer K}.${infer Rest}` ? K extends keyof TShape ? GetValue<NonNullable<TShape[K]>, Rest> : never : TPath extends keyof TShape ? TShape[TPath] : never;
|
|
6
|
-
function getValue<TShape extends object, TPath extends Field.Paths<TShape>>(data: TShape, path: TPath): Field.GetValue<TShape, TPath> | undefined;
|
|
7
|
-
function deepEqual(a: any, b: any, customComparator?: (a: any, b: any) => boolean | undefined): boolean;
|
|
8
|
-
function diff<T>(prev: readonly T[], next: readonly T[], equals: (a: T, b: T) => boolean, filter?: (a: T) => boolean): {
|
|
9
|
-
added: T[];
|
|
10
|
-
removed: T[];
|
|
11
|
-
unchanged: T[];
|
|
12
|
-
};
|
|
13
|
-
function setValue<TShape extends object, TPath extends Field.Paths<TShape>>(data: TShape, key: TPath, value: Field.GetValue<TShape, TPath>): void;
|
|
14
|
-
function modifyValue<TShape extends object, TPath extends Field.Paths<TShape>>(data: TShape, key: TPath, modifier: (currentValue: Field.GetValue<TShape, TPath>) => Field.GetValue<TShape, TPath> | void): void;
|
|
15
|
-
function deleteValue<TShape extends object, TPath extends Field.Paths<TShape>>(data: TShape, key: TPath): void;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=Field.d.ts.map
|
package/dist/form/Field.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/form/Field.ts"],"names":[],"mappings":"AAAA,yBAAiB,KAAK,CAAC;IACrB,KAAY,KAAK,CAAC,MAAM,SAAS,MAAM,IAAI;SACxC,CAAC,IAAI,MAAM,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAC3D,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,GAAG,GACJ,KAAK,GACL,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GACnC,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAC3C,CAAC;KACR,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC;IAEzB,KAAY,QAAQ,CAClB,MAAM,SAAS,MAAM,EACrB,KAAK,SAAS,MAAM,IAClB,KAAK,SAAS,GAAG,MAAM,CAAC,IAAI,MAAM,IAAI,EAAE,GACxC,CAAC,SAAS,MAAM,MAAM,GACpB,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GACtC,KAAK,GACP,KAAK,SAAS,MAAM,MAAM,GACxB,MAAM,CAAC,KAAK,CAAC,GACb,KAAK,CAAC;IAEZ,SAAgB,QAAQ,CACtB,MAAM,SAAS,MAAM,EACrB,KAAK,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EACjC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,SAAS,CAatE;IAED,SAAgB,SAAS,CACvB,CAAC,EAAE,GAAG,EACN,CAAC,EAAE,GAAG,EACN,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAAO,GAAG,SAAS,WAkE3D;IAED,SAAgB,IAAI,CAAC,CAAC,EACpB,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,EAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO;;;;MAqB3B;IAED,SAAgB,QAAQ,CACtB,MAAM,SAAS,MAAM,EACrB,KAAK,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EACjC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,QAE/D;IAED,SAAgB,WAAW,CACzB,MAAM,SAAS,MAAM,EACrB,KAAK,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAEjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,KAAK,EACV,QAAQ,EAAE,CACR,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KACxC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,QAoB1C;IAED,SAAgB,WAAW,CACzB,MAAM,SAAS,MAAM,EACrB,KAAK,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EACjC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,QAczB;CACF"}
|