@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
@@ -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
@@ -2,7 +2,7 @@ import { IRules } from '@arco-design/mobile-utils';
|
|
2
2
|
import { 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",
|
@@ -52,6 +52,11 @@ export interface FormProps {
|
|
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
|
/**
|
@@ -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
|
+
}
|
package/esnext/input/index.js
CHANGED
@@ -12,7 +12,7 @@ const Input = forwardRef((props, ref) => {
|
|
12
12
|
}));
|
13
13
|
function renderInput({ prefixCls }) {
|
14
14
|
const prefix = `${prefixCls}-input`;
|
15
|
-
return renderWrapper(prefix, type
|
15
|
+
return renderWrapper(prefix, `${type} single-line`, React.createElement("input", Object.assign({}, nativeProps, { id: id, name: name, maxLength: maxLength, placeholder: placeholder, readOnly: readOnly, onFocus: handleFocus, onBlur: handleBlur, onKeyUp: onKeyUp, onKeyPress: onKeyPress, ref: inputRef, className: cls(prefix, inputClass), style: inputStyle, value: inputValue, type: type, disabled: disabled, pattern: pattern, onChange: handleChange, onInput: handleInput, onKeyDown: handleKeyDown, onClick: handleClick, "aria-disabled": disabled, "aria-label": ariaLabel })));
|
16
16
|
}
|
17
17
|
return React.createElement(ContextLayout, null, renderInput);
|
18
18
|
});
|
@@ -161,24 +161,44 @@ export const usePosition = (props, popoverRef, childRef, wrapperRef) => {
|
|
161
161
|
// 垂直方向安全距离调整
|
162
162
|
// @en Vertical safety distance adjustment
|
163
163
|
if (verticalAuto) {
|
164
|
-
const
|
165
|
-
(newConfig.bottom && newConfig.height ? newConfig.bottom + newConfig.height : 0);
|
166
|
-
const popoverBottom = childRect.top +
|
167
|
-
(newConfig.top && newConfig.height ? newConfig.top + newConfig.height : 0);
|
168
|
-
// 顶部安全距离不够,调整到底部
|
169
|
-
// @en The top safety distance is not enough, adjust to the bottom
|
170
|
-
if (directionState.indexOf('top') !== -1 && popoverTop < topOffset) {
|
164
|
+
const setToBottom = () => {
|
171
165
|
newConfig.top = verticalOffset + childRect.height;
|
172
166
|
newConfig.bottom = null;
|
173
167
|
onAdjustDirection('bottom');
|
174
|
-
}
|
175
|
-
|
176
|
-
popoverBottom + bottomOffset > window.innerHeight) {
|
177
|
-
// 底部安全距离不够,调整到顶部
|
178
|
-
// @en The bottom safety distance is not enough, adjust to the top
|
168
|
+
};
|
169
|
+
const setToTop = () => {
|
179
170
|
newConfig.top = null;
|
180
171
|
newConfig.bottom = verticalOffset + childRect.height;
|
181
172
|
onAdjustDirection('top');
|
173
|
+
};
|
174
|
+
// 判断上下空间是否都不足以展示气泡内容
|
175
|
+
// @en Determine whether there is insufficient space both above and below to display content
|
176
|
+
const isPopoverTooTall = window.innerHeight - topOffset - bottomOffset <
|
177
|
+
2 * (newConfig.height || 0) + 2 * verticalOffset + childRect.height;
|
178
|
+
if (isPopoverTooTall) {
|
179
|
+
const spaceAbove = childRect.top;
|
180
|
+
const spaceBelow = window.innerHeight - childRect.bottom;
|
181
|
+
spaceAbove > spaceBelow ? setToTop() : setToBottom();
|
182
|
+
}
|
183
|
+
else {
|
184
|
+
const popoverTop = childRect.bottom -
|
185
|
+
(newConfig.bottom && newConfig.height
|
186
|
+
? newConfig.bottom + newConfig.height
|
187
|
+
: 0);
|
188
|
+
const popoverBottom = childRect.top +
|
189
|
+
(newConfig.top && newConfig.height ? newConfig.top + newConfig.height : 0);
|
190
|
+
// 顶部安全距离不够,调整到底部
|
191
|
+
// @en The top safety distance is not enough, adjust to the bottom
|
192
|
+
if (directionState.indexOf('top') !== -1 && popoverTop < topOffset) {
|
193
|
+
setToBottom();
|
194
|
+
}
|
195
|
+
else if (
|
196
|
+
// 底部安全距离不够,调整到顶部
|
197
|
+
// @en The bottom safety distance is not enough, adjust to the top
|
198
|
+
directionState.indexOf('bottom') !== -1 &&
|
199
|
+
popoverBottom + bottomOffset > window.innerHeight) {
|
200
|
+
setToTop();
|
201
|
+
}
|
182
202
|
}
|
183
203
|
}
|
184
204
|
// 挂载在全局的气泡需要计算相对屏幕的位置
|
package/esnext/radio/group.js
CHANGED
@@ -39,7 +39,9 @@ export function componentGenerator(Comp) {
|
|
39
39
|
layout,
|
40
40
|
disabled,
|
41
41
|
icons,
|
42
|
-
value: groupValue === void 0
|
42
|
+
value: groupValue === void 0 || groupValue === null
|
43
|
+
? []
|
44
|
+
: [groupValue],
|
43
45
|
onChange: handleChange,
|
44
46
|
} },
|
45
47
|
children,
|
package/esnext/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/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arco-design/mobile-react",
|
3
|
-
"version": "2.36.
|
3
|
+
"version": "2.36.2",
|
4
4
|
"description": "",
|
5
5
|
"main": "cjs/index.js",
|
6
6
|
"module": "esm/index.js",
|
@@ -15,7 +15,7 @@
|
|
15
15
|
"author": "taoyiyue@bytedance.com",
|
16
16
|
"license": "ISC",
|
17
17
|
"dependencies": {
|
18
|
-
"@arco-design/mobile-utils": "2.21.
|
18
|
+
"@arco-design/mobile-utils": "2.21.2",
|
19
19
|
"@arco-design/transformable": "^1.0.0",
|
20
20
|
"@babel/runtime": "^7",
|
21
21
|
"lodash.throttle": "^4.1.1",
|
@@ -47,5 +47,5 @@
|
|
47
47
|
"publishConfig": {
|
48
48
|
"access": "public"
|
49
49
|
},
|
50
|
-
"gitHead": "
|
50
|
+
"gitHead": "55380e688a52344b58e7bdc28bd3999b759386ba"
|
51
51
|
}
|
package/umd/carousel/index.js
CHANGED
@@ -704,12 +704,6 @@
|
|
704
704
|
|
705
705
|
stopPropagation && e.stopPropagation();
|
706
706
|
|
707
|
-
if (bouncingRef.current) {
|
708
|
-
bouncingRef.current = false;
|
709
|
-
jumpTo(index, false);
|
710
|
-
return;
|
711
|
-
}
|
712
|
-
|
713
707
|
if (!touchStartedRef.current) {
|
714
708
|
return;
|
715
709
|
}
|
@@ -721,7 +715,14 @@
|
|
721
715
|
return;
|
722
716
|
}
|
723
717
|
|
724
|
-
touchMovedRef.current = false;
|
718
|
+
touchMovedRef.current = false; // bugfix: 回弹判断逻辑需在touchMovedRef标识重置逻辑之后,否则会在触发回弹后导致标识无法重置引起滑动判断问题
|
719
|
+
// @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.
|
720
|
+
|
721
|
+
if (bouncingRef.current) {
|
722
|
+
bouncingRef.current = false;
|
723
|
+
jumpTo(index, false);
|
724
|
+
return;
|
725
|
+
}
|
725
726
|
|
726
727
|
if (posAdjustingRef.current || touchStoppedRef.current) {
|
727
728
|
return;
|
@@ -90,9 +90,11 @@
|
|
90
90
|
currentText += temp;
|
91
91
|
l = m;
|
92
92
|
}
|
93
|
-
} // Remove the
|
93
|
+
} // Remove the last character if it is orphaned high-surrogate characters (indicative of incomplete emoji).
|
94
94
|
|
95
95
|
|
96
|
+
currentText = currentText.replace(/[\uD800-\uDBFF]+$/, ''); // Remove the exclude char at the end of the content.
|
97
|
+
|
96
98
|
while (endExcludes && endExcludes.includes(currentText[currentText.length - 1])) {
|
97
99
|
currentText = currentText.slice(0, -1);
|
98
100
|
} // Callback after reflow.
|
package/umd/form/form-item.d.ts
CHANGED
@@ -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;
|