@arco-design/mobile-react 2.36.1 → 2.37.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/CHANGELOG.md +23 -0
- package/README.en-US.md +2 -2
- package/README.md +2 -2
- package/cjs/_helpers/hooks.d.ts +1 -1
- package/cjs/_helpers/hooks.js +1 -1
- package/cjs/_helpers/react-dom.d.ts +5 -5
- package/cjs/_helpers/react-dom.js +49 -32
- package/cjs/_helpers/render.js +6 -3
- package/cjs/action-sheet/index.d.ts +3 -2
- package/cjs/action-sheet/index.js +2 -2
- package/cjs/carousel/index.js +8 -7
- package/cjs/checkbox/checkbox.d.ts +1 -1
- package/cjs/checkbox/group.d.ts +1 -1
- package/cjs/checkbox/hooks/useMergeProps.d.ts +1 -1
- package/cjs/checkbox/index.d.ts +2 -2
- package/cjs/context-provider/index.d.ts +8 -2
- package/cjs/count-down/hooks.js +2 -2
- package/cjs/dialog/index.d.ts +8 -3
- package/cjs/dialog/methods.d.ts +6 -2
- package/cjs/dropdown-menu/helper.d.ts +2 -2
- package/cjs/ellipsis/components/native-ellipsis.d.ts +2 -3
- package/cjs/ellipsis/components/native-ellipsis.js +1 -2
- package/cjs/form/form-item.d.ts +33 -2
- package/cjs/form/form-item.js +142 -121
- package/cjs/form/index.js +3 -1
- package/cjs/form/linked-container.d.ts +1 -1
- package/cjs/form/linked-container.js +4 -0
- package/cjs/form/style/css/index.css +4 -1
- package/cjs/form/style/index.less +6 -1
- package/cjs/form/type.d.ts +29 -6
- package/cjs/form/type.js +10 -2
- package/cjs/form/useForm.d.ts +2 -17
- package/cjs/form/useForm.js +98 -17
- package/cjs/form/utils.d.ts +2 -0
- package/cjs/form/utils.js +42 -2
- package/cjs/image-preview/index.d.ts +2 -2
- package/cjs/index-bar/group.js +3 -1
- package/cjs/index-bar/index.d.ts +2 -2
- package/cjs/index-bar/utils.d.ts +1 -1
- package/cjs/input/index.js +1 -1
- package/cjs/masking/index.d.ts +2 -2
- package/cjs/notify/index.d.ts +8 -8
- package/cjs/notify/index.js +2 -2
- package/cjs/picker-view/components/cascader.js +3 -1
- package/cjs/picker-view/components/picker-cell.js +1 -1
- package/cjs/picker-view/index.js +3 -1
- package/cjs/popup/index.d.ts +2 -2
- package/cjs/popup-swiper/index.d.ts +2 -2
- package/cjs/pull-refresh/hooks.d.ts +2 -2
- package/cjs/radio/group.d.ts +1 -1
- package/cjs/radio/group.js +1 -1
- package/cjs/radio/index.d.ts +2 -2
- package/cjs/radio/radio.d.ts +1 -1
- package/cjs/radio/type.d.ts +2 -2
- package/cjs/skeleton/elements.js +9 -3
- package/cjs/slider/hooks/index.d.ts +1 -1
- package/cjs/slider/hooks/useSliderEvents.d.ts +1 -1
- package/cjs/stepper/hooks/useValue.d.ts +2 -1
- package/cjs/steps/index.d.ts +1 -1
- package/cjs/tabs/type.d.ts +2 -2
- package/cjs/toast/index.d.ts +12 -12
- package/cjs/toast/index.js +1 -1
- package/dist/index.js +3070 -411
- package/dist/index.min.js +4 -4
- package/dist/style.css +4 -1
- package/dist/style.min.css +1 -1
- package/esm/_helpers/hooks.d.ts +1 -1
- package/esm/_helpers/hooks.js +1 -1
- package/esm/_helpers/react-dom.d.ts +5 -5
- package/esm/_helpers/react-dom.js +49 -30
- package/esm/_helpers/render.js +6 -3
- package/esm/action-sheet/index.d.ts +3 -2
- package/esm/action-sheet/index.js +2 -2
- package/esm/carousel/index.js +8 -7
- package/esm/checkbox/checkbox.d.ts +1 -1
- package/esm/checkbox/group.d.ts +1 -1
- package/esm/checkbox/hooks/useMergeProps.d.ts +1 -1
- package/esm/checkbox/index.d.ts +2 -2
- package/esm/context-provider/index.d.ts +8 -2
- package/esm/count-down/hooks.js +2 -2
- package/esm/dialog/index.d.ts +8 -3
- package/esm/dialog/methods.d.ts +6 -2
- package/esm/dropdown-menu/helper.d.ts +2 -2
- package/esm/ellipsis/components/native-ellipsis.d.ts +2 -3
- package/esm/ellipsis/components/native-ellipsis.js +1 -1
- package/esm/form/form-item.d.ts +33 -2
- package/esm/form/form-item.js +143 -122
- package/esm/form/index.js +3 -1
- package/esm/form/linked-container.d.ts +1 -1
- package/esm/form/linked-container.js +4 -0
- package/esm/form/style/css/index.css +4 -1
- package/esm/form/style/index.less +6 -1
- package/esm/form/type.d.ts +29 -6
- package/esm/form/type.js +8 -1
- package/esm/form/useForm.d.ts +2 -17
- package/esm/form/useForm.js +97 -17
- package/esm/form/utils.d.ts +2 -0
- package/esm/form/utils.js +31 -1
- package/esm/image-preview/index.d.ts +2 -2
- package/esm/index-bar/group.js +3 -1
- package/esm/index-bar/index.d.ts +2 -2
- package/esm/index-bar/utils.d.ts +1 -1
- package/esm/input/index.js +1 -1
- package/esm/masking/index.d.ts +2 -2
- package/esm/notify/index.d.ts +8 -8
- package/esm/notify/index.js +2 -2
- package/esm/picker-view/components/cascader.js +3 -1
- package/esm/picker-view/components/picker-cell.js +1 -1
- package/esm/picker-view/index.js +3 -1
- package/esm/popup/index.d.ts +2 -2
- package/esm/popup-swiper/index.d.ts +2 -2
- package/esm/pull-refresh/hooks.d.ts +2 -2
- package/esm/radio/group.d.ts +1 -1
- package/esm/radio/group.js +1 -1
- package/esm/radio/index.d.ts +2 -2
- package/esm/radio/radio.d.ts +1 -1
- package/esm/radio/type.d.ts +2 -2
- package/esm/skeleton/elements.js +9 -3
- package/esm/slider/hooks/index.d.ts +1 -1
- package/esm/slider/hooks/useSliderEvents.d.ts +1 -1
- package/esm/stepper/hooks/useValue.d.ts +2 -1
- package/esm/steps/index.d.ts +1 -1
- package/esm/tabs/type.d.ts +2 -2
- package/esm/toast/index.d.ts +12 -12
- package/esm/toast/index.js +1 -1
- package/esnext/_helpers/hooks.js +1 -1
- package/esnext/_helpers/react-dom.d.ts +5 -5
- package/esnext/_helpers/react-dom.js +47 -28
- package/esnext/_helpers/render.js +3 -2
- package/esnext/action-sheet/index.d.ts +3 -2
- package/esnext/action-sheet/index.js +1 -1
- package/esnext/carousel/index.js +7 -5
- package/esnext/context-provider/index.d.ts +8 -2
- package/esnext/context-provider/index.js +1 -1
- package/esnext/count-down/hooks.js +2 -2
- package/esnext/dialog/index.d.ts +8 -3
- package/esnext/dialog/methods.d.ts +6 -2
- package/esnext/dropdown-menu/helper.d.ts +1 -1
- package/esnext/ellipsis/components/native-ellipsis.d.ts +2 -3
- package/esnext/ellipsis/components/native-ellipsis.js +1 -1
- package/esnext/form/form-item.d.ts +33 -2
- package/esnext/form/form-item.js +85 -71
- package/esnext/form/index.js +2 -1
- package/esnext/form/linked-container.d.ts +1 -1
- package/esnext/form/linked-container.js +3 -0
- package/esnext/form/style/css/index.css +4 -1
- package/esnext/form/style/index.less +6 -1
- package/esnext/form/type.d.ts +29 -6
- package/esnext/form/type.js +7 -0
- package/esnext/form/useForm.d.ts +2 -17
- package/esnext/form/useForm.js +72 -13
- package/esnext/form/utils.d.ts +2 -0
- package/esnext/form/utils.js +26 -0
- package/esnext/image-preview/index.d.ts +2 -2
- package/esnext/index-bar/group.js +5 -1
- package/esnext/index-bar/index.d.ts +2 -2
- package/esnext/input/index.js +1 -1
- package/esnext/masking/index.d.ts +2 -2
- package/esnext/notify/index.d.ts +8 -8
- package/esnext/notify/index.js +2 -2
- package/esnext/picker-view/components/cascader.js +5 -1
- package/esnext/picker-view/components/picker-cell.js +1 -1
- package/esnext/picker-view/index.js +5 -1
- package/esnext/popup/index.d.ts +2 -2
- package/esnext/popup-swiper/index.d.ts +2 -2
- package/esnext/pull-refresh/hooks.d.ts +2 -2
- package/esnext/radio/group.js +3 -1
- package/esnext/radio/type.d.ts +2 -2
- package/esnext/skeleton/elements.js +15 -3
- package/esnext/slider/hooks/useSliderEvents.d.ts +1 -1
- package/esnext/tabs/type.d.ts +2 -2
- package/esnext/toast/index.d.ts +12 -12
- package/esnext/toast/index.js +1 -1
- package/package.json +3 -3
- package/umd/_helpers/hooks.d.ts +1 -1
- package/umd/_helpers/hooks.js +1 -1
- package/umd/_helpers/react-dom.d.ts +5 -5
- package/umd/_helpers/react-dom.js +53 -35
- package/umd/_helpers/render.js +6 -3
- package/umd/action-sheet/index.d.ts +3 -2
- package/umd/action-sheet/index.js +2 -2
- package/umd/carousel/index.js +8 -7
- package/umd/checkbox/checkbox.d.ts +1 -1
- package/umd/checkbox/group.d.ts +1 -1
- package/umd/checkbox/hooks/useMergeProps.d.ts +1 -1
- package/umd/checkbox/index.d.ts +2 -2
- package/umd/context-provider/index.d.ts +8 -2
- package/umd/count-down/hooks.js +2 -2
- package/umd/dialog/index.d.ts +8 -3
- package/umd/dialog/methods.d.ts +6 -2
- package/umd/dropdown-menu/helper.d.ts +2 -2
- package/umd/ellipsis/components/native-ellipsis.d.ts +2 -3
- package/umd/ellipsis/components/native-ellipsis.js +1 -2
- package/umd/form/form-item.d.ts +33 -2
- package/umd/form/form-item.js +142 -121
- package/umd/form/index.js +3 -1
- package/umd/form/linked-container.d.ts +1 -1
- package/umd/form/linked-container.js +4 -0
- package/umd/form/style/css/index.css +4 -1
- package/umd/form/style/index.less +6 -1
- package/umd/form/type.d.ts +29 -6
- package/umd/form/type.js +9 -1
- package/umd/form/useForm.d.ts +2 -17
- package/umd/form/useForm.js +98 -21
- package/umd/form/utils.d.ts +2 -0
- package/umd/form/utils.js +40 -5
- package/umd/image-preview/index.d.ts +2 -2
- package/umd/index-bar/group.js +3 -1
- package/umd/index-bar/index.d.ts +2 -2
- package/umd/index-bar/utils.d.ts +1 -1
- package/umd/input/index.js +1 -1
- package/umd/masking/index.d.ts +2 -2
- package/umd/notify/index.d.ts +8 -8
- package/umd/notify/index.js +2 -2
- package/umd/picker-view/components/cascader.js +3 -1
- package/umd/picker-view/components/picker-cell.js +1 -1
- package/umd/picker-view/index.js +3 -1
- package/umd/popup/index.d.ts +2 -2
- package/umd/popup-swiper/index.d.ts +2 -2
- package/umd/pull-refresh/hooks.d.ts +2 -2
- package/umd/radio/group.d.ts +1 -1
- package/umd/radio/group.js +1 -1
- package/umd/radio/index.d.ts +2 -2
- package/umd/radio/radio.d.ts +1 -1
- package/umd/radio/type.d.ts +2 -2
- package/umd/skeleton/elements.js +9 -3
- package/umd/slider/hooks/index.d.ts +1 -1
- package/umd/slider/hooks/useSliderEvents.d.ts +1 -1
- package/umd/stepper/hooks/useValue.d.ts +2 -1
- package/umd/steps/index.d.ts +1 -1
- package/umd/tabs/type.d.ts +2 -2
- package/umd/toast/index.d.ts +12 -12
- package/umd/toast/index.js +1 -1
package/esnext/form/form-item.js
CHANGED
@@ -4,37 +4,66 @@ import { cls, Validator, ValidatorType } from '@arco-design/mobile-utils';
|
|
4
4
|
import { Promise } from 'es6-promise';
|
5
5
|
import { FormItemContext } from './form-item-context';
|
6
6
|
import { GlobalContext } from '../context-provider';
|
7
|
-
import { FormInternalComponentType, } from './type';
|
8
|
-
import { getErrorAndWarnings, isFieldRequired } from './utils';
|
7
|
+
import { FormInternalComponentType, ValueChangeType, } from './type';
|
8
|
+
import { getDefaultValueForInterComponent, getErrorAndWarnings, isFieldRequired } from './utils';
|
9
9
|
import { DefaultDatePickerLinkedContainer, DefaultPickerLinkedContainer } from './linked-container';
|
10
10
|
class FormItemInner extends PureComponent {
|
11
11
|
constructor(props, context) {
|
12
12
|
super(props);
|
13
13
|
this._errors = [];
|
14
14
|
this._touched = false;
|
15
|
-
this.onValueChange = (curValue, preValue) => {
|
15
|
+
this.onValueChange = (curValue, preValue, info) => {
|
16
16
|
this._touched = true;
|
17
17
|
const { shouldUpdate } = this.props;
|
18
18
|
if (typeof shouldUpdate === 'function') {
|
19
19
|
shouldUpdate({ preValue, curValue }) && this.forceUpdate();
|
20
20
|
return;
|
21
21
|
}
|
22
|
+
if (info?.changeType === ValueChangeType.Reset) {
|
23
|
+
this.props.onValidateStatusChange({
|
24
|
+
errors: [],
|
25
|
+
warnings: [],
|
26
|
+
errorTypes: [],
|
27
|
+
});
|
28
|
+
this._errors = [];
|
29
|
+
}
|
22
30
|
this.forceUpdate();
|
23
31
|
};
|
32
|
+
this.getInitialValue = () => {
|
33
|
+
const { children, displayType } = this.props;
|
34
|
+
const { getInitialValue } = this.context.form.getInternalHooks();
|
35
|
+
const childrenType = displayType || children.type?.displayName;
|
36
|
+
// get user-defined initialValue or if not defined
|
37
|
+
return getInitialValue(this.props.field) ?? getDefaultValueForInterComponent(childrenType);
|
38
|
+
};
|
24
39
|
this.getFieldError = () => {
|
25
40
|
return this._errors;
|
26
41
|
};
|
27
42
|
this.isFieldTouched = () => {
|
28
43
|
return this._touched;
|
29
44
|
};
|
30
|
-
this.
|
45
|
+
this.getAllRuleValidateTriggers = () => {
|
46
|
+
return (this.props.rules
|
47
|
+
?.map(rule => rule.validateTrigger)
|
48
|
+
.flat()
|
49
|
+
.filter(v => !!v) || []);
|
50
|
+
};
|
51
|
+
this.validateField = (validateTrigger) => {
|
31
52
|
const { validateMessages } = this.context;
|
32
53
|
const { getFieldValue } = this.context.form;
|
33
54
|
const { field, rules, onValidateStatusChange } = this.props;
|
34
55
|
const value = getFieldValue(field);
|
35
|
-
if
|
56
|
+
// rules: if validateTrigger is not defined, all rules will be validated
|
57
|
+
// if validateTrigger is defined, only rules with validateTrigger or without rule.validateTrigger will be validated
|
58
|
+
const curRules = validateTrigger
|
59
|
+
? rules?.filter(rule => {
|
60
|
+
const triggerList = [].concat(rule.validateTrigger || validateTrigger);
|
61
|
+
return triggerList.includes(validateTrigger);
|
62
|
+
})
|
63
|
+
: rules;
|
64
|
+
if (curRules?.length && field) {
|
36
65
|
const fieldDom = this.props.getFormItemRef();
|
37
|
-
const fieldValidator = new Validator({ [field]:
|
66
|
+
const fieldValidator = new Validator({ [field]: curRules }, { validateMessages });
|
38
67
|
return new Promise(resolve => {
|
39
68
|
fieldValidator.validate({ [field]: value }, (errorsMap) => {
|
40
69
|
const { errors, warnings, errorTypes } = getErrorAndWarnings(errorsMap?.[field] || []);
|
@@ -57,17 +86,10 @@ class FormItemInner extends PureComponent {
|
|
57
86
|
return Promise.resolve({ errors: [], warnings: [], value, field, dom: null });
|
58
87
|
};
|
59
88
|
this.setFieldData = (value) => {
|
60
|
-
const { field } = this.props;
|
61
|
-
const {
|
62
|
-
|
63
|
-
this.validateField();
|
64
|
-
};
|
65
|
-
this.innerTriggerFunction = (_, value, ...args) => {
|
66
|
-
this.setFieldData(value);
|
67
|
-
const { children, trigger = 'onChange' } = this.props;
|
68
|
-
if (trigger && children.props?.[trigger]) {
|
69
|
-
children.props?.[trigger](_, value, ...args);
|
70
|
-
}
|
89
|
+
const { field, trigger = 'onChange' } = this.props;
|
90
|
+
const { innerSetFieldValue } = this.context.form.getInternalHooks();
|
91
|
+
innerSetFieldValue(field, value);
|
92
|
+
this.validateField(trigger);
|
71
93
|
};
|
72
94
|
this.innerTriggerFunctionWithValueFirst = (value, ...args) => {
|
73
95
|
this.setFieldData(value);
|
@@ -76,6 +98,11 @@ class FormItemInner extends PureComponent {
|
|
76
98
|
children.props?.[trigger](value, ...args);
|
77
99
|
}
|
78
100
|
};
|
101
|
+
this.innerOnInputFunction = (_, value, ...args) => {
|
102
|
+
this.setFieldData(value);
|
103
|
+
const { children } = this.props;
|
104
|
+
children.props?.onInput?.(_, value, ...args);
|
105
|
+
};
|
79
106
|
this.innerClearFunction = (...args) => {
|
80
107
|
const { children } = this.props;
|
81
108
|
this.setFieldData('');
|
@@ -85,8 +112,8 @@ class FormItemInner extends PureComponent {
|
|
85
112
|
};
|
86
113
|
this.destroyField = () => { };
|
87
114
|
if (props?.initialValue && props.field) {
|
88
|
-
const {
|
89
|
-
|
115
|
+
const { setInitialValue } = context.form.getInternalHooks();
|
116
|
+
setInitialValue(props.field, props.initialValue);
|
90
117
|
}
|
91
118
|
}
|
92
119
|
componentDidMount() {
|
@@ -97,82 +124,69 @@ class FormItemInner extends PureComponent {
|
|
97
124
|
this.destroyField();
|
98
125
|
}
|
99
126
|
renderChildren() {
|
100
|
-
const { children, field, trigger = 'onChange', triggerPropsField = 'value', displayType, } = this.props;
|
127
|
+
const { children, field, trigger = 'onChange', triggerPropsField = 'value', displayType, disabled, } = this.props;
|
101
128
|
const { getFieldValue } = this.context.form;
|
102
|
-
|
103
|
-
|
104
|
-
disabled: this.props.disabled,
|
129
|
+
const childrenProps = {
|
130
|
+
disabled,
|
105
131
|
};
|
132
|
+
// inject validateTriggers of rules
|
133
|
+
this.getAllRuleValidateTriggers().forEach(triggerName => {
|
134
|
+
childrenProps[triggerName] = e => {
|
135
|
+
this.validateField(triggerName);
|
136
|
+
children?.props?.[triggerName]?.(e);
|
137
|
+
};
|
138
|
+
});
|
106
139
|
const childrenType = displayType || children.type?.displayName;
|
107
140
|
switch (childrenType) {
|
108
141
|
case FormInternalComponentType.Input:
|
109
142
|
case FormInternalComponentType.Textarea:
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
break;
|
117
|
-
case FormInternalComponentType.Checkbox:
|
118
|
-
case FormInternalComponentType.Radio:
|
119
|
-
case FormInternalComponentType.Slider:
|
120
|
-
case FormInternalComponentType.RadioGroup:
|
121
|
-
case FormInternalComponentType.CheckboxGroup:
|
122
|
-
props = {
|
123
|
-
value: getFieldValue(field),
|
124
|
-
onChange: this.innerTriggerFunctionWithValueFirst,
|
125
|
-
disabled: this.props.disabled,
|
126
|
-
};
|
143
|
+
childrenProps.value =
|
144
|
+
getFieldValue(field) || '';
|
145
|
+
childrenProps.onInput =
|
146
|
+
this.innerOnInputFunction;
|
147
|
+
childrenProps.onClear =
|
148
|
+
this.innerClearFunction;
|
127
149
|
break;
|
128
150
|
case FormInternalComponentType.DatePicker:
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
((ts, types) => React.createElement(DefaultDatePickerLinkedContainer, { ts: ts, types: types }))
|
135
|
-
};
|
151
|
+
childrenProps.currentTs = getFieldValue(field);
|
152
|
+
childrenProps.onChange =
|
153
|
+
this.innerTriggerFunctionWithValueFirst;
|
154
|
+
childrenProps.renderLinkedContainer =
|
155
|
+
children.props?.renderLinkedContainer ||
|
156
|
+
((ts, types) => React.createElement(DefaultDatePickerLinkedContainer, { ts: ts, types: types }));
|
136
157
|
break;
|
137
158
|
case FormInternalComponentType.Picker:
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
(val => React.createElement(DefaultPickerLinkedContainer, { value: val })),
|
144
|
-
};
|
159
|
+
childrenProps.value = getFieldValue(field) || '';
|
160
|
+
childrenProps.onChange = this.innerTriggerFunctionWithValueFirst;
|
161
|
+
childrenProps.renderLinkedContainer =
|
162
|
+
children.props?.renderLinkedContainer ||
|
163
|
+
(val => React.createElement(DefaultPickerLinkedContainer, { value: val }));
|
145
164
|
break;
|
146
165
|
case FormInternalComponentType.Switch:
|
147
|
-
|
148
|
-
|
149
|
-
onChange: this.innerTriggerFunctionWithValueFirst,
|
150
|
-
disabled: this.props.disabled,
|
151
|
-
};
|
166
|
+
childrenProps.checked = Boolean(getFieldValue(field));
|
167
|
+
childrenProps.onChange = this.innerTriggerFunctionWithValueFirst;
|
152
168
|
break;
|
153
169
|
case FormInternalComponentType.ImagePicker:
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
disabled: this.props.disabled,
|
158
|
-
};
|
170
|
+
childrenProps.images = getFieldValue(field);
|
171
|
+
childrenProps.onChange =
|
172
|
+
this.innerTriggerFunctionWithValueFirst;
|
159
173
|
break;
|
160
174
|
default:
|
161
|
-
|
175
|
+
if (triggerPropsField) {
|
176
|
+
childrenProps[triggerPropsField] = getFieldValue(field);
|
177
|
+
}
|
162
178
|
// inject the validated result
|
163
|
-
|
164
|
-
|
165
|
-
this.setFieldData(newValue);
|
166
|
-
originTrigger && originTrigger(newValue, ...args);
|
167
|
-
};
|
179
|
+
childrenProps.error = this._errors;
|
180
|
+
childrenProps[trigger] = this.innerTriggerFunctionWithValueFirst;
|
168
181
|
}
|
169
|
-
return React.cloneElement(children,
|
182
|
+
return React.cloneElement(children, childrenProps);
|
170
183
|
}
|
171
184
|
render() {
|
172
185
|
return this.renderChildren();
|
173
186
|
}
|
174
187
|
}
|
175
188
|
FormItemInner.contextType = FormItemContext;
|
189
|
+
export { FormItemInner };
|
176
190
|
export default forwardRef((props, ref) => {
|
177
191
|
const { label, field, disabled = false, layout: itemLayout, style, extra, requiredIcon, rules, className = '', ...rest } = props;
|
178
192
|
const { prefixCls } = useContext(GlobalContext);
|
package/esnext/form/index.js
CHANGED
@@ -7,7 +7,7 @@ import useForm from './useForm';
|
|
7
7
|
export { default as useForm } from './useForm';
|
8
8
|
export * from './type';
|
9
9
|
const Form = forwardRef((props, ref) => {
|
10
|
-
const { className = '', style, layout = 'horizontal', initialValues, form: formInstance, children, onValuesChange, onSubmit, onSubmitFailed, disabled, } = props;
|
10
|
+
const { className = '', style, layout = 'horizontal', initialValues, form: formInstance, children, onValuesChange, onChange, onSubmit, onSubmitFailed, disabled, } = props;
|
11
11
|
const domRef = useRef(null);
|
12
12
|
const initRef = useRef(false);
|
13
13
|
const [form] = useForm(formInstance);
|
@@ -16,6 +16,7 @@ const Form = forwardRef((props, ref) => {
|
|
16
16
|
onValuesChange,
|
17
17
|
onSubmit,
|
18
18
|
onSubmitFailed,
|
19
|
+
onChange,
|
19
20
|
});
|
20
21
|
if (!initRef.current) {
|
21
22
|
setInitialValues(initialValues || {});
|
@@ -3,6 +3,6 @@ export declare function DefaultPickerLinkedContainer({ value }: {
|
|
3
3
|
value: (string | number)[];
|
4
4
|
}): JSX.Element;
|
5
5
|
export declare function DefaultDatePickerLinkedContainer({ ts, types, }: {
|
6
|
-
ts
|
6
|
+
ts?: number | [number, number];
|
7
7
|
types: string[];
|
8
8
|
}): JSX.Element;
|
@@ -11,6 +11,9 @@ export function DefaultDatePickerLinkedContainer({ ts, types, }) {
|
|
11
11
|
const { prefixCls, locale } = useContext(GlobalContext);
|
12
12
|
const className = `${prefixCls}-form-picker-link-container`;
|
13
13
|
const dateTimeStr = useMemo(() => {
|
14
|
+
if (ts === undefined) {
|
15
|
+
return '';
|
16
|
+
}
|
14
17
|
if (typeof ts === 'number') {
|
15
18
|
return formatDateTimeStr(ts, types);
|
16
19
|
}
|
@@ -567,6 +567,9 @@
|
|
567
567
|
.arco-form-item-control .arco-input {
|
568
568
|
padding: 0;
|
569
569
|
}
|
570
|
+
.arco-form-item-control .arco-input-wrap.textarea {
|
571
|
+
padding: 0;
|
572
|
+
}
|
570
573
|
.arco-form-item-control-wrapper {
|
571
574
|
width: 100%;
|
572
575
|
-webkit-box-flex: 1;
|
@@ -574,7 +577,7 @@
|
|
574
577
|
flex: 1;
|
575
578
|
position: relative;
|
576
579
|
}
|
577
|
-
.arco-form-item-control-wrapper .arco-input-wrap {
|
580
|
+
.arco-form-item-control-wrapper .arco-input-wrap.single-line {
|
578
581
|
height: 0.44rem ;
|
579
582
|
}
|
580
583
|
.arco-form-item-message {
|
@@ -42,11 +42,16 @@
|
|
42
42
|
.@{prefix}-input-wrap, .@{prefix}-input {
|
43
43
|
padding: 0;
|
44
44
|
}
|
45
|
+
|
46
|
+
.@{prefix}-input-wrap.textarea {
|
47
|
+
padding: 0;
|
48
|
+
}
|
49
|
+
|
45
50
|
&-wrapper {
|
46
51
|
width: 100%;
|
47
52
|
flex: 1;
|
48
53
|
position: relative;
|
49
|
-
.@{prefix}-input-wrap {
|
54
|
+
.@{prefix}-input-wrap.single-line {
|
50
55
|
.use-var(height, input-text-line-height);
|
51
56
|
}
|
52
57
|
}
|
package/esnext/form/type.d.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import { IRules } from '@arco-design/mobile-utils';
|
2
|
-
import { ReactNode } from 'react';
|
2
|
+
import { ReactElement, ReactNode } from 'react';
|
3
3
|
import { Promise } from 'es6-promise';
|
4
4
|
export declare type FieldValue = any;
|
5
|
-
export declare type FieldItem = Record<string,
|
5
|
+
export declare type FieldItem = Record<string, FieldValue>;
|
6
6
|
export declare type ILayout = 'horizontal' | 'vertical' | 'inline';
|
7
7
|
export declare enum FormInternalComponentType {
|
8
8
|
Input = "Input",
|
@@ -46,12 +46,17 @@ export interface FormProps {
|
|
46
46
|
* @en Form initial value
|
47
47
|
*/
|
48
48
|
initialValues?: FieldItem;
|
49
|
-
children:
|
49
|
+
children: ReactNode[] | ReactNode;
|
50
50
|
/**
|
51
51
|
* 表单项数据变化时的回调
|
52
52
|
* @en Callback when the form item value changes
|
53
53
|
*/
|
54
54
|
onValuesChange?: Callbacks['onValuesChange'];
|
55
|
+
/**
|
56
|
+
* 表单项数据变化时的回调(仅用户操作表单时触发)
|
57
|
+
* @en Callback when the form item value changes (Only trigger when user operate form)
|
58
|
+
*/
|
59
|
+
onChange?: Callbacks['onChange'];
|
55
60
|
/**
|
56
61
|
* 表单项数据变化时的回调
|
57
62
|
* @en Callback when the form is submitted
|
@@ -115,6 +120,11 @@ export interface Callbacks {
|
|
115
120
|
* @en Callback when the form item value changes
|
116
121
|
*/
|
117
122
|
onValuesChange?: (changedValues: FieldValue, values: FieldValue) => void;
|
123
|
+
/**
|
124
|
+
* 表单项数据变化时的回调(仅用户操作表单时触发)
|
125
|
+
* @en Callback when the form item value changes (Only trigger when user operate form)
|
126
|
+
*/
|
127
|
+
onChange?: (changedValues: FieldValue, values: FieldValue) => void;
|
118
128
|
/**
|
119
129
|
* 表单项数据变化时的回调
|
120
130
|
* @en Callback when the form is submitted
|
@@ -134,6 +144,10 @@ export interface InternalHooks {
|
|
134
144
|
registerField: (name: string, self: any) => () => void;
|
135
145
|
setInitialValues: (values: FieldItem) => void;
|
136
146
|
setCallbacks: (callbacks: Callbacks) => void;
|
147
|
+
getInitialValue: (fieldName: string) => FieldValue;
|
148
|
+
setInitialValue: (fieldName: string, values: FieldItem) => void;
|
149
|
+
innerSetFieldsValue: (values: FieldItem) => boolean;
|
150
|
+
innerSetFieldValue: (name: string, value: FieldValue) => boolean;
|
137
151
|
}
|
138
152
|
export interface IFormInstance {
|
139
153
|
/**
|
@@ -183,6 +197,11 @@ export declare type InternalFormInstance = IFormInstance & {
|
|
183
197
|
* @en Get internal methods
|
184
198
|
*/
|
185
199
|
getInternalHooks: () => InternalHooks;
|
200
|
+
/**
|
201
|
+
* 注册表单组件
|
202
|
+
* @en Register Form Item component
|
203
|
+
*/
|
204
|
+
registerField: (name: string, self: any) => () => void;
|
186
205
|
};
|
187
206
|
export interface FormRef {
|
188
207
|
/**
|
@@ -263,7 +282,7 @@ export interface FormItemProps {
|
|
263
282
|
* 表单项子节点
|
264
283
|
* @en Form item children
|
265
284
|
*/
|
266
|
-
children:
|
285
|
+
children: ReactElement;
|
267
286
|
/**
|
268
287
|
* 表单项是否刷新
|
269
288
|
* @en Form item is updated
|
@@ -278,7 +297,7 @@ export interface FormItemProps {
|
|
278
297
|
* 表单项下方节点
|
279
298
|
* @en Form item extra node
|
280
299
|
*/
|
281
|
-
extra?:
|
300
|
+
extra?: ReactElement;
|
282
301
|
/**
|
283
302
|
* 触发事件更新事件名称
|
284
303
|
* @en The function name when updating data
|
@@ -318,7 +337,7 @@ export interface IFormItemInnerProps {
|
|
318
337
|
* 表单项子节点
|
319
338
|
* @en Form item children
|
320
339
|
*/
|
321
|
-
children:
|
340
|
+
children: ReactElement<any, any>;
|
322
341
|
/**
|
323
342
|
* 表单项是否刷新
|
324
343
|
* @en Form item is updated
|
@@ -371,3 +390,7 @@ export interface IFormItemInnerProps {
|
|
371
390
|
*/
|
372
391
|
displayType?: FormInternalComponentType;
|
373
392
|
}
|
393
|
+
export declare enum ValueChangeType {
|
394
|
+
Update = 0,
|
395
|
+
Reset = 1
|
396
|
+
}
|
package/esnext/form/type.js
CHANGED
@@ -24,3 +24,10 @@ export var ValidateStatus;
|
|
24
24
|
ValidateStatus["Validating"] = "validating";
|
25
25
|
ValidateStatus["Success"] = "success";
|
26
26
|
})(ValidateStatus || (ValidateStatus = {}));
|
27
|
+
export var ValueChangeType;
|
28
|
+
(function (ValueChangeType) {
|
29
|
+
/* form update */
|
30
|
+
ValueChangeType[ValueChangeType["Update"] = 0] = "Update";
|
31
|
+
/* form clear */
|
32
|
+
ValueChangeType[ValueChangeType["Reset"] = 1] = "Reset";
|
33
|
+
})(ValueChangeType || (ValueChangeType = {}));
|
package/esnext/form/useForm.d.ts
CHANGED
@@ -1,18 +1,3 @@
|
|
1
|
-
import { IFormInstance } from './type';
|
2
|
-
export declare const defaultFormDataMethods:
|
3
|
-
getFieldValue: (name: any) => any;
|
4
|
-
getFieldsValue: (_names: any) => {};
|
5
|
-
getFieldError: (_name: any) => never[];
|
6
|
-
setFieldValue: (_name: any, _value: any) => boolean;
|
7
|
-
setFieldsValue: (_values: any) => boolean;
|
8
|
-
registerField: (_name: any, _self: any) => () => void;
|
9
|
-
resetFields: any;
|
10
|
-
validateFields: any;
|
11
|
-
submit: any;
|
12
|
-
getInternalHooks: () => {
|
13
|
-
registerField: any;
|
14
|
-
setInitialValues: any;
|
15
|
-
setCallbacks: any;
|
16
|
-
};
|
17
|
-
};
|
1
|
+
import { IFormInstance, InternalFormInstance } from './type';
|
2
|
+
export declare const defaultFormDataMethods: InternalFormInstance;
|
18
3
|
export default function useForm(form?: IFormInstance): IFormInstance[];
|
package/esnext/form/useForm.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
/* eslint-disable no-console */
|
2
2
|
import { useRef } from 'react';
|
3
3
|
import { Promise } from 'es6-promise';
|
4
|
+
import { ValueChangeType, } from './type';
|
5
|
+
import { deepClone } from './utils';
|
4
6
|
const defaultFunc = () => { };
|
5
7
|
export const defaultFormDataMethods = {
|
6
8
|
getFieldValue: name => name,
|
@@ -25,6 +27,10 @@ export const defaultFormDataMethods = {
|
|
25
27
|
registerField: defaultFunc,
|
26
28
|
setInitialValues: defaultFunc,
|
27
29
|
setCallbacks: defaultFunc,
|
30
|
+
getInitialValue: defaultFunc,
|
31
|
+
setInitialValue: defaultFunc,
|
32
|
+
innerSetFieldsValue: defaultFunc,
|
33
|
+
innerSetFieldValue: defaultFunc,
|
28
34
|
};
|
29
35
|
},
|
30
36
|
};
|
@@ -35,33 +41,61 @@ class FormData {
|
|
35
41
|
this._fieldsList = {}; // 字段列表
|
36
42
|
this._initialValues = {}; // 初始值
|
37
43
|
this._callbacks = {};
|
38
|
-
this.
|
44
|
+
this.commonSetFieldsValue = (values, changeType) => {
|
39
45
|
const oldValues = Object.keys(values).reduce((acc, key) => ({
|
40
46
|
...acc,
|
41
47
|
[key]: this.getFieldValue(key),
|
42
48
|
}), {});
|
43
49
|
this._formData = { ...this._formData, ...values };
|
50
|
+
this.notifyField(values, oldValues, changeType);
|
51
|
+
};
|
52
|
+
this.setFieldsValue = (values) => {
|
53
|
+
this.commonSetFieldsValue(values);
|
44
54
|
const { onValuesChange } = this._callbacks;
|
45
|
-
onValuesChange
|
46
|
-
this.notifyField(values, oldValues);
|
55
|
+
onValuesChange?.(values, this._formData);
|
47
56
|
return true;
|
48
57
|
};
|
49
|
-
this.
|
58
|
+
this.innerSetFieldsValue = (values, changeType) => {
|
59
|
+
this.commonSetFieldsValue(values, changeType);
|
60
|
+
const { onValuesChange, onChange } = this._callbacks;
|
61
|
+
onValuesChange?.(values, this._formData);
|
62
|
+
onChange?.(values, this._formData);
|
63
|
+
return true;
|
64
|
+
};
|
65
|
+
this.commonSetFieldValue = (name, value, changeType) => {
|
50
66
|
const oldValues = { [name]: this.getFieldValue(name) };
|
51
67
|
this._formData = { ...this._formData, [name]: value };
|
68
|
+
this.notifyField({ [name]: value }, oldValues, changeType);
|
69
|
+
};
|
70
|
+
this.setFieldValue = (name, value) => {
|
71
|
+
this.commonSetFieldValue(name, value);
|
52
72
|
const { onValuesChange } = this._callbacks;
|
53
73
|
onValuesChange &&
|
54
74
|
onValuesChange({
|
55
75
|
[name]: value,
|
76
|
+
}, this.getFieldsValue());
|
77
|
+
return true;
|
78
|
+
};
|
79
|
+
this.innerSetFieldValue = (name, value, changeType) => {
|
80
|
+
this.commonSetFieldValue(name, value, changeType);
|
81
|
+
const { onValuesChange, onChange } = this._callbacks;
|
82
|
+
onValuesChange &&
|
83
|
+
onValuesChange({
|
84
|
+
[name]: value,
|
85
|
+
}, this._formData);
|
86
|
+
onChange &&
|
87
|
+
onChange({
|
88
|
+
[name]: value,
|
56
89
|
}, this._formData);
|
57
|
-
this.notifyField({ [name]: value }, oldValues);
|
58
90
|
return true;
|
59
91
|
};
|
60
|
-
this.notifyField = (values, oldValues) => {
|
92
|
+
this.notifyField = (values, oldValues, changeType = ValueChangeType.Update) => {
|
61
93
|
Object.keys(values).map((fieldName) => {
|
62
94
|
const fieldObj = this._fieldsList?.[fieldName] || null;
|
63
95
|
if (fieldObj) {
|
64
|
-
fieldObj.onValueChange(values[fieldName], oldValues[fieldName]
|
96
|
+
fieldObj.onValueChange(values[fieldName], oldValues[fieldName], {
|
97
|
+
changeType,
|
98
|
+
});
|
65
99
|
}
|
66
100
|
});
|
67
101
|
};
|
@@ -69,10 +103,10 @@ class FormData {
|
|
69
103
|
if (names) {
|
70
104
|
return names.map(name => this.getFieldValue(name));
|
71
105
|
}
|
72
|
-
return this._formData;
|
106
|
+
return deepClone(this._formData);
|
73
107
|
};
|
74
108
|
this.getFieldValue = (name) => {
|
75
|
-
return this._formData?.[name];
|
109
|
+
return deepClone(this._formData?.[name]);
|
76
110
|
};
|
77
111
|
this.getFieldError = (name) => {
|
78
112
|
const field = this._fieldsList?.[name] || null;
|
@@ -119,11 +153,32 @@ class FormData {
|
|
119
153
|
};
|
120
154
|
};
|
121
155
|
this.setInitialValues = (initVal) => {
|
122
|
-
this._initialValues =
|
156
|
+
this._initialValues = deepClone(initVal || {});
|
123
157
|
this.setFieldsValue(initVal);
|
124
158
|
};
|
159
|
+
this.setInitialValue = (fieldName, value) => {
|
160
|
+
if (!fieldName) {
|
161
|
+
return;
|
162
|
+
}
|
163
|
+
this._initialValues[fieldName] = value;
|
164
|
+
this.setFieldValue(fieldName, value);
|
165
|
+
};
|
166
|
+
this.getInitialValue = (fieldName) => {
|
167
|
+
return this._initialValues[fieldName];
|
168
|
+
};
|
125
169
|
this.resetFields = () => {
|
126
|
-
this.
|
170
|
+
const oldValues = { ...this._formData };
|
171
|
+
const initialValues = {};
|
172
|
+
Object.keys(this._formData).forEach((fieldName) => {
|
173
|
+
const fieldObj = this._fieldsList?.[fieldName] || null;
|
174
|
+
if (fieldObj) {
|
175
|
+
initialValues[fieldName] = fieldObj.getInitialValue();
|
176
|
+
}
|
177
|
+
});
|
178
|
+
const { onValuesChange } = this._callbacks;
|
179
|
+
onValuesChange && onValuesChange(initialValues, this._formData);
|
180
|
+
this._formData = initialValues;
|
181
|
+
this.notifyField(initialValues, oldValues, ValueChangeType.Reset);
|
127
182
|
};
|
128
183
|
this.validateFields = () => {
|
129
184
|
const promiseList = [];
|
@@ -148,14 +203,14 @@ class FormData {
|
|
148
203
|
this.validateFields()
|
149
204
|
.then(result => {
|
150
205
|
const { onSubmit } = this._callbacks;
|
151
|
-
onSubmit?.(this.
|
206
|
+
onSubmit?.(this.getFieldsValue(), result);
|
152
207
|
})
|
153
208
|
.catch(e => {
|
154
209
|
const { onSubmitFailed } = this._callbacks;
|
155
210
|
if (!onSubmitFailed) {
|
156
211
|
return;
|
157
212
|
}
|
158
|
-
onSubmitFailed(this.
|
213
|
+
onSubmitFailed(this.getFieldsValue(), e);
|
159
214
|
});
|
160
215
|
};
|
161
216
|
this.setCallbacks = (callbacks) => {
|
@@ -182,6 +237,10 @@ class FormData {
|
|
182
237
|
registerField: this.registerField,
|
183
238
|
setInitialValues: this.setInitialValues,
|
184
239
|
setCallbacks: this.setCallbacks,
|
240
|
+
getInitialValue: this.getInitialValue,
|
241
|
+
setInitialValue: this.setInitialValue,
|
242
|
+
innerSetFieldsValue: this.innerSetFieldsValue,
|
243
|
+
innerSetFieldValue: this.innerSetFieldValue,
|
185
244
|
};
|
186
245
|
};
|
187
246
|
}
|
package/esnext/form/utils.d.ts
CHANGED
@@ -5,3 +5,5 @@ export declare const getErrorAndWarnings: (result: ValidatorError[]) => {
|
|
5
5
|
errors: string[];
|
6
6
|
errorTypes: string[];
|
7
7
|
};
|
8
|
+
export declare const getDefaultValueForInterComponent: (componentType: string) => 0 | never[] | null | undefined;
|
9
|
+
export declare function deepClone(value: any): any;
|
package/esnext/form/utils.js
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
import { isObject, isArray } from '@arco-design/mobile-utils';
|
2
|
+
import cloneDeepWith from 'lodash/cloneDeepWith';
|
3
|
+
import { FormInternalComponentType } from './type';
|
1
4
|
export const isFieldRequired = (rules = []) => {
|
2
5
|
return (rules || []).some(rule => rule?.required);
|
3
6
|
};
|
@@ -19,3 +22,26 @@ export const getErrorAndWarnings = (result) => {
|
|
19
22
|
});
|
20
23
|
return { warnings, errors, errorTypes };
|
21
24
|
};
|
25
|
+
export const getDefaultValueForInterComponent = (componentType) => {
|
26
|
+
switch (componentType) {
|
27
|
+
case FormInternalComponentType.Input:
|
28
|
+
case FormInternalComponentType.Textarea:
|
29
|
+
return undefined;
|
30
|
+
case FormInternalComponentType.CheckboxGroup:
|
31
|
+
return [];
|
32
|
+
case FormInternalComponentType.RadioGroup:
|
33
|
+
return null;
|
34
|
+
case FormInternalComponentType.Slider:
|
35
|
+
case FormInternalComponentType.Rate:
|
36
|
+
return 0;
|
37
|
+
default:
|
38
|
+
return undefined;
|
39
|
+
}
|
40
|
+
};
|
41
|
+
export function deepClone(value) {
|
42
|
+
return cloneDeepWith(value, val => {
|
43
|
+
if (!isObject(val) && !isArray(val)) {
|
44
|
+
return val;
|
45
|
+
}
|
46
|
+
});
|
47
|
+
}
|