@arco-design/mobile-react 2.36.0 → 2.36.2
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 +24 -0
- package/README.en-US.md +2 -2
- package/README.md +2 -2
- package/cjs/carousel/index.js +8 -7
- package/cjs/ellipsis/components/js-ellipsis.js +3 -1
- 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 +24 -1
- 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/input/index.js +1 -1
- package/cjs/popover/hooks/usePosition.js +26 -8
- package/cjs/radio/group.js +1 -1
- package/cjs/radio/type.d.ts +2 -2
- package/dist/index.js +3021 -370
- package/dist/index.min.js +4 -4
- package/dist/style.css +4 -1
- package/dist/style.min.css +1 -1
- package/esm/carousel/index.js +8 -7
- package/esm/ellipsis/components/js-ellipsis.js +3 -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 +24 -1
- 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/input/index.js +1 -1
- package/esm/popover/hooks/usePosition.js +26 -8
- package/esm/radio/group.js +1 -1
- package/esm/radio/type.d.ts +2 -2
- package/esnext/carousel/index.js +7 -5
- package/esnext/ellipsis/components/js-ellipsis.js +2 -0
- 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 +24 -1
- 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/input/index.js +1 -1
- package/esnext/popover/hooks/usePosition.js +32 -12
- package/esnext/radio/group.js +3 -1
- package/esnext/radio/type.d.ts +2 -2
- package/package.json +3 -3
- package/umd/carousel/index.js +8 -7
- package/umd/ellipsis/components/js-ellipsis.js +3 -1
- 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 +24 -1
- 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/input/index.js +1 -1
- package/umd/popover/hooks/usePosition.js +26 -8
- package/umd/radio/group.js +1 -1
- package/umd/radio/type.d.ts +2 -2
package/esm/form/useForm.js
CHANGED
@@ -3,6 +3,8 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
3
3
|
/* eslint-disable no-console */
|
4
4
|
import { useRef } from 'react';
|
5
5
|
import { Promise } from 'es6-promise';
|
6
|
+
import { ValueChangeType } from './type';
|
7
|
+
import { deepClone } from './utils';
|
6
8
|
|
7
9
|
var defaultFunc = function defaultFunc() {};
|
8
10
|
|
@@ -32,7 +34,11 @@ export var defaultFormDataMethods = {
|
|
32
34
|
return {
|
33
35
|
registerField: defaultFunc,
|
34
36
|
setInitialValues: defaultFunc,
|
35
|
-
setCallbacks: defaultFunc
|
37
|
+
setCallbacks: defaultFunc,
|
38
|
+
getInitialValue: defaultFunc,
|
39
|
+
setInitialValue: defaultFunc,
|
40
|
+
innerSetFieldsValue: defaultFunc,
|
41
|
+
innerSetFieldValue: defaultFunc
|
36
42
|
};
|
37
43
|
}
|
38
44
|
}; // 在field的静态的状态下设置
|
@@ -45,42 +51,82 @@ var FormData = function FormData() {
|
|
45
51
|
this._initialValues = {};
|
46
52
|
this._callbacks = {};
|
47
53
|
|
48
|
-
this.
|
54
|
+
this.commonSetFieldsValue = function (values, changeType) {
|
49
55
|
var oldValues = Object.keys(values).reduce(function (acc, key) {
|
50
56
|
var _extends2;
|
51
57
|
|
52
58
|
return _extends({}, acc, (_extends2 = {}, _extends2[key] = _this.getFieldValue(key), _extends2));
|
53
59
|
}, {});
|
54
60
|
_this._formData = _extends({}, _this._formData, values);
|
61
|
+
|
62
|
+
_this.notifyField(values, oldValues, changeType);
|
63
|
+
};
|
64
|
+
|
65
|
+
this.setFieldsValue = function (values) {
|
66
|
+
_this.commonSetFieldsValue(values);
|
67
|
+
|
55
68
|
var onValuesChange = _this._callbacks.onValuesChange;
|
56
|
-
onValuesChange
|
69
|
+
onValuesChange == null ? void 0 : onValuesChange(values, _this._formData);
|
70
|
+
return true;
|
71
|
+
};
|
57
72
|
|
58
|
-
|
73
|
+
this.innerSetFieldsValue = function (values, changeType) {
|
74
|
+
_this.commonSetFieldsValue(values, changeType);
|
59
75
|
|
76
|
+
var _this$_callbacks = _this._callbacks,
|
77
|
+
onValuesChange = _this$_callbacks.onValuesChange,
|
78
|
+
onChange = _this$_callbacks.onChange;
|
79
|
+
onValuesChange == null ? void 0 : onValuesChange(values, _this._formData);
|
80
|
+
onChange == null ? void 0 : onChange(values, _this._formData);
|
60
81
|
return true;
|
61
82
|
};
|
62
83
|
|
63
|
-
this.
|
64
|
-
var _oldValues, _extends3,
|
84
|
+
this.commonSetFieldValue = function (name, value, changeType) {
|
85
|
+
var _oldValues, _extends3, _this$notifyField;
|
65
86
|
|
66
87
|
var oldValues = (_oldValues = {}, _oldValues[name] = _this.getFieldValue(name), _oldValues);
|
67
88
|
_this._formData = _extends({}, _this._formData, (_extends3 = {}, _extends3[name] = value, _extends3));
|
89
|
+
|
90
|
+
_this.notifyField((_this$notifyField = {}, _this$notifyField[name] = value, _this$notifyField), oldValues, changeType);
|
91
|
+
};
|
92
|
+
|
93
|
+
this.setFieldValue = function (name, value) {
|
94
|
+
var _onValuesChange;
|
95
|
+
|
96
|
+
_this.commonSetFieldValue(name, value);
|
97
|
+
|
68
98
|
var onValuesChange = _this._callbacks.onValuesChange;
|
69
|
-
onValuesChange && onValuesChange((_onValuesChange = {}, _onValuesChange[name] = value, _onValuesChange), _this.
|
99
|
+
onValuesChange && onValuesChange((_onValuesChange = {}, _onValuesChange[name] = value, _onValuesChange), _this.getFieldsValue());
|
100
|
+
return true;
|
101
|
+
};
|
102
|
+
|
103
|
+
this.innerSetFieldValue = function (name, value, changeType) {
|
104
|
+
var _onValuesChange2, _onChange;
|
70
105
|
|
71
|
-
_this.
|
106
|
+
_this.commonSetFieldValue(name, value, changeType);
|
72
107
|
|
108
|
+
var _this$_callbacks2 = _this._callbacks,
|
109
|
+
onValuesChange = _this$_callbacks2.onValuesChange,
|
110
|
+
onChange = _this$_callbacks2.onChange;
|
111
|
+
onValuesChange && onValuesChange((_onValuesChange2 = {}, _onValuesChange2[name] = value, _onValuesChange2), _this._formData);
|
112
|
+
onChange && onChange((_onChange = {}, _onChange[name] = value, _onChange), _this._formData);
|
73
113
|
return true;
|
74
114
|
};
|
75
115
|
|
76
|
-
this.notifyField = function (values, oldValues) {
|
116
|
+
this.notifyField = function (values, oldValues, changeType) {
|
117
|
+
if (changeType === void 0) {
|
118
|
+
changeType = ValueChangeType.Update;
|
119
|
+
}
|
120
|
+
|
77
121
|
Object.keys(values).map(function (fieldName) {
|
78
122
|
var _this$_fieldsList;
|
79
123
|
|
80
124
|
var fieldObj = ((_this$_fieldsList = _this._fieldsList) == null ? void 0 : _this$_fieldsList[fieldName]) || null;
|
81
125
|
|
82
126
|
if (fieldObj) {
|
83
|
-
fieldObj.onValueChange(values[fieldName], oldValues[fieldName]
|
127
|
+
fieldObj.onValueChange(values[fieldName], oldValues[fieldName], {
|
128
|
+
changeType: changeType
|
129
|
+
});
|
84
130
|
}
|
85
131
|
});
|
86
132
|
};
|
@@ -92,13 +138,13 @@ var FormData = function FormData() {
|
|
92
138
|
});
|
93
139
|
}
|
94
140
|
|
95
|
-
return _this._formData;
|
141
|
+
return deepClone(_this._formData);
|
96
142
|
};
|
97
143
|
|
98
144
|
this.getFieldValue = function (name) {
|
99
145
|
var _this$_formData;
|
100
146
|
|
101
|
-
return (_this$_formData = _this._formData) == null ? void 0 : _this$_formData[name];
|
147
|
+
return deepClone((_this$_formData = _this._formData) == null ? void 0 : _this$_formData[name]);
|
102
148
|
};
|
103
149
|
|
104
150
|
this.getFieldError = function (name) {
|
@@ -161,13 +207,43 @@ var FormData = function FormData() {
|
|
161
207
|
};
|
162
208
|
|
163
209
|
this.setInitialValues = function (initVal) {
|
164
|
-
_this._initialValues =
|
210
|
+
_this._initialValues = deepClone(initVal || {});
|
165
211
|
|
166
212
|
_this.setFieldsValue(initVal);
|
167
213
|
};
|
168
214
|
|
215
|
+
this.setInitialValue = function (fieldName, value) {
|
216
|
+
if (!fieldName) {
|
217
|
+
return;
|
218
|
+
}
|
219
|
+
|
220
|
+
_this._initialValues[fieldName] = value;
|
221
|
+
|
222
|
+
_this.setFieldValue(fieldName, value);
|
223
|
+
};
|
224
|
+
|
225
|
+
this.getInitialValue = function (fieldName) {
|
226
|
+
return _this._initialValues[fieldName];
|
227
|
+
};
|
228
|
+
|
169
229
|
this.resetFields = function () {
|
170
|
-
|
230
|
+
var oldValues = _extends({}, _this._formData);
|
231
|
+
|
232
|
+
var initialValues = {};
|
233
|
+
Object.keys(_this._formData).forEach(function (fieldName) {
|
234
|
+
var _this$_fieldsList5;
|
235
|
+
|
236
|
+
var fieldObj = ((_this$_fieldsList5 = _this._fieldsList) == null ? void 0 : _this$_fieldsList5[fieldName]) || null;
|
237
|
+
|
238
|
+
if (fieldObj) {
|
239
|
+
initialValues[fieldName] = fieldObj.getInitialValue();
|
240
|
+
}
|
241
|
+
});
|
242
|
+
var onValuesChange = _this._callbacks.onValuesChange;
|
243
|
+
onValuesChange && onValuesChange(initialValues, _this._formData);
|
244
|
+
_this._formData = initialValues;
|
245
|
+
|
246
|
+
_this.notifyField(initialValues, oldValues, ValueChangeType.Reset);
|
171
247
|
};
|
172
248
|
|
173
249
|
this.validateFields = function () {
|
@@ -199,7 +275,7 @@ var FormData = function FormData() {
|
|
199
275
|
this.submit = function () {
|
200
276
|
_this.validateFields().then(function (result) {
|
201
277
|
var onSubmit = _this._callbacks.onSubmit;
|
202
|
-
onSubmit == null ? void 0 : onSubmit(_this.
|
278
|
+
onSubmit == null ? void 0 : onSubmit(_this.getFieldsValue(), result);
|
203
279
|
}).catch(function (e) {
|
204
280
|
var onSubmitFailed = _this._callbacks.onSubmitFailed;
|
205
281
|
|
@@ -207,7 +283,7 @@ var FormData = function FormData() {
|
|
207
283
|
return;
|
208
284
|
}
|
209
285
|
|
210
|
-
onSubmitFailed(_this.
|
286
|
+
onSubmitFailed(_this.getFieldsValue(), e);
|
211
287
|
});
|
212
288
|
};
|
213
289
|
|
@@ -236,7 +312,11 @@ var FormData = function FormData() {
|
|
236
312
|
return {
|
237
313
|
registerField: _this.registerField,
|
238
314
|
setInitialValues: _this.setInitialValues,
|
239
|
-
setCallbacks: _this.setCallbacks
|
315
|
+
setCallbacks: _this.setCallbacks,
|
316
|
+
getInitialValue: _this.getInitialValue,
|
317
|
+
setInitialValue: _this.setInitialValue,
|
318
|
+
innerSetFieldsValue: _this.innerSetFieldsValue,
|
319
|
+
innerSetFieldValue: _this.innerSetFieldValue
|
240
320
|
};
|
241
321
|
};
|
242
322
|
};
|
package/esm/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/esm/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 var isFieldRequired = function isFieldRequired(rules) {
|
2
5
|
if (rules === void 0) {
|
3
6
|
rules = [];
|
@@ -34,4 +37,31 @@ export var getErrorAndWarnings = function getErrorAndWarnings(result) {
|
|
34
37
|
errors: errors,
|
35
38
|
errorTypes: errorTypes
|
36
39
|
};
|
37
|
-
};
|
40
|
+
};
|
41
|
+
export var getDefaultValueForInterComponent = function getDefaultValueForInterComponent(componentType) {
|
42
|
+
switch (componentType) {
|
43
|
+
case FormInternalComponentType.Input:
|
44
|
+
case FormInternalComponentType.Textarea:
|
45
|
+
return undefined;
|
46
|
+
|
47
|
+
case FormInternalComponentType.CheckboxGroup:
|
48
|
+
return [];
|
49
|
+
|
50
|
+
case FormInternalComponentType.RadioGroup:
|
51
|
+
return null;
|
52
|
+
|
53
|
+
case FormInternalComponentType.Slider:
|
54
|
+
case FormInternalComponentType.Rate:
|
55
|
+
return 0;
|
56
|
+
|
57
|
+
default:
|
58
|
+
return undefined;
|
59
|
+
}
|
60
|
+
};
|
61
|
+
export function deepClone(value) {
|
62
|
+
return cloneDeepWith(value, function (val) {
|
63
|
+
if (!isObject(val) && !isArray(val)) {
|
64
|
+
return val;
|
65
|
+
}
|
66
|
+
});
|
67
|
+
}
|
package/esm/input/index.js
CHANGED
@@ -44,7 +44,7 @@ var Input = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
44
44
|
function renderInput(_ref) {
|
45
45
|
var prefixCls = _ref.prefixCls;
|
46
46
|
var prefix = prefixCls + "-input";
|
47
|
-
return renderWrapper(prefix, type, /*#__PURE__*/React.createElement("input", _extends({}, nativeProps, {
|
47
|
+
return renderWrapper(prefix, type + " single-line", /*#__PURE__*/React.createElement("input", _extends({}, nativeProps, {
|
48
48
|
id: id,
|
49
49
|
name: name,
|
50
50
|
maxLength: maxLength,
|
@@ -223,20 +223,38 @@ export var usePosition = function usePosition(props, popoverRef, childRef, wrapp
|
|
223
223
|
|
224
224
|
|
225
225
|
if (verticalAuto) {
|
226
|
-
var
|
227
|
-
var popoverBottom = childRect.top + (newConfig.top && newConfig.height ? newConfig.top + newConfig.height : 0); // 顶部安全距离不够,调整到底部
|
228
|
-
// @en The top safety distance is not enough, adjust to the bottom
|
229
|
-
|
230
|
-
if (directionState.indexOf('top') !== -1 && popoverTop < topOffset) {
|
226
|
+
var setToBottom = function setToBottom() {
|
231
227
|
newConfig.top = verticalOffset + childRect.height;
|
232
228
|
newConfig.bottom = null;
|
233
229
|
onAdjustDirection('bottom');
|
234
|
-
}
|
235
|
-
|
236
|
-
|
230
|
+
};
|
231
|
+
|
232
|
+
var setToTop = function setToTop() {
|
237
233
|
newConfig.top = null;
|
238
234
|
newConfig.bottom = verticalOffset + childRect.height;
|
239
235
|
onAdjustDirection('top');
|
236
|
+
}; // 判断上下空间是否都不足以展示气泡内容
|
237
|
+
// @en Determine whether there is insufficient space both above and below to display content
|
238
|
+
|
239
|
+
|
240
|
+
var isPopoverTooTall = window.innerHeight - topOffset - bottomOffset < 2 * (newConfig.height || 0) + 2 * verticalOffset + childRect.height;
|
241
|
+
|
242
|
+
if (isPopoverTooTall) {
|
243
|
+
var spaceAbove = childRect.top;
|
244
|
+
var spaceBelow = window.innerHeight - childRect.bottom;
|
245
|
+
spaceAbove > spaceBelow ? setToTop() : setToBottom();
|
246
|
+
} else {
|
247
|
+
var popoverTop = childRect.bottom - (newConfig.bottom && newConfig.height ? newConfig.bottom + newConfig.height : 0);
|
248
|
+
var popoverBottom = childRect.top + (newConfig.top && newConfig.height ? newConfig.top + newConfig.height : 0); // 顶部安全距离不够,调整到底部
|
249
|
+
// @en The top safety distance is not enough, adjust to the bottom
|
250
|
+
|
251
|
+
if (directionState.indexOf('top') !== -1 && popoverTop < topOffset) {
|
252
|
+
setToBottom();
|
253
|
+
} else if ( // 底部安全距离不够,调整到顶部
|
254
|
+
// @en The bottom safety distance is not enough, adjust to the top
|
255
|
+
directionState.indexOf('bottom') !== -1 && popoverBottom + bottomOffset > window.innerHeight) {
|
256
|
+
setToTop();
|
257
|
+
}
|
240
258
|
}
|
241
259
|
} // 挂载在全局的气泡需要计算相对屏幕的位置
|
242
260
|
// @en Bubble mounted in the global needs to calculate the position relative to the screen
|
package/esm/radio/group.js
CHANGED
@@ -71,7 +71,7 @@ export function componentGenerator(Comp) {
|
|
71
71
|
layout: layout,
|
72
72
|
disabled: disabled,
|
73
73
|
icons: icons,
|
74
|
-
value: groupValue === void 0 ? [] : [groupValue],
|
74
|
+
value: groupValue === void 0 || groupValue === null ? [] : [groupValue],
|
75
75
|
onChange: handleChange
|
76
76
|
}
|
77
77
|
}, children, !children && options && options.map(function (option) {
|
package/esm/radio/type.d.ts
CHANGED
@@ -8,10 +8,10 @@ export interface RadioGroupProps<T extends ValueType = ValueType, P extends Radi
|
|
8
8
|
*/
|
9
9
|
options?: P[];
|
10
10
|
/**
|
11
|
-
*
|
11
|
+
* 受控模式,选中的选项,传null表示取消选中
|
12
12
|
* @en Checked option, controlled mode
|
13
13
|
*/
|
14
|
-
value?: T;
|
14
|
+
value?: T | null;
|
15
15
|
/**
|
16
16
|
* 默认选中项
|
17
17
|
* @en Default checked value
|
package/esnext/carousel/index.js
CHANGED
@@ -507,11 +507,6 @@ const Carousel = forwardRef((props, ref) => {
|
|
507
507
|
return;
|
508
508
|
}
|
509
509
|
stopPropagation && e.stopPropagation();
|
510
|
-
if (bouncingRef.current) {
|
511
|
-
bouncingRef.current = false;
|
512
|
-
jumpTo(index, false);
|
513
|
-
return;
|
514
|
-
}
|
515
510
|
if (!touchStartedRef.current) {
|
516
511
|
return;
|
517
512
|
}
|
@@ -521,6 +516,13 @@ const Carousel = forwardRef((props, ref) => {
|
|
521
516
|
return;
|
522
517
|
}
|
523
518
|
touchMovedRef.current = false;
|
519
|
+
// bugfix: 回弹判断逻辑需在touchMovedRef标识重置逻辑之后,否则会在触发回弹后导致标识无法重置引起滑动判断问题
|
520
|
+
// @en bugfix: The logic for the bounce judgment needs to be after the touchMovedRef reset logic, otherwise it will cause the problem of slide judgment after the bounce is triggered.
|
521
|
+
if (bouncingRef.current) {
|
522
|
+
bouncingRef.current = false;
|
523
|
+
jumpTo(index, false);
|
524
|
+
return;
|
525
|
+
}
|
524
526
|
if (posAdjustingRef.current || touchStoppedRef.current) {
|
525
527
|
return;
|
526
528
|
}
|
@@ -49,6 +49,8 @@ const JsEllipsis = forwardRef((props, ref) => {
|
|
49
49
|
l = m;
|
50
50
|
}
|
51
51
|
}
|
52
|
+
// Remove the last character if it is orphaned high-surrogate characters (indicative of incomplete emoji).
|
53
|
+
currentText = currentText.replace(/[\uD800-\uDBFF]+$/, '');
|
52
54
|
// Remove the exclude char at the end of the content.
|
53
55
|
while (endExcludes && endExcludes.includes(currentText[currentText.length - 1])) {
|
54
56
|
currentText = currentText.slice(0, -1);
|
@@ -1,4 +1,35 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import {
|
1
|
+
import React, { PureComponent, ReactNode } from 'react';
|
2
|
+
import { Promise } from 'es6-promise';
|
3
|
+
import { FormItemContext } from './form-item-context';
|
4
|
+
import { IFieldError, FieldValue, IFormItemInnerProps, FormItemProps, ValidateStatus, FormItemRef, ValueChangeType, IFormItemContext } from './type';
|
5
|
+
interface IFormItemInnerState {
|
6
|
+
validateStatus: ValidateStatus;
|
7
|
+
errors?: ReactNode[];
|
8
|
+
_touched: boolean;
|
9
|
+
}
|
10
|
+
declare class FormItemInner extends PureComponent<IFormItemInnerProps, IFormItemInnerState> {
|
11
|
+
context: React.ContextType<typeof FormItemContext>;
|
12
|
+
destroyField: () => void;
|
13
|
+
private _errors;
|
14
|
+
private _touched;
|
15
|
+
constructor(props: IFormItemInnerProps, context: IFormItemContext);
|
16
|
+
componentDidMount(): void;
|
17
|
+
componentWillUnmount(): void;
|
18
|
+
onValueChange: (curValue: FieldValue, preValue: any, info?: {
|
19
|
+
changeType: ValueChangeType;
|
20
|
+
} | undefined) => void;
|
21
|
+
getInitialValue: () => any;
|
22
|
+
getFieldError: () => React.ReactNode[];
|
23
|
+
isFieldTouched: () => boolean;
|
24
|
+
getAllRuleValidateTriggers: () => string[];
|
25
|
+
validateField: (validateTrigger?: string | undefined) => Promise<IFieldError>;
|
26
|
+
setFieldData: (value: FieldValue) => void;
|
27
|
+
innerTriggerFunctionWithValueFirst: (value: any, ...args: any[]) => void;
|
28
|
+
innerOnInputFunction: (_: any, value: any, ...args: any[]) => void;
|
29
|
+
innerClearFunction: (...args: any[]) => void;
|
30
|
+
renderChildren(): React.FunctionComponentElement<any>;
|
31
|
+
render(): React.FunctionComponentElement<any>;
|
32
|
+
}
|
33
|
+
export { FormItemInner };
|
3
34
|
declare const _default: React.ForwardRefExoticComponent<FormItemProps & React.RefAttributes<FormItemRef>>;
|
4
35
|
export default _default;
|
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 || {});
|