@carefrees/form-utils-react-taro 0.0.4
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 +9 -0
- package/esm/formItem/index.d.ts +11 -0
- package/esm/formItem/index.js +70 -0
- package/esm/formList/index.d.ts +27 -0
- package/esm/formList/index.js +40 -0
- package/esm/hooks/attr/attr.FormItem.d.ts +48 -0
- package/esm/hooks/attr/attr.FormItem.js +61 -0
- package/esm/hooks/register/register.FormHideItem.d.ts +9 -0
- package/esm/hooks/register/register.FormHideItem.js +31 -0
- package/esm/hooks/register/register.FormItem.d.ts +23 -0
- package/esm/hooks/register/register.FormItem.js +42 -0
- package/esm/hooks/register/register.FormList.d.ts +9 -0
- package/esm/hooks/register/register.FormList.js +31 -0
- package/esm/hooks/register/register.form.d.ts +3 -0
- package/esm/hooks/register/register.form.js +17 -0
- package/esm/hooks/useAttrs.d.ts +25 -0
- package/esm/hooks/useAttrs.js +10 -0
- package/esm/hooks/useForm.d.ts +7 -0
- package/esm/hooks/useForm.js +13 -0
- package/esm/hooks/useFormItem.d.ts +7 -0
- package/esm/hooks/useFormItem.js +11 -0
- package/esm/hooks/useFormItemParentName.d.ts +30 -0
- package/esm/hooks/useFormItemParentName.js +61 -0
- package/esm/hooks/useFormList.d.ts +7 -0
- package/esm/hooks/useFormList.js +11 -0
- package/esm/hooks/useHtmlFor.d.ts +1 -0
- package/esm/hooks/useHtmlFor.js +10 -0
- package/esm/hooks/useMultipleForm.d.ts +13 -0
- package/esm/hooks/useMultipleForm.js +19 -0
- package/esm/hooks/useUpdate.d.ts +2 -0
- package/esm/hooks/useUpdate.js +10 -0
- package/esm/hooks/useWatch.d.ts +19 -0
- package/esm/hooks/useWatch.js +41 -0
- package/esm/index.d.ts +46 -0
- package/esm/index.js +61 -0
- package/esm/layout/index.d.ts +35 -0
- package/esm/layout/index.js +99 -0
- package/esm/layout/layout.formItem.d.ts +44 -0
- package/esm/layout/layout.formItem.js +113 -0
- package/esm/styles/index.css +200 -0
- package/lib/formItem/index.d.ts +11 -0
- package/lib/formItem/index.js +107 -0
- package/lib/formList/index.d.ts +27 -0
- package/lib/formList/index.js +77 -0
- package/lib/hooks/attr/attr.FormItem.d.ts +48 -0
- package/lib/hooks/attr/attr.FormItem.js +95 -0
- package/lib/hooks/register/register.FormHideItem.d.ts +9 -0
- package/lib/hooks/register/register.FormHideItem.js +65 -0
- package/lib/hooks/register/register.FormItem.d.ts +23 -0
- package/lib/hooks/register/register.FormItem.js +76 -0
- package/lib/hooks/register/register.FormList.d.ts +9 -0
- package/lib/hooks/register/register.FormList.js +65 -0
- package/lib/hooks/register/register.form.d.ts +3 -0
- package/lib/hooks/register/register.form.js +51 -0
- package/lib/hooks/useAttrs.d.ts +25 -0
- package/lib/hooks/useAttrs.js +47 -0
- package/lib/hooks/useForm.d.ts +7 -0
- package/lib/hooks/useForm.js +53 -0
- package/lib/hooks/useFormItem.d.ts +7 -0
- package/lib/hooks/useFormItem.js +51 -0
- package/lib/hooks/useFormItemParentName.d.ts +30 -0
- package/lib/hooks/useFormItemParentName.js +101 -0
- package/lib/hooks/useFormList.d.ts +7 -0
- package/lib/hooks/useFormList.js +51 -0
- package/lib/hooks/useHtmlFor.d.ts +1 -0
- package/lib/hooks/useHtmlFor.js +44 -0
- package/lib/hooks/useMultipleForm.d.ts +13 -0
- package/lib/hooks/useMultipleForm.js +62 -0
- package/lib/hooks/useUpdate.d.ts +2 -0
- package/lib/hooks/useUpdate.js +44 -0
- package/lib/hooks/useWatch.d.ts +19 -0
- package/lib/hooks/useWatch.js +78 -0
- package/lib/index.d.ts +46 -0
- package/lib/index.js +317 -0
- package/lib/layout/index.d.ts +35 -0
- package/lib/layout/index.js +146 -0
- package/lib/layout/layout.formItem.d.ts +44 -0
- package/lib/layout/layout.formItem.js +157 -0
- package/lib/styles/index.css +200 -0
- package/package.json +32 -0
- package/src/formItem/index.tsx +103 -0
- package/src/formList/index.tsx +59 -0
- package/src/hooks/attr/attr.FormItem.tsx +131 -0
- package/src/hooks/register/register.FormHideItem.ts +29 -0
- package/src/hooks/register/register.FormItem.ts +52 -0
- package/src/hooks/register/register.FormList.ts +31 -0
- package/src/hooks/register/register.form.ts +18 -0
- package/src/hooks/useAttrs.ts +35 -0
- package/src/hooks/useForm.ts +23 -0
- package/src/hooks/useFormItem.ts +21 -0
- package/src/hooks/useFormItemParentName.ts +49 -0
- package/src/hooks/useFormList.ts +21 -0
- package/src/hooks/useHtmlFor.ts +9 -0
- package/src/hooks/useMultipleForm.ts +36 -0
- package/src/hooks/useUpdate.ts +12 -0
- package/src/hooks/useWatch.ts +61 -0
- package/src/index.tsx +102 -0
- package/src/layout/index.tsx +152 -0
- package/src/layout/layout.formItem.tsx +152 -0
- package/src/styles/index.css +208 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useRegisterFormList, RegisterFormListOptions } from './../hooks/register/register.FormList';
|
|
2
|
+
import { FormListInstanceContext } from '../hooks/useFormList';
|
|
3
|
+
import { FormItemParentNameProvider } from './../hooks/useFormItemParentName';
|
|
4
|
+
import { RuleInstanceBase, FormItemInstanceBase, FormListInstanceBase } from '@carefrees/form-utils';
|
|
5
|
+
import { useRegisterFormHideItem } from './../hooks/register/register.FormHideItem';
|
|
6
|
+
import React, { Fragment, memo } from 'react';
|
|
7
|
+
|
|
8
|
+
export interface FormListChildrenProps {
|
|
9
|
+
/**数据集合*/
|
|
10
|
+
fields: { name: number; key: number }[];
|
|
11
|
+
/**添加*/
|
|
12
|
+
onAdd: (initialValue?: Object) => void;
|
|
13
|
+
/**删除*/
|
|
14
|
+
onDelete: (index: number | number[]) => void;
|
|
15
|
+
/**移动*/
|
|
16
|
+
onMove: (from: number, to: number) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface FormListProps extends RegisterFormListOptions {
|
|
20
|
+
children: (
|
|
21
|
+
options: FormListChildrenProps,
|
|
22
|
+
instances: {
|
|
23
|
+
ruleInstance: RuleInstanceBase;
|
|
24
|
+
formItemInstance: FormItemInstanceBase;
|
|
25
|
+
formListInstance: FormListInstanceBase;
|
|
26
|
+
},
|
|
27
|
+
) => React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**form list 组件*/
|
|
31
|
+
export const FormList = memo((props: FormListProps) => {
|
|
32
|
+
const { children, ...rest } = props;
|
|
33
|
+
const { formListInstance, ruleInstance, formItemInstance } = useRegisterFormList(rest);
|
|
34
|
+
return (
|
|
35
|
+
<FormListInstanceContext.Provider value={formListInstance}>
|
|
36
|
+
<FormItemParentNameProvider name={formListInstance.name} sort={formListInstance.sort}>
|
|
37
|
+
{children(
|
|
38
|
+
{
|
|
39
|
+
fields: formListInstance.getFields(),
|
|
40
|
+
onAdd: formListInstance.onAdd,
|
|
41
|
+
onDelete: formListInstance.onDelete,
|
|
42
|
+
onMove: formListInstance.onMove,
|
|
43
|
+
},
|
|
44
|
+
{ ruleInstance, formItemInstance, formListInstance },
|
|
45
|
+
)}
|
|
46
|
+
</FormItemParentNameProvider>
|
|
47
|
+
</FormListInstanceContext.Provider>
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/**隐藏 form list item 组件*/
|
|
52
|
+
export const FormHideList = memo((props: FormListProps) => {
|
|
53
|
+
const { name, sort, isJoinParentField } = props;
|
|
54
|
+
const { isHide } = useRegisterFormHideItem({ name, sort: sort, isJoinParentField });
|
|
55
|
+
if (isHide) {
|
|
56
|
+
return <Fragment />;
|
|
57
|
+
}
|
|
58
|
+
return <FormList {...props} />;
|
|
59
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { RuleInstanceBase, FormInstanceBase, FormItemInstanceBase, get } from '@carefrees/form-utils';
|
|
2
|
+
import { useRegisterFormItem, RegisterFormItemOptions } from '../register/register.FormItem';
|
|
3
|
+
import { useHtmlFor } from '../useHtmlFor';
|
|
4
|
+
import React, { cloneElement, isValidElement, useMemo } from 'react';
|
|
5
|
+
|
|
6
|
+
export interface FormItemAttrOptions extends RegisterFormItemOptions {
|
|
7
|
+
/**依赖更新项*/
|
|
8
|
+
dependencies?: string[];
|
|
9
|
+
/**通知 只用于校验规则提示 字段 */
|
|
10
|
+
noticeOnlyRuleDataField?: string[];
|
|
11
|
+
/**通知父级字段监听方法更新*/
|
|
12
|
+
isNoticeParentField?: boolean;
|
|
13
|
+
/**通知watch监听方法更新*/
|
|
14
|
+
noticeWatchField?: string[];
|
|
15
|
+
/**是否保护值(不进行表单项组件卸载重置初始值)*/
|
|
16
|
+
preserve?: boolean;
|
|
17
|
+
/**重写规则*/
|
|
18
|
+
useRules?: (ruleInstance: RuleInstanceBase, form: FormInstanceBase, formItemInstance: FormItemInstanceBase) => void;
|
|
19
|
+
/**输入框属性重写*/
|
|
20
|
+
useAttrs?: (attrs: any, form: FormInstanceBase, formItemInstance: FormItemInstanceBase) => any;
|
|
21
|
+
/**输入框属性*/
|
|
22
|
+
attrs?: any;
|
|
23
|
+
/**传递组件字段*/
|
|
24
|
+
valuePropName?: string;
|
|
25
|
+
/**取值字段(默认和valuePropName值相同)*/
|
|
26
|
+
getValuePath?: string;
|
|
27
|
+
/**自定义获取值*/
|
|
28
|
+
getValueFromEvent?: (event: any, form: FormInstanceBase, formItemInstance: FormItemInstanceBase) => any;
|
|
29
|
+
/**值格式化*/
|
|
30
|
+
formatValue?: (value: any, form: FormInstanceBase, formItemInstance: FormItemInstanceBase, event: any) => any;
|
|
31
|
+
/**触发数据更新之后触发(用于数据联动之类的)*/
|
|
32
|
+
onAfterUpdate?: (value: any, form: FormInstanceBase, formItemInstance: FormItemInstanceBase, event: any) => void;
|
|
33
|
+
/**事件名称*/
|
|
34
|
+
trigger?: string;
|
|
35
|
+
/**子元素*/
|
|
36
|
+
children?: React.ReactNode;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**表单项参数*/
|
|
40
|
+
export const useFormItemAttr = (options: FormItemAttrOptions) => {
|
|
41
|
+
const {
|
|
42
|
+
trigger = 'onChange',
|
|
43
|
+
dependencies,
|
|
44
|
+
noticeOnlyRuleDataField,
|
|
45
|
+
isNoticeParentField,
|
|
46
|
+
noticeWatchField,
|
|
47
|
+
preserve,
|
|
48
|
+
valuePropName = 'value',
|
|
49
|
+
getValuePath = valuePropName,
|
|
50
|
+
getValueFromEvent,
|
|
51
|
+
formatValue,
|
|
52
|
+
onAfterUpdate,
|
|
53
|
+
useAttrs,
|
|
54
|
+
useRules,
|
|
55
|
+
attrs,
|
|
56
|
+
children,
|
|
57
|
+
...rest
|
|
58
|
+
} = options;
|
|
59
|
+
const { formItemInstance, form, ruleInstance, newName } = useRegisterFormItem({ ...rest });
|
|
60
|
+
formItemInstance.dependencies = dependencies;
|
|
61
|
+
formItemInstance.noticeOnlyRuleDataField = noticeOnlyRuleDataField;
|
|
62
|
+
formItemInstance.isNoticeParentField = isNoticeParentField;
|
|
63
|
+
formItemInstance.onAfterUpdate = onAfterUpdate;
|
|
64
|
+
formItemInstance.noticeWatchField = noticeWatchField;
|
|
65
|
+
formItemInstance.preserve = preserve;
|
|
66
|
+
|
|
67
|
+
/**获取值*/
|
|
68
|
+
const oldValue = form.getFieldValue(newName);
|
|
69
|
+
|
|
70
|
+
const onValueChange = (event: any) => {
|
|
71
|
+
try {
|
|
72
|
+
let value = event;
|
|
73
|
+
const target = event?.detail || event?.target;
|
|
74
|
+
if (typeof getValueFromEvent === 'function') {
|
|
75
|
+
value = getValueFromEvent(event, form, formItemInstance);
|
|
76
|
+
} else if (event && target && typeof target === 'object' && getValuePath in target) {
|
|
77
|
+
value = get(target, getValuePath);
|
|
78
|
+
}
|
|
79
|
+
if (typeof formatValue === 'function') {
|
|
80
|
+
value = formatValue(value, form, formItemInstance, event);
|
|
81
|
+
}
|
|
82
|
+
if (oldValue !== value) {
|
|
83
|
+
form.updatedFieldValue(newName, value, 'validate');
|
|
84
|
+
formItemInstance.onAfterUpdate?.(value, form, formItemInstance, event);
|
|
85
|
+
if (Array.isArray(formItemInstance.noticeWatchField) && formItemInstance.noticeWatchField.length) {
|
|
86
|
+
form.noticeWatch(formItemInstance.noticeWatchField);
|
|
87
|
+
}
|
|
88
|
+
if (
|
|
89
|
+
Array.isArray(formItemInstance.noticeOnlyRuleDataField) &&
|
|
90
|
+
formItemInstance.noticeOnlyRuleDataField.length
|
|
91
|
+
) {
|
|
92
|
+
form.onlyValidate(formItemInstance.noticeOnlyRuleDataField);
|
|
93
|
+
}
|
|
94
|
+
if (formItemInstance.isNoticeParentField && formItemInstance.parentDataField) {
|
|
95
|
+
form.notice(formItemInstance.parentDataField);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.log(error);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
formItemInstance.onChange = onValueChange;
|
|
103
|
+
|
|
104
|
+
// useHtmlFor
|
|
105
|
+
const htmlFor = useHtmlFor(newName);
|
|
106
|
+
formItemInstance.htmlFor = htmlFor;
|
|
107
|
+
|
|
108
|
+
const control: any = {
|
|
109
|
+
[trigger]: onValueChange,
|
|
110
|
+
...attrs,
|
|
111
|
+
name: newName,
|
|
112
|
+
id: htmlFor,
|
|
113
|
+
[valuePropName]: oldValue,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**触发数据调整*/
|
|
117
|
+
const newControl = useAttrs?.(control, form, formItemInstance) || control;
|
|
118
|
+
formItemInstance.control = newControl;
|
|
119
|
+
useRules?.(ruleInstance, form, formItemInstance);
|
|
120
|
+
const validateResult = useMemo(() => ruleInstance.getValidateResult(), [ruleInstance.messages]);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
children: isValidElement(children) ? cloneElement(children, newControl) : children,
|
|
124
|
+
form,
|
|
125
|
+
formItemInstance,
|
|
126
|
+
ruleInstance,
|
|
127
|
+
onChange: onValueChange,
|
|
128
|
+
htmlFor,
|
|
129
|
+
validateResult,
|
|
130
|
+
};
|
|
131
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { RegisterFormItemOptions } from './register.FormItem';
|
|
3
|
+
import { FormHideItemInstanceBase } from '@carefrees/form-utils';
|
|
4
|
+
import { useFormItemParentName } from '../useFormItemParentName';
|
|
5
|
+
import { useFormInstance } from '../useForm';
|
|
6
|
+
import { useUpdate } from '../useUpdate';
|
|
7
|
+
|
|
8
|
+
interface RegisterFormHideItemOptions extends Omit<RegisterFormItemOptions, 'rules'> {}
|
|
9
|
+
|
|
10
|
+
/**注册表单隐藏表单项到表单实例中*/
|
|
11
|
+
export const useRegisterFormHideItem = (options: RegisterFormHideItemOptions) => {
|
|
12
|
+
const { name, sort, isJoinParentField = true } = options;
|
|
13
|
+
const form = useFormInstance();
|
|
14
|
+
const _update = useUpdate();
|
|
15
|
+
const { newName, newSort } = useFormItemParentName({ name, sort, isJoinParentField });
|
|
16
|
+
const hideItemInstance = useRef(new FormHideItemInstanceBase().ctor(newName)).current;
|
|
17
|
+
const isHide = form.getFieldHideValue(newName);
|
|
18
|
+
|
|
19
|
+
hideItemInstance.instance = form;
|
|
20
|
+
hideItemInstance.updated = _update.current;
|
|
21
|
+
hideItemInstance.sort = newSort;
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const unMount = form.registerFormHideItem(hideItemInstance);
|
|
25
|
+
return () => unMount();
|
|
26
|
+
}, [newName]);
|
|
27
|
+
|
|
28
|
+
return { form, isHide };
|
|
29
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description 注册组件
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
6
|
+
import { RuleInstanceBase } from '@carefrees/form-utils';
|
|
7
|
+
import type { RuleItem } from 'async-validator';
|
|
8
|
+
import { useUpdate } from '../useUpdate';
|
|
9
|
+
import { useFormInstance } from '../useForm';
|
|
10
|
+
import { useFormItem } from '../useFormItem';
|
|
11
|
+
import { useFormItemParentName } from '../useFormItemParentName';
|
|
12
|
+
|
|
13
|
+
export interface RegisterFormItemOptions {
|
|
14
|
+
/**字段*/
|
|
15
|
+
name: string;
|
|
16
|
+
/**规则*/
|
|
17
|
+
rules?: RuleItem[];
|
|
18
|
+
/**排序值*/
|
|
19
|
+
sort?: string;
|
|
20
|
+
/**是否拼接父级字段*/
|
|
21
|
+
isJoinParentField?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**注册表单项到表单实例中*/
|
|
25
|
+
export const useRegisterFormItem = (options: RegisterFormItemOptions) => {
|
|
26
|
+
const { name, rules, sort, isJoinParentField = true } = options;
|
|
27
|
+
const form = useFormInstance();
|
|
28
|
+
const { newName, newSort, parentName } = useFormItemParentName({ name, sort, isJoinParentField });
|
|
29
|
+
// 注册规则
|
|
30
|
+
// 注册单个实例
|
|
31
|
+
const ruleInstance = useRef(new RuleInstanceBase()).current;
|
|
32
|
+
useMemo(() => ruleInstance.ctor(newName, rules), [rules, newName]);
|
|
33
|
+
ruleInstance.instance = form;
|
|
34
|
+
ruleInstance.sort = newSort;
|
|
35
|
+
|
|
36
|
+
const formItemInstance = useFormItem();
|
|
37
|
+
useMemo(() => formItemInstance.ctor(newName, ruleInstance), []);
|
|
38
|
+
formItemInstance.instance = form;
|
|
39
|
+
formItemInstance.sort = newSort;
|
|
40
|
+
formItemInstance.parentDataField = parentName;
|
|
41
|
+
|
|
42
|
+
const _updated = useUpdate();
|
|
43
|
+
formItemInstance.updated = _updated.current;
|
|
44
|
+
ruleInstance.updated = _updated.current;
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const unMount = form.registerFormItem(formItemInstance);
|
|
48
|
+
return () => unMount();
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
return { ruleInstance, formItemInstance, form, parentName, newName };
|
|
52
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'react';
|
|
2
|
+
import { RegisterFormItemOptions, useRegisterFormItem } from './register.FormItem';
|
|
3
|
+
import { useFormList } from '../useFormList';
|
|
4
|
+
|
|
5
|
+
export interface RegisterFormListOptions extends RegisterFormItemOptions {}
|
|
6
|
+
|
|
7
|
+
/**注册表单List到表单实例中*/
|
|
8
|
+
export const useRegisterFormList = (options: RegisterFormListOptions) => {
|
|
9
|
+
const { ...rest } = options;
|
|
10
|
+
const { ruleInstance, formItemInstance, form, newName, parentName } = useRegisterFormItem({ ...rest });
|
|
11
|
+
const formListInstance = useFormList();
|
|
12
|
+
|
|
13
|
+
useMemo(() => formListInstance.ctor(newName), [newName]);
|
|
14
|
+
|
|
15
|
+
formListInstance.instance = form;
|
|
16
|
+
formListInstance.rule = ruleInstance;
|
|
17
|
+
formListInstance.sort = options.sort;
|
|
18
|
+
formListInstance.formItemInstance = formItemInstance;
|
|
19
|
+
formListInstance.parentDataField = parentName;
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const unMount = form.registerFormList(options.name, formListInstance);
|
|
23
|
+
return () => unMount();
|
|
24
|
+
}, [options.name, formListInstance]);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
ruleInstance,
|
|
28
|
+
formItemInstance,
|
|
29
|
+
formListInstance,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useMultipleFormInstance } from '../useMultipleForm';
|
|
3
|
+
import { FormInstanceBase } from '@carefrees/form-utils';
|
|
4
|
+
|
|
5
|
+
/**注册表单实例到多表单收集实例中*/
|
|
6
|
+
export const useRegisterForm = (form: FormInstanceBase, name?: string) => {
|
|
7
|
+
const multipleForm = useMultipleFormInstance();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
let onMounted;
|
|
10
|
+
if (name) {
|
|
11
|
+
onMounted = multipleForm.ctor(name, form);
|
|
12
|
+
}
|
|
13
|
+
return () => {
|
|
14
|
+
onMounted?.();
|
|
15
|
+
};
|
|
16
|
+
}, [name, form]);
|
|
17
|
+
return multipleForm;
|
|
18
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**公共属性*/
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
import type { LayoutFormItemProps } from '../layout/layout.formItem';
|
|
4
|
+
export interface AttrsOptions {
|
|
5
|
+
/**列数据*/
|
|
6
|
+
colCount?: number;
|
|
7
|
+
/**规则校验失败错误提示位置*/
|
|
8
|
+
errorLayout?: LayoutFormItemProps['errorLayout'];
|
|
9
|
+
/**label显示模式*/
|
|
10
|
+
labelMode?: LayoutFormItemProps['labelMode'];
|
|
11
|
+
/**是否显示label后的冒号*/
|
|
12
|
+
showColon?: boolean;
|
|
13
|
+
/**表单项 className*/
|
|
14
|
+
formItemClassName?: string;
|
|
15
|
+
/**表单项 style*/
|
|
16
|
+
formItemStyle?: React.CSSProperties;
|
|
17
|
+
/**表单项 label className*/
|
|
18
|
+
formItemLabelClassName?: string;
|
|
19
|
+
/**表单项 label style*/
|
|
20
|
+
formItemLabelStyle?: React.CSSProperties;
|
|
21
|
+
/**输入框底部边框*/
|
|
22
|
+
inputBordered?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**公共属性 Context */
|
|
26
|
+
export const AttrsContext = createContext<AttrsOptions>({
|
|
27
|
+
colCount: 4,
|
|
28
|
+
errorLayout: 'left-bottom',
|
|
29
|
+
labelMode: 'top',
|
|
30
|
+
showColon: true,
|
|
31
|
+
inputBordered: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**子项中获取公共属性*/
|
|
35
|
+
export const useAttrs = () => useContext(AttrsContext);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FormInstanceBase } from '@carefrees/form-utils';
|
|
2
|
+
import { createContext, useContext, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
/**表单实例 Context */
|
|
5
|
+
export const FormInstanceContext = createContext(new FormInstanceBase());
|
|
6
|
+
|
|
7
|
+
/**子项中获取表单实例*/
|
|
8
|
+
export function useFormInstance<T = any>() {
|
|
9
|
+
return useContext<FormInstanceBase<T>>(FormInstanceContext);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**初始化表单实例*/
|
|
13
|
+
export function useForm<T = any>(form?: FormInstanceBase<T>) {
|
|
14
|
+
const ref = useRef<FormInstanceBase<T>>();
|
|
15
|
+
if (!ref.current) {
|
|
16
|
+
if (form) {
|
|
17
|
+
ref.current = form;
|
|
18
|
+
} else {
|
|
19
|
+
ref.current = new FormInstanceBase<T>();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return ref.current;
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FormItemInstanceBase } from '@carefrees/form-utils';
|
|
2
|
+
import { createContext, useContext, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
/**表单项实例 Context */
|
|
5
|
+
export const FormItemInstanceContext = createContext(new FormItemInstanceBase());
|
|
6
|
+
|
|
7
|
+
/**子项中获取表单项实例*/
|
|
8
|
+
export const useFormItemInstance = () => useContext(FormItemInstanceContext);
|
|
9
|
+
|
|
10
|
+
/**s初始化 表单项实例*/
|
|
11
|
+
export const useFormItem = (formItem?: FormItemInstanceBase) => {
|
|
12
|
+
const ref = useRef<FormItemInstanceBase>();
|
|
13
|
+
if (!ref.current) {
|
|
14
|
+
if (formItem) {
|
|
15
|
+
ref.current = formItem;
|
|
16
|
+
} else {
|
|
17
|
+
ref.current = new FormItemInstanceBase();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return ref.current;
|
|
21
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, createElement } from 'react';
|
|
2
|
+
|
|
3
|
+
export const FormItemParentNameContext = createContext({ name: '', sort: '' });
|
|
4
|
+
|
|
5
|
+
export interface FormItemParentNamOptions {
|
|
6
|
+
/**字段*/
|
|
7
|
+
name: string;
|
|
8
|
+
/**排序*/
|
|
9
|
+
sort?: string;
|
|
10
|
+
/**是否拼接父级字段*/
|
|
11
|
+
isJoinParentField?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface FormItemParentNameProviderProps extends Omit<FormItemParentNamOptions, 'isJoinParentField'> {
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const FormItemParentNameProvider = (props: FormItemParentNameProviderProps) => {
|
|
19
|
+
const { name, sort, children } = props;
|
|
20
|
+
const value = useMemo(() => {
|
|
21
|
+
return { name, sort };
|
|
22
|
+
}, [name, sort]);
|
|
23
|
+
return createElement(FormItemParentNameContext.Provider, { value, children });
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**表单项获取父级字段*/
|
|
27
|
+
export const useFormItemParentName = (options: FormItemParentNamOptions) => {
|
|
28
|
+
const { isJoinParentField = true, sort, name } = options;
|
|
29
|
+
const parentItem = useContext(FormItemParentNameContext);
|
|
30
|
+
const parentName = parentItem.name;
|
|
31
|
+
const parentSort = parentItem.sort;
|
|
32
|
+
const newName = useMemo(() => {
|
|
33
|
+
if (parentName && isJoinParentField) {
|
|
34
|
+
if (/^\./.test(`${name}`)) {
|
|
35
|
+
return [parentName, name].filter(Boolean).join('');
|
|
36
|
+
} else if (name) {
|
|
37
|
+
return [parentName, '.', name].filter(Boolean).join('');
|
|
38
|
+
}
|
|
39
|
+
return [parentName, name].filter(Boolean).join('');
|
|
40
|
+
}
|
|
41
|
+
return [name].filter(Boolean).join('');
|
|
42
|
+
}, [isJoinParentField, name, parentName]);
|
|
43
|
+
const newSort = useMemo(
|
|
44
|
+
() => [isJoinParentField ? parentSort : '', sort].filter(Boolean).join('-'),
|
|
45
|
+
[isJoinParentField, parentSort, sort],
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return { newName, newSort, parentItem, parentName: parentName };
|
|
49
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FormListInstanceBase } from '@carefrees/form-utils';
|
|
2
|
+
import { createContext, useContext, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
/**表单List实例 Context */
|
|
5
|
+
export const FormListInstanceContext = createContext(new FormListInstanceBase());
|
|
6
|
+
|
|
7
|
+
/**子项中获取表单List实例*/
|
|
8
|
+
export const useFormListInstance = () => useContext(FormListInstanceContext);
|
|
9
|
+
|
|
10
|
+
/**初始化 表单List实例*/
|
|
11
|
+
export const useFormList = (formList?: FormListInstanceBase) => {
|
|
12
|
+
const ref = useRef<FormListInstanceBase>();
|
|
13
|
+
if (!ref.current) {
|
|
14
|
+
if (formList) {
|
|
15
|
+
ref.current = formList;
|
|
16
|
+
} else {
|
|
17
|
+
ref.current = new FormListInstanceBase();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return ref.current;
|
|
21
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useMemo, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
let localId = 0;
|
|
4
|
+
export const useHtmlFor = (suffix: string) => {
|
|
5
|
+
const count = useRef(localId++);
|
|
6
|
+
return useMemo(() => {
|
|
7
|
+
return `carefree-form-item_${count.current.toString(32)}_${suffix}`;
|
|
8
|
+
}, [count.current, suffix]);
|
|
9
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { MultipleInstanceBase } from '@carefrees/form-utils';
|
|
2
|
+
import { createContext, useContext, useRef, createElement } from 'react';
|
|
3
|
+
|
|
4
|
+
/**多表单收集 Context */
|
|
5
|
+
export const MultipleFormInstanceContext = createContext(new MultipleInstanceBase());
|
|
6
|
+
|
|
7
|
+
/**子项中获取 多表单收集 实例*/
|
|
8
|
+
export const useMultipleFormInstance = () => useContext(MultipleFormInstanceContext);
|
|
9
|
+
|
|
10
|
+
/**初始化 多表单收集 实例*/
|
|
11
|
+
export const useMultipleForm = (multipleForm?: MultipleInstanceBase) => {
|
|
12
|
+
const ref = useRef<MultipleInstanceBase>();
|
|
13
|
+
if (!ref.current) {
|
|
14
|
+
if (multipleForm) {
|
|
15
|
+
ref.current = multipleForm;
|
|
16
|
+
} else {
|
|
17
|
+
ref.current = new MultipleInstanceBase();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return ref.current;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export interface MultipleFormProviderProps {
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
multipleForm?: MultipleInstanceBase;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**多表单收集 Provider */
|
|
29
|
+
export const MultipleFormProvider = (props: MultipleFormProviderProps) => {
|
|
30
|
+
const { children, multipleForm } = props;
|
|
31
|
+
const multipleFormInstance = useMultipleForm(multipleForm);
|
|
32
|
+
return createElement(MultipleFormInstanceContext.Provider, {
|
|
33
|
+
value: multipleFormInstance,
|
|
34
|
+
children,
|
|
35
|
+
});
|
|
36
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useState, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/**更新页面状态*/
|
|
4
|
+
export const useUpdate = () => {
|
|
5
|
+
const [, _update] = useState({});
|
|
6
|
+
/**为了防止 hooks 闭包问题*/
|
|
7
|
+
const refUpdate = useRef<Function>(() => void 0);
|
|
8
|
+
refUpdate.current = () => {
|
|
9
|
+
_update({});
|
|
10
|
+
};
|
|
11
|
+
return refUpdate;
|
|
12
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { FormInstanceBase } from '@carefrees/form-utils';
|
|
3
|
+
import { useFormInstance } from './useForm';
|
|
4
|
+
import { useFormItem } from './useFormItem';
|
|
5
|
+
|
|
6
|
+
export class WatchInstanceBase {
|
|
7
|
+
/**监听字段*/
|
|
8
|
+
name: string;
|
|
9
|
+
/**表单实例*/
|
|
10
|
+
form: FormInstanceBase;
|
|
11
|
+
/**老值*/
|
|
12
|
+
oldValue: any;
|
|
13
|
+
/**更新值*/
|
|
14
|
+
dispatch: (value: any) => void;
|
|
15
|
+
/**回调*/
|
|
16
|
+
callBack?: (value: any, form: FormInstanceBase) => void;
|
|
17
|
+
/**更新*/
|
|
18
|
+
updated = () => {
|
|
19
|
+
// 如果上一次和当前相等,则不进行更新
|
|
20
|
+
const newValue = this.form.getFieldValue(this.name);
|
|
21
|
+
if (this.oldValue === newValue) {
|
|
22
|
+
/**相同不进行更新*/
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (this.callBack) {
|
|
26
|
+
this.callBack(newValue, this.form);
|
|
27
|
+
} else {
|
|
28
|
+
this.dispatch(newValue);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 字段监听
|
|
35
|
+
*/
|
|
36
|
+
export const useWatch = (
|
|
37
|
+
name: string,
|
|
38
|
+
form: FormInstanceBase,
|
|
39
|
+
callBack?: (value: any, form: FormInstanceBase) => void,
|
|
40
|
+
) => {
|
|
41
|
+
const formInstance = form || useFormInstance();
|
|
42
|
+
const [oldValue, setValue] = useState(formInstance.getFieldValue(name));
|
|
43
|
+
const watch = useRef(new WatchInstanceBase()).current;
|
|
44
|
+
watch.name = name;
|
|
45
|
+
watch.oldValue = oldValue;
|
|
46
|
+
watch.dispatch = setValue;
|
|
47
|
+
watch.callBack = callBack;
|
|
48
|
+
watch.form = formInstance;
|
|
49
|
+
|
|
50
|
+
const formItemInstance = useFormItem();
|
|
51
|
+
useMemo(() => formItemInstance.ctor(name), []);
|
|
52
|
+
formItemInstance.instance = formInstance;
|
|
53
|
+
formItemInstance.isWatch = true;
|
|
54
|
+
formItemInstance.updated = watch.updated;
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const unMount = formInstance.registerFormItem(formItemInstance);
|
|
58
|
+
return () => unMount();
|
|
59
|
+
}, []);
|
|
60
|
+
return [oldValue, formInstance, watch] as [any, FormInstanceBase, WatchInstanceBase];
|
|
61
|
+
};
|