@fairys/valtio-form-basic 0.0.13 → 1.0.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 +935 -2
- package/esm/common/instance/index.d.ts +25 -5
- package/esm/common/instance/index.js +33 -13
- package/esm/common/utils/index.d.ts +6 -0
- package/esm/common/utils/index.js +10 -1
- package/esm/form/form.d.ts +8 -2
- package/esm/form/form.item.d.ts +8 -4
- package/esm/form/form.item.js +8 -2
- package/esm/form/form.js +2 -1
- package/lib/common/instance/index.d.ts +25 -5
- package/lib/common/instance/index.js +42 -16
- package/lib/common/utils/index.d.ts +6 -0
- package/lib/common/utils/index.js +12 -0
- package/lib/form/form.d.ts +8 -2
- package/lib/form/form.item.d.ts +8 -4
- package/lib/form/form.item.js +8 -2
- package/lib/form/form.js +2 -1
- package/package.json +1 -1
- package/src/common/instance/index.ts +69 -18
- package/src/common/utils/index.ts +19 -0
- package/src/form/form.item.tsx +28 -4
- package/src/form/form.tsx +12 -3
package/lib/form/form.js
CHANGED
|
@@ -29,9 +29,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
const index_js_namespaceObject = require("../common/instance/index.js");
|
|
30
30
|
const external_react_namespaceObject = require("react");
|
|
31
31
|
function useFairysValtioForm(props, ref) {
|
|
32
|
-
const { form, rules, formData, hideState, initFormDataType = 'deepCopy', ...rest } = props;
|
|
32
|
+
const { form, rules, formData, hideState, initFormDataType = 'deepCopy', onValuesChange, ...rest } = props;
|
|
33
33
|
const formInstance = (0, index_js_namespaceObject.useFairysValtioFormInstance)(form);
|
|
34
34
|
formInstance.rules = rules;
|
|
35
|
+
formInstance.onValuesChange = onValuesChange;
|
|
35
36
|
(0, external_react_namespaceObject.useMemo)(()=>formInstance.ctor({
|
|
36
37
|
formData,
|
|
37
38
|
hideState,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"author": "SunLxy <1011771396@qq.com>",
|
|
4
4
|
"description": "使用 valtio 实现的表单基础库, 使其更加便捷,同时支持`PC`、`H5`、`Taro`,同时也更加灵活。",
|
|
5
5
|
"homepage": "https://github.com/autumn-fairy-tales/valtio-form-basic",
|
|
6
|
-
"version": "0.0
|
|
6
|
+
"version": "1.0.0",
|
|
7
7
|
"main": "lib/index.js",
|
|
8
8
|
"types": "esm/index.d.ts",
|
|
9
9
|
"module": "esm/index.js",
|
|
@@ -3,11 +3,17 @@ import { createContext, useContext, useRef } from 'react';
|
|
|
3
3
|
import { proxy, ref, snapshot, useSnapshot, unstable_getInternalStates } from 'valtio';
|
|
4
4
|
import AsyncValidator, { RuleItem, ValidateFieldsError, Values } from 'async-validator';
|
|
5
5
|
import { copy } from 'fast-copy';
|
|
6
|
-
import { formatePath, get, set, isObject } from 'common/utils';
|
|
6
|
+
import { formatePath, get, set, isObject, removeValueByPaths } from 'common/utils';
|
|
7
7
|
import { FairysValtioFormAttrsProps } from 'form/form';
|
|
8
8
|
|
|
9
9
|
/**表单实例*/
|
|
10
10
|
export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>> {
|
|
11
|
+
/**
|
|
12
|
+
* 表单值改变时回调
|
|
13
|
+
* @param path 表单项路径
|
|
14
|
+
* @param value 表单项值
|
|
15
|
+
*/
|
|
16
|
+
onValuesChange?: (path: PropertyKey, value: any) => void;
|
|
11
17
|
/***
|
|
12
18
|
* 判断值是否为代理对象
|
|
13
19
|
* @param value 值
|
|
@@ -46,25 +52,26 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
46
52
|
initFormDataType?: FairysValtioFormAttrsProps['initFormDataType'];
|
|
47
53
|
}) => {
|
|
48
54
|
const { formData, hideState, initFormDataType = 'deepCopy' } = options || {};
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
51
|
-
// 如果是 isProxy,则直接赋值
|
|
52
|
-
this.errorState = proxy<Record<PropertyKey, string[]>>({});
|
|
53
|
-
this.hideState = proxy<Record<PropertyKey, boolean>>(hideState ? copy(hideState) : {});
|
|
55
|
+
this.clear();
|
|
56
|
+
this.updatedHideInfo(hideState ? copy(hideState) : {});
|
|
54
57
|
// 判断是否是代理对象
|
|
55
58
|
const isValtioProxy = this.isValtioProxy(formData);
|
|
56
59
|
if (isValtioProxy) {
|
|
57
60
|
if (initFormDataType === 'deepCopy') {
|
|
58
|
-
this.state = proxy(copy(snapshot(formData)) as T);
|
|
61
|
+
// this.state = proxy(copy(snapshot(formData)) as T);
|
|
62
|
+
this.updated(copy(snapshot(formData)) as T, false);
|
|
59
63
|
} else {
|
|
60
|
-
this.state = formData as T;
|
|
64
|
+
// this.state = formData as T;
|
|
65
|
+
this.updated(formData as T, false);
|
|
61
66
|
}
|
|
62
67
|
} else {
|
|
63
68
|
if (initFormDataType === 'deepCopy') {
|
|
64
|
-
this.state = proxy(copy(formData || {}) as T);
|
|
69
|
+
// this.state = proxy(copy(formData || {}) as T);
|
|
70
|
+
this.updated(copy(formData || {}) as T, false);
|
|
65
71
|
}
|
|
66
72
|
{
|
|
67
|
-
this.state = proxy((formData || {}) as T);
|
|
73
|
+
// this.state = proxy((formData || {}) as T);
|
|
74
|
+
this.updated((formData || {}) as T, false);
|
|
68
75
|
}
|
|
69
76
|
}
|
|
70
77
|
};
|
|
@@ -91,7 +98,28 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
91
98
|
updatedValueByPaths = (path: PropertyKey, value: any) => {
|
|
92
99
|
set(this.state, formatePath(path), value);
|
|
93
100
|
this.validate([path], false);
|
|
101
|
+
this.onValuesChange?.(path, value);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**表单项卸载移除保存值*/
|
|
105
|
+
removeValueByPaths = (path: PropertyKey) => {
|
|
106
|
+
removeValueByPaths(this.state, formatePath(path));
|
|
94
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* 清理值
|
|
110
|
+
*/
|
|
111
|
+
clearValue = (fields?: PropertyKey[]) => {
|
|
112
|
+
let _fields = fields;
|
|
113
|
+
if (!Array.isArray(fields)) {
|
|
114
|
+
_fields = Object.keys(this.state) as PropertyKey[];
|
|
115
|
+
}
|
|
116
|
+
for (let index = 0; index < _fields.length; index++) {
|
|
117
|
+
const field = _fields[index];
|
|
118
|
+
delete this.state[field];
|
|
119
|
+
}
|
|
120
|
+
return this;
|
|
121
|
+
};
|
|
122
|
+
|
|
95
123
|
// ===================================================隐藏状态================================================================
|
|
96
124
|
/**
|
|
97
125
|
* 更新行数据的隐藏信息
|
|
@@ -154,9 +182,9 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
154
182
|
* 清理所有数据
|
|
155
183
|
*/
|
|
156
184
|
clear = () => {
|
|
157
|
-
this.
|
|
158
|
-
this.
|
|
159
|
-
this.
|
|
185
|
+
this.clearValue();
|
|
186
|
+
this.clearHideInfo();
|
|
187
|
+
this.clearErrorInfo();
|
|
160
188
|
this.mountRules = {}; //由表单项挂载规则,(根据表单项的字段存储路径对应校验规则)
|
|
161
189
|
this.rules = {}; //表单项规则
|
|
162
190
|
this.nameToPaths = {}; //表单项名称到路径映射
|
|
@@ -177,7 +205,10 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
177
205
|
* @param fields 要验证的字段(可选)
|
|
178
206
|
* @param isReturn 是否返回验证结果(可选)
|
|
179
207
|
*/
|
|
180
|
-
validate = async (
|
|
208
|
+
validate = async (
|
|
209
|
+
fields?: PropertyKey[],
|
|
210
|
+
isReturn: boolean = true,
|
|
211
|
+
): Promise<ValidateFieldsError | Values | Partial<T>> => {
|
|
181
212
|
const rules = {
|
|
182
213
|
...this.rules,
|
|
183
214
|
...this.mountRules,
|
|
@@ -251,7 +282,9 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
251
282
|
}
|
|
252
283
|
|
|
253
284
|
/**声明实例*/
|
|
254
|
-
export function useFairysValtioFormInstance<T extends MObject<T> =
|
|
285
|
+
export function useFairysValtioFormInstance<T extends MObject<T> = Record<string, any>>(
|
|
286
|
+
instance?: FairysValtioFormInstance<T>,
|
|
287
|
+
) {
|
|
255
288
|
const ref = useRef<FairysValtioFormInstance<T>>();
|
|
256
289
|
if (!ref.current) {
|
|
257
290
|
if (instance) {
|
|
@@ -269,12 +302,12 @@ export const FairysValtioFormInstanceContext = createContext<FairysValtioFormIns
|
|
|
269
302
|
);
|
|
270
303
|
|
|
271
304
|
/**表单实例上下文*/
|
|
272
|
-
export function useFairysValtioFormInstanceContext<T extends MObject<T> =
|
|
305
|
+
export function useFairysValtioFormInstanceContext<T extends MObject<T> = Record<string, any>>() {
|
|
273
306
|
return useContext(FairysValtioFormInstanceContext) as FairysValtioFormInstance<T>;
|
|
274
307
|
}
|
|
275
308
|
|
|
276
309
|
/**状态取值*/
|
|
277
|
-
export function useFairysValtioFormInstanceContextState<T extends MObject<T> =
|
|
310
|
+
export function useFairysValtioFormInstanceContextState<T extends MObject<T> = Record<string, any>>() {
|
|
278
311
|
const instance = useFairysValtioFormInstanceContext<T>();
|
|
279
312
|
const state = useSnapshot(instance.state) as T;
|
|
280
313
|
const errorState = useSnapshot(instance.errorState) as Record<PropertyKey, string[]>;
|
|
@@ -288,7 +321,7 @@ export function useFairysValtioFormInstanceContextState<T extends MObject<T> = o
|
|
|
288
321
|
}
|
|
289
322
|
|
|
290
323
|
/**隐藏组件状态取值*/
|
|
291
|
-
export function useFairysValtioFormInstanceContextHideState<T extends MObject<T> =
|
|
324
|
+
export function useFairysValtioFormInstanceContextHideState<T extends MObject<T> = Record<string, any>>() {
|
|
292
325
|
const instance = useFairysValtioFormInstanceContext<T>();
|
|
293
326
|
const hideState = useSnapshot(instance.hideState) as Record<PropertyKey, boolean>;
|
|
294
327
|
return [hideState, instance, (hideState as any).__defaultValue] as [
|
|
@@ -297,3 +330,21 @@ export function useFairysValtioFormInstanceContextHideState<T extends MObject<T>
|
|
|
297
330
|
any,
|
|
298
331
|
];
|
|
299
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* 传递表单实例获取状态
|
|
335
|
+
*/
|
|
336
|
+
export function useFairysValtioFormInstanceToState<T extends MObject<T> = Record<string, any>>(
|
|
337
|
+
formInstance: FairysValtioFormInstance<T>,
|
|
338
|
+
) {
|
|
339
|
+
const state = useSnapshot(formInstance.state) as T;
|
|
340
|
+
return state as T;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* 传递表单实例获取隐藏状态
|
|
344
|
+
*/
|
|
345
|
+
export function useFairysValtioFormInstanceToHideState<T extends MObject<T> = Record<string, any>>(
|
|
346
|
+
formInstance: FairysValtioFormInstance<T>,
|
|
347
|
+
) {
|
|
348
|
+
const hideState = useSnapshot(formInstance.hideState) as Record<PropertyKey, boolean>;
|
|
349
|
+
return hideState as Record<PropertyKey, boolean>;
|
|
350
|
+
}
|
|
@@ -50,6 +50,25 @@ export function get<TDefault = unknown>(value: any, segments: PropertyKey[]): TD
|
|
|
50
50
|
return current;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/***
|
|
54
|
+
* 移除值
|
|
55
|
+
* @param value 任意值
|
|
56
|
+
* @param segments 键路径
|
|
57
|
+
*/
|
|
58
|
+
export function removeValueByPaths(value: any, segments: PropertyKey[]) {
|
|
59
|
+
// 移除字段
|
|
60
|
+
let current: any = value;
|
|
61
|
+
const lg = segments.length;
|
|
62
|
+
for (let index = 0; index < lg; index++) {
|
|
63
|
+
const key = segments[index];
|
|
64
|
+
if (index === lg - 1) {
|
|
65
|
+
delete current[key];
|
|
66
|
+
} else {
|
|
67
|
+
current = current?.[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
53
72
|
/***
|
|
54
73
|
* 格式化路径,将路径中的数组索引转换为数字
|
|
55
74
|
* @param path 路径
|
package/src/form/form.item.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { FairysValtioFormParentAttrs, useFairysValtioFormAttrsName, useId } from
|
|
|
9
9
|
import { formatePath, get } from 'common/utils';
|
|
10
10
|
import { RuleItem } from 'async-validator';
|
|
11
11
|
|
|
12
|
-
export interface FairysValtioFormItemAttrsProps<T extends MObject<T> =
|
|
12
|
+
export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = Record<string, any>> {
|
|
13
13
|
/**平台*/
|
|
14
14
|
platform?: 'pc' | 'rn' | 'taro';
|
|
15
15
|
/**
|
|
@@ -81,6 +81,11 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
|
|
|
81
81
|
isJoinParentField?: boolean;
|
|
82
82
|
/**校验规则*/
|
|
83
83
|
rules?: RuleItem[];
|
|
84
|
+
|
|
85
|
+
/**卸载移除数据值
|
|
86
|
+
* @default true
|
|
87
|
+
*/
|
|
88
|
+
isRemoveValueOnUnmount?: boolean;
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
/**
|
|
@@ -126,7 +131,9 @@ export const FormItem = (props: FormItemProps) => {
|
|
|
126
131
|
* ```
|
|
127
132
|
*
|
|
128
133
|
*/
|
|
129
|
-
export function useFairysValtioFormItemAttrs<T extends MObject<T> =
|
|
134
|
+
export function useFairysValtioFormItemAttrs<T extends MObject<T> = Record<string, any>>(
|
|
135
|
+
props: FairysValtioFormItemAttrsProps<T>,
|
|
136
|
+
) {
|
|
130
137
|
const [layoutAttrs] = useFairysValtioFormLayoutContext();
|
|
131
138
|
const colCount = layoutAttrs.colCount || 1;
|
|
132
139
|
const parent_borderedType = layoutAttrs.itemBorderType || 'bottom';
|
|
@@ -173,6 +180,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
173
180
|
isJoinParentField = true,
|
|
174
181
|
rules,
|
|
175
182
|
platform = parent_platform,
|
|
183
|
+
isRemoveValueOnUnmount = true,
|
|
176
184
|
} = props;
|
|
177
185
|
|
|
178
186
|
const {
|
|
@@ -217,6 +225,14 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
217
225
|
}
|
|
218
226
|
};
|
|
219
227
|
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
return () => {
|
|
230
|
+
if (isRemoveValueOnUnmount) {
|
|
231
|
+
formInstance.removeValueByPaths(_name);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}, []);
|
|
235
|
+
|
|
220
236
|
/**基础组件参数*/
|
|
221
237
|
const baseControl = {
|
|
222
238
|
...attrs,
|
|
@@ -420,7 +436,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
420
436
|
} as FairysValtioFormItemAttrsReturn<T>;
|
|
421
437
|
}
|
|
422
438
|
|
|
423
|
-
export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> =
|
|
439
|
+
export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> = Record<string, any>> {
|
|
424
440
|
/**表单项值*/
|
|
425
441
|
value?: any;
|
|
426
442
|
/**是否校验错误*/
|
|
@@ -507,7 +523,7 @@ export const FormItem = (props: FormItemProps) => {
|
|
|
507
523
|
}
|
|
508
524
|
* ```
|
|
509
525
|
*/
|
|
510
|
-
export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> =
|
|
526
|
+
export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = Record<string, any>>(
|
|
511
527
|
props: FairysValtioFormItemAttrsProps<T>,
|
|
512
528
|
) {
|
|
513
529
|
const {
|
|
@@ -522,6 +538,7 @@ export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = objec
|
|
|
522
538
|
attrs = {},
|
|
523
539
|
isJoinParentField = true,
|
|
524
540
|
rules,
|
|
541
|
+
isRemoveValueOnUnmount = true,
|
|
525
542
|
} = props;
|
|
526
543
|
const [state, errorState, formInstance] = useFairysValtioFormInstanceContextState<T>();
|
|
527
544
|
const {
|
|
@@ -563,6 +580,13 @@ export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = objec
|
|
|
563
580
|
onAfterUpdate(_value, formInstance, event);
|
|
564
581
|
}
|
|
565
582
|
};
|
|
583
|
+
useEffect(() => {
|
|
584
|
+
return () => {
|
|
585
|
+
if (isRemoveValueOnUnmount) {
|
|
586
|
+
formInstance.removeValueByPaths(_name);
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
}, []);
|
|
566
590
|
/**基础组件参数*/
|
|
567
591
|
const baseControl = {
|
|
568
592
|
...attrs,
|
package/src/form/form.tsx
CHANGED
|
@@ -4,7 +4,8 @@ import { useImperativeHandle, useMemo, type ReactNode, useEffect } from 'react';
|
|
|
4
4
|
import { FairysValtioFormLayoutAttrsProps } from './layout';
|
|
5
5
|
import { RuleItem } from 'async-validator';
|
|
6
6
|
|
|
7
|
-
export interface FairysValtioFormAttrsProps<T extends MObject<T> =
|
|
7
|
+
export interface FairysValtioFormAttrsProps<T extends MObject<T> = Record<string, any>>
|
|
8
|
+
extends FairysValtioFormLayoutAttrsProps {
|
|
8
9
|
/**表单实例*/
|
|
9
10
|
form?: FairysValtioFormInstance<T>;
|
|
10
11
|
/**子元素*/
|
|
@@ -21,6 +22,12 @@ export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> exten
|
|
|
21
22
|
* - immutable:直接使用对象(注意:当传递的不是`valtio`的`proxy`对象时,会使用`valtio`中的`proxy`声明)
|
|
22
23
|
*/
|
|
23
24
|
initFormDataType?: 'deepCopy' | 'immutable';
|
|
25
|
+
/**
|
|
26
|
+
* 表单值改变时回调
|
|
27
|
+
* @param path 表单项路径
|
|
28
|
+
* @param value 表单项值
|
|
29
|
+
*/
|
|
30
|
+
onValuesChange?: (path: PropertyKey, value: any) => void;
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
/**
|
|
@@ -43,14 +50,16 @@ export const Form = (props: FormProps) => {
|
|
|
43
50
|
}
|
|
44
51
|
* ```
|
|
45
52
|
*/
|
|
46
|
-
export function useFairysValtioForm<T extends MObject<T> =
|
|
53
|
+
export function useFairysValtioForm<T extends MObject<T> = Record<string, any>>(
|
|
47
54
|
props: FairysValtioFormAttrsProps<T>,
|
|
48
55
|
ref: React.Ref<FairysValtioFormInstance<T>>,
|
|
49
56
|
) {
|
|
50
|
-
const { form, rules, formData, hideState, initFormDataType = 'deepCopy', ...rest } = props;
|
|
57
|
+
const { form, rules, formData, hideState, initFormDataType = 'deepCopy', onValuesChange, ...rest } = props;
|
|
51
58
|
const formInstance = useFairysValtioFormInstance(form);
|
|
52
59
|
/**表单规则*/
|
|
53
60
|
formInstance.rules = rules;
|
|
61
|
+
/**表单值改变时回调*/
|
|
62
|
+
formInstance.onValuesChange = onValuesChange;
|
|
54
63
|
/**初始化表单值*/
|
|
55
64
|
useMemo(() => formInstance.ctor({ formData, hideState, initFormDataType }), []);
|
|
56
65
|
useImperativeHandle(ref, () => formInstance);
|