@mpxjs/webpack-plugin 2.10.3 → 2.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/config.js +2 -1
- package/lib/index.js +1 -1
- package/lib/platform/json/wx/index.js +6 -3
- package/lib/platform/style/wx/index.js +23 -12
- package/lib/platform/template/wx/component-config/button.js +19 -2
- package/lib/platform/template/wx/component-config/canvas.js +4 -0
- package/lib/platform/template/wx/component-config/checkbox-group.js +4 -0
- package/lib/platform/template/wx/component-config/checkbox.js +4 -0
- package/lib/platform/template/wx/component-config/cover-image.js +7 -1
- package/lib/platform/template/wx/component-config/cover-view.js +4 -0
- package/lib/platform/template/wx/component-config/fix-component-name.js +3 -2
- package/lib/platform/template/wx/component-config/form.js +7 -1
- package/lib/platform/template/wx/component-config/icon.js +4 -0
- package/lib/platform/template/wx/component-config/image.js +7 -1
- package/lib/platform/template/wx/component-config/input.js +18 -3
- package/lib/platform/template/wx/component-config/label.js +4 -0
- package/lib/platform/template/wx/component-config/movable-area.js +7 -1
- package/lib/platform/template/wx/component-config/movable-view.js +12 -3
- package/lib/platform/template/wx/component-config/navigator.js +4 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +4 -0
- package/lib/platform/template/wx/component-config/picker-view.js +7 -1
- package/lib/platform/template/wx/component-config/picker.js +7 -1
- package/lib/platform/template/wx/component-config/radio-group.js +4 -0
- package/lib/platform/template/wx/component-config/radio.js +4 -0
- package/lib/platform/template/wx/component-config/rich-text.js +4 -0
- package/lib/platform/template/wx/component-config/root-portal.js +4 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +10 -2
- package/lib/platform/template/wx/component-config/swiper-item.js +7 -1
- package/lib/platform/template/wx/component-config/swiper.js +12 -3
- package/lib/platform/template/wx/component-config/switch.js +4 -0
- package/lib/platform/template/wx/component-config/text.js +24 -3
- package/lib/platform/template/wx/component-config/textarea.js +17 -2
- package/lib/platform/template/wx/component-config/unsupported.js +7 -0
- package/lib/platform/template/wx/component-config/video.js +10 -2
- package/lib/platform/template/wx/component-config/view.js +11 -1
- package/lib/platform/template/wx/component-config/web-view.js +4 -0
- package/lib/platform/template/wx/index.js +42 -75
- package/lib/react/processScript.js +1 -18
- package/lib/runtime/components/react/dist/event.config.js +1 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +18 -7
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +3 -6
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
- package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +178 -96
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
- package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +3 -3
- package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +64 -16
- package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +8 -5
- package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
- package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
- package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +192 -25
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +8 -7
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
- package/lib/runtime/components/react/dist/mpx-video.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +7 -4
- package/lib/runtime/components/react/dist/utils.jsx +2 -1
- package/lib/runtime/components/react/event.config.ts +2 -0
- package/lib/runtime/components/react/getInnerListeners.ts +28 -25
- package/lib/runtime/components/react/mpx-canvas/index.tsx +2 -2
- package/lib/runtime/components/react/mpx-inline-text.tsx +18 -0
- package/lib/runtime/components/react/mpx-input.tsx +2 -6
- package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker/date.tsx +226 -69
- package/lib/runtime/components/react/mpx-picker/dateData.ts +22 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +239 -118
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +96 -139
- package/lib/runtime/components/react/mpx-picker/region.tsx +217 -89
- package/lib/runtime/components/react/mpx-picker/selector.tsx +75 -80
- package/lib/runtime/components/react/mpx-picker/time.tsx +119 -236
- package/lib/runtime/components/react/mpx-picker/type.ts +85 -71
- package/lib/runtime/components/react/{mpx-picker-view.tsx → mpx-picker-view/index.tsx} +7 -7
- package/lib/runtime/components/react/{mpx-picker-view-column.tsx → mpx-picker-view-column/index.tsx} +70 -19
- package/lib/runtime/components/react/{mpx-picker-view-column-item.tsx → mpx-picker-view-column/pickerViewColumnItem.tsx} +8 -5
- package/lib/runtime/components/react/{pickerFaces.ts → mpx-picker-view-column/pickerViewFaces.ts} +7 -0
- package/lib/runtime/components/react/mpx-popup/index.tsx +86 -0
- package/lib/runtime/components/react/mpx-popup/popupBase.tsx +130 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +249 -43
- package/lib/runtime/components/react/mpx-simple-text.tsx +10 -8
- package/lib/runtime/components/react/mpx-simple-view.tsx +11 -16
- package/lib/runtime/components/react/mpx-video.tsx +2 -2
- package/lib/runtime/components/react/mpx-web-view.tsx +7 -4
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +5 -1
- package/lib/runtime/components/react/types/global.d.ts +1 -1
- package/lib/runtime/components/react/utils.tsx +3 -2
- package/lib/runtime/components/web/mini-video-controls.min.js +1 -1
- package/lib/runtime/components/web/mpx-input.vue +1 -1
- package/lib/runtime/stringify.wxs +2 -2
- package/lib/template-compiler/compiler.js +8 -8
- package/lib/utils/env.js +1 -1
- package/package.json +4 -5
- /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
- /package/lib/runtime/components/react/{pickerVIewContext.ts → mpx-picker-view/pickerVIewContext.ts} +0 -0
- /package/lib/runtime/components/react/{pickerViewIndicator.tsx → mpx-picker-view-column/pickerViewIndicator.tsx} +0 -0
- /package/lib/runtime/components/react/{pickerViewMask.tsx → mpx-picker-view-column/pickerViewMask.tsx} +0 -0
|
@@ -1,74 +1,200 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import React, { forwardRef, useCallback, useMemo, useRef, useState, useEffect, useImperativeHandle } from 'react';
|
|
2
|
+
import { StyleSheet, Text } from 'react-native';
|
|
3
|
+
import MpxPickerView from '../mpx-picker-view';
|
|
4
|
+
import MpxPickerViewColumn from '../mpx-picker-view-column';
|
|
5
|
+
import { useUpdateEffect } from '../utils';
|
|
6
|
+
import { years, months, daysInMonth, wrapDate, daysInMonthLength, START_YEAR, END_YEAR } from './dateData';
|
|
7
|
+
const START_DATE = `${START_YEAR}-01-01`;
|
|
8
|
+
const END_DATE = `${END_YEAR}-12-31`;
|
|
9
|
+
const START_DATE_ARR = [START_YEAR, 1, 1];
|
|
10
|
+
const END_DATE_ARR = [END_YEAR, 12, 31];
|
|
11
|
+
const styles = StyleSheet.create({
|
|
12
|
+
pickerContainer: {
|
|
13
|
+
height: 240,
|
|
14
|
+
paddingHorizontal: 10,
|
|
15
|
+
borderTopLeftRadius: 10,
|
|
16
|
+
borderTopRightRadius: 10
|
|
17
|
+
},
|
|
18
|
+
pickerIndicator: {
|
|
19
|
+
height: 45
|
|
20
|
+
},
|
|
21
|
+
pickerItem: {
|
|
22
|
+
fontSize: 16,
|
|
23
|
+
lineHeight: 45,
|
|
24
|
+
textAlign: 'center'
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const getColumnLength = (fields = 'day') => {
|
|
28
|
+
return fields === 'year' ? 1 : fields === 'month' ? 2 : 3;
|
|
29
|
+
};
|
|
30
|
+
const compareDateStr = (date1, date2) => {
|
|
31
|
+
const [y1 = START_YEAR, m1 = 0, d1 = 0] = typeof date1 === 'string' ? date1.split('-').map(Number) : date1;
|
|
32
|
+
const [y2 = START_YEAR, m2 = 0, d2 = 0] = typeof date2 === 'string' ? date2.split('-').map(Number) : date2;
|
|
33
|
+
const num1 = y1 * 10000 + m1 * 100 + d1;
|
|
34
|
+
const num2 = y2 * 10000 + m2 * 100 + d2;
|
|
35
|
+
if (num1 === num2) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
return num1 > num2 ? 1 : -1;
|
|
39
|
+
};
|
|
40
|
+
const getDateArr = (date) => {
|
|
41
|
+
const [y, m, d] = typeof date === 'string' ? date.split('-').map(Number) : date;
|
|
42
|
+
return [y || 0, m || 0, d || 0];
|
|
43
|
+
};
|
|
44
|
+
const calibrateDate = (date, start, end) => {
|
|
45
|
+
let startArr = getDateArr(start);
|
|
46
|
+
let endArr = getDateArr(end);
|
|
47
|
+
let dateArr = getDateArr(date);
|
|
48
|
+
if (compareDateStr(startArr, endArr) > 0) {
|
|
49
|
+
startArr = START_DATE_ARR;
|
|
50
|
+
}
|
|
51
|
+
if (compareDateStr(endArr, startArr) < 0) {
|
|
52
|
+
endArr = END_DATE_ARR;
|
|
53
|
+
}
|
|
54
|
+
if (compareDateStr(start, end) > 0) {
|
|
55
|
+
startArr = START_DATE_ARR;
|
|
56
|
+
endArr = END_DATE_ARR;
|
|
57
|
+
}
|
|
58
|
+
if (compareDateStr(dateArr, endArr) > 0) {
|
|
59
|
+
dateArr = endArr;
|
|
60
|
+
}
|
|
61
|
+
if (compareDateStr(dateArr, startArr) < 0) {
|
|
62
|
+
dateArr = startArr;
|
|
63
|
+
}
|
|
64
|
+
return dateArr;
|
|
65
|
+
};
|
|
66
|
+
const initDateStr2Arr = (dateStr, start, end) => {
|
|
67
|
+
if (!dateStr) {
|
|
68
|
+
const today = new Date();
|
|
69
|
+
const todayYear = today.getFullYear();
|
|
70
|
+
const todayMonth = today.getMonth() + 1;
|
|
71
|
+
const todayDay = today.getDate();
|
|
72
|
+
dateStr = [todayYear, todayMonth, todayDay];
|
|
73
|
+
}
|
|
74
|
+
const [y, m, d] = getDateArr(dateStr);
|
|
75
|
+
const year = Math.min(Math.max(START_YEAR, y), END_YEAR);
|
|
76
|
+
const month = Math.min(Math.max(1, m), 12);
|
|
77
|
+
const day = Math.min(Math.max(1, d), daysInMonthLength(year, month));
|
|
78
|
+
const res = [year, month, day];
|
|
79
|
+
return calibrateDate(res, start, end);
|
|
80
|
+
};
|
|
81
|
+
const valueStr2Obj = (_value = '', // eg: 2025-2-12
|
|
82
|
+
limit, start, end) => {
|
|
83
|
+
const [y, m, d] = initDateStr2Arr(_value, start, end);
|
|
84
|
+
const ans = {
|
|
85
|
+
indexArr: [y - START_YEAR],
|
|
86
|
+
rangeArr: [years]
|
|
87
|
+
};
|
|
88
|
+
if (limit === 2) {
|
|
89
|
+
ans.indexArr.push(m - 1);
|
|
90
|
+
ans.rangeArr.push(months);
|
|
91
|
+
}
|
|
92
|
+
else if (limit === 3) {
|
|
93
|
+
const days = daysInMonth(y, m);
|
|
94
|
+
ans.indexArr.push(m - 1, d - 1);
|
|
95
|
+
ans.rangeArr.push(months, days);
|
|
96
|
+
}
|
|
97
|
+
return ans;
|
|
98
|
+
};
|
|
99
|
+
const valueChanged2Obj = (currentObj, value, limit = 3) => {
|
|
100
|
+
const currentValue = currentObj.indexArr;
|
|
101
|
+
const rangeArr = currentObj.rangeArr;
|
|
102
|
+
if (limit === 3 && (currentValue[0] !== value[0] || currentValue[1] !== value[1])) {
|
|
103
|
+
const days = daysInMonth(value[0], value[1] + 1);
|
|
104
|
+
rangeArr[2] = days;
|
|
105
|
+
const maxIndex = days.length - 1;
|
|
106
|
+
if (value[2] > maxIndex) {
|
|
107
|
+
value[2] = maxIndex;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
indexArr: value,
|
|
112
|
+
rangeArr
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const valueChanged2Obj2 = (value, limit = 3, start, end) => {
|
|
116
|
+
const y = value[0] + START_YEAR;
|
|
117
|
+
const m = value[1] + 1;
|
|
118
|
+
const d = value[2] + 1;
|
|
119
|
+
return valueStr2Obj([y, m, d], limit, start, end);
|
|
120
|
+
};
|
|
121
|
+
const valueNum2String = (value) => {
|
|
122
|
+
return value.map((item, index) => {
|
|
123
|
+
if (index === 0) {
|
|
124
|
+
return item + START_YEAR;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
return wrapDate()(item + 1);
|
|
128
|
+
}
|
|
129
|
+
}).join('-');
|
|
130
|
+
};
|
|
131
|
+
const hasDiff = (currentValue, value, limit = 3) => {
|
|
132
|
+
for (let i = 0; i < limit; i++) {
|
|
133
|
+
if (currentValue[i] !== value[i]) {
|
|
134
|
+
return true;
|
|
21
135
|
}
|
|
22
136
|
}
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
const
|
|
26
|
-
const {
|
|
27
|
-
const [datevalue, setDateValue] = useState(value);
|
|
28
|
-
// 存储layout布局信息
|
|
29
|
-
const layoutRef = useRef({});
|
|
30
|
-
const viewRef = useRef(null);
|
|
137
|
+
return false;
|
|
138
|
+
};
|
|
139
|
+
const PickerDate = forwardRef((props, ref) => {
|
|
140
|
+
const { value = '', start = START_DATE, end = END_DATE, fields, bindchange } = props;
|
|
31
141
|
const nodeRef = useRef(null);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
142
|
+
const columnLength = useMemo(() => getColumnLength(fields), [fields]);
|
|
143
|
+
const [formatObj, setFormatObj] = useState(valueStr2Obj(value, columnLength, start, end));
|
|
144
|
+
const timerRef = useRef(null);
|
|
35
145
|
useEffect(() => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
146
|
+
return () => {
|
|
147
|
+
timerRef.current && clearTimeout(timerRef.current);
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
150
|
+
useUpdateEffect(() => {
|
|
151
|
+
const calibratedValue = valueStr2Obj(value, columnLength, start, end);
|
|
152
|
+
setFormatObj(calibratedValue);
|
|
153
|
+
}, [value, columnLength, start, end]);
|
|
154
|
+
const updateValue = useCallback((value = '') => {
|
|
155
|
+
const calibratedValue = valueStr2Obj(value, columnLength, start, end);
|
|
156
|
+
setFormatObj(calibratedValue);
|
|
157
|
+
}, [columnLength, start, end]);
|
|
158
|
+
const _props = useRef(props);
|
|
159
|
+
_props.current = props;
|
|
160
|
+
useImperativeHandle(ref, () => ({
|
|
161
|
+
updateValue,
|
|
162
|
+
getNodeInstance: () => ({
|
|
163
|
+
props: _props,
|
|
164
|
+
nodeRef,
|
|
165
|
+
instance: {
|
|
166
|
+
style: {}
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
}));
|
|
170
|
+
const onChange = useCallback((e) => {
|
|
171
|
+
const { value } = e.detail;
|
|
172
|
+
const currentValue = formatObj.indexArr;
|
|
173
|
+
const newObj = valueChanged2Obj(formatObj, value, columnLength);
|
|
174
|
+
if (hasDiff(currentValue, value, columnLength)) {
|
|
175
|
+
setFormatObj(newObj);
|
|
176
|
+
const newObj2 = valueChanged2Obj2(value, columnLength, start, end);
|
|
177
|
+
if (hasDiff(newObj.indexArr, newObj2.indexArr, columnLength)) {
|
|
178
|
+
timerRef.current && clearTimeout(timerRef.current);
|
|
179
|
+
timerRef.current = setTimeout(() => setFormatObj(newObj2));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
bindchange?.({ detail: { value: valueNum2String(newObj.indexArr) } });
|
|
183
|
+
}, [formatObj, columnLength, bindchange, start, end]);
|
|
184
|
+
const renderColumn = () => {
|
|
185
|
+
return formatObj.rangeArr?.map((item, index) => (
|
|
186
|
+
// @ts-expect-error ignore
|
|
187
|
+
<MpxPickerViewColumn key={index}>
|
|
188
|
+
{item.map((item, index) => {
|
|
189
|
+
return <Text key={index} style={styles.pickerItem}>
|
|
190
|
+
{item}
|
|
191
|
+
</Text>;
|
|
192
|
+
})}
|
|
193
|
+
</MpxPickerViewColumn>));
|
|
66
194
|
};
|
|
67
|
-
return (<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</TouchableWithoutFeedback>
|
|
71
|
-
</DatePicker>);
|
|
195
|
+
return (<MpxPickerView style={styles.pickerContainer} indicator-style={styles.pickerIndicator} value={formatObj.indexArr} bindchange={onChange}>
|
|
196
|
+
{renderColumn()}
|
|
197
|
+
</MpxPickerView>);
|
|
72
198
|
});
|
|
73
|
-
|
|
74
|
-
export default
|
|
199
|
+
PickerDate.displayName = 'MpxPickerDate';
|
|
200
|
+
export default PickerDate;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const wrapDate = (union = '') => (num) => String(num).padStart(2, '0') + union;
|
|
2
|
+
export const START_YEAR = 1900;
|
|
3
|
+
export const END_YEAR = 2099;
|
|
4
|
+
export const years = Array.from({ length: 200 }, (_, index) => index + START_YEAR + '年');
|
|
5
|
+
export const months = Array.from({ length: 12 }, (_, index) => index + 1).map(wrapDate('月'));
|
|
6
|
+
export const daysInMonthLength = (year, month) => {
|
|
7
|
+
return month === 2
|
|
8
|
+
? year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
|
|
9
|
+
? 29
|
|
10
|
+
: 28
|
|
11
|
+
: [4, 6, 9, 11].includes(month)
|
|
12
|
+
? 30
|
|
13
|
+
: 31;
|
|
14
|
+
};
|
|
15
|
+
export const daysInMonth = (year, month) => {
|
|
16
|
+
return Array.from({ length: daysInMonthLength(year, month) }, (_, index) => index + 1).map(wrapDate('日'));
|
|
17
|
+
};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import React, { forwardRef, useRef, useContext, useEffect } from 'react';
|
|
2
|
+
import { StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native';
|
|
3
3
|
import { warn } from '@mpxjs/utils';
|
|
4
|
+
import PickerSelector from './selector';
|
|
5
|
+
import PickerMultiSelector from './multiSelector';
|
|
6
|
+
import PickerTime from './time';
|
|
7
|
+
import PickerDate from './date';
|
|
8
|
+
import PickerRegion from './region';
|
|
9
|
+
import { FormContext, RouteContext } from '../context';
|
|
10
|
+
import useNodesRef from '../useNodesRef';
|
|
4
11
|
import useInnerProps, { getCustomEvent } from '../getInnerListeners';
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import TimeSelector from './time';
|
|
8
|
-
import DateSelector from './date';
|
|
9
|
-
import MultiSelector from './multiSelector';
|
|
10
|
-
import RegionSelector from './region';
|
|
11
|
-
import { FormContext } from '../context';
|
|
12
|
+
import { extendObject } from '../utils';
|
|
13
|
+
import { createPopupManager } from '../mpx-popup';
|
|
12
14
|
/**
|
|
13
15
|
* ✔ mode
|
|
14
16
|
* ✔ disabled
|
|
@@ -24,40 +26,118 @@ import { FormContext } from '../context';
|
|
|
24
26
|
* ✔ custom-item
|
|
25
27
|
* ✔ level 选择器层级 province,city,region,<sub-district不支持>
|
|
26
28
|
* ✔ level
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
+
* ✔ header-text
|
|
30
|
+
* ✔ bindcolumnchange
|
|
29
31
|
*/
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
+
const styles = StyleSheet.create({
|
|
33
|
+
header: {
|
|
34
|
+
height: 40,
|
|
35
|
+
alignItems: 'center',
|
|
36
|
+
justifyContent: 'center',
|
|
37
|
+
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
38
|
+
borderBottomColor: '#eeeeee'
|
|
39
|
+
},
|
|
40
|
+
headerText: {
|
|
41
|
+
color: '#333333',
|
|
42
|
+
fontSize: 18,
|
|
43
|
+
textAlign: 'center'
|
|
44
|
+
},
|
|
45
|
+
footer: {
|
|
46
|
+
gap: 20,
|
|
47
|
+
height: 50,
|
|
48
|
+
marginBottom: 20,
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
flexDirection: 'row',
|
|
51
|
+
justifyContent: 'center'
|
|
52
|
+
},
|
|
53
|
+
footerItem: {
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
justifyContent: 'center',
|
|
56
|
+
height: 40,
|
|
57
|
+
width: 110,
|
|
58
|
+
borderRadius: 5
|
|
59
|
+
},
|
|
60
|
+
cancelButton: {
|
|
61
|
+
backgroundColor: '#eeeeee'
|
|
62
|
+
},
|
|
63
|
+
confirmButton: {
|
|
64
|
+
backgroundColor: '#1AAD19'
|
|
65
|
+
},
|
|
66
|
+
cancelText: {
|
|
67
|
+
color: 'green',
|
|
68
|
+
fontSize: 18,
|
|
69
|
+
textAlign: 'center'
|
|
70
|
+
},
|
|
71
|
+
confirmText: {
|
|
72
|
+
color: '#FFFFFF',
|
|
73
|
+
fontSize: 18,
|
|
74
|
+
textAlign: 'center'
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const pickerModalMap = {
|
|
78
|
+
["selector" /* PickerMode.SELECTOR */]: PickerSelector,
|
|
79
|
+
["multiSelector" /* PickerMode.MULTI_SELECTOR */]: PickerMultiSelector,
|
|
80
|
+
["time" /* PickerMode.TIME */]: PickerTime,
|
|
81
|
+
["date" /* PickerMode.DATE */]: PickerDate,
|
|
82
|
+
["region" /* PickerMode.REGION */]: PickerRegion
|
|
83
|
+
};
|
|
84
|
+
const getDefaultValue = (mode) => {
|
|
85
|
+
switch (mode) {
|
|
86
|
+
case "selector" /* PickerMode.SELECTOR */:
|
|
87
|
+
case "multiSelector" /* PickerMode.MULTI_SELECTOR */:
|
|
88
|
+
case "region" /* PickerMode.REGION */:
|
|
89
|
+
return [];
|
|
90
|
+
case "time" /* PickerMode.TIME */:
|
|
91
|
+
case "date" /* PickerMode.DATE */:
|
|
92
|
+
default:
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const buttonTextMap = {
|
|
97
|
+
'zh-CN': {
|
|
98
|
+
cancel: '取消',
|
|
99
|
+
confirm: '确定'
|
|
100
|
+
},
|
|
101
|
+
'en-US': {
|
|
102
|
+
cancel: 'Cancel',
|
|
103
|
+
confirm: 'Confirm'
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const Picker = forwardRef((props, ref) => {
|
|
107
|
+
const { mode, value, range = null, children, disabled, bindcancel, bindchange, 'header-text': headerText = '' } = props;
|
|
108
|
+
const { pageId } = useContext(RouteContext) || {};
|
|
109
|
+
const buttonText = buttonTextMap[global.__mpx?.i18n?.locale || 'zh-CN'];
|
|
110
|
+
const pickerValue = useRef(value);
|
|
111
|
+
pickerValue.current = Array.isArray(value) ? value.slice() : value;
|
|
32
112
|
const innerLayout = useRef({});
|
|
33
113
|
const nodeRef = useRef(null);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
114
|
+
const pickerRef = useRef(null);
|
|
115
|
+
const { open, show, hide, remove } = useRef(createPopupManager()).current;
|
|
116
|
+
useNodesRef(props, ref, nodeRef);
|
|
37
117
|
const innerProps = useInnerProps(props, {
|
|
38
118
|
ref: nodeRef
|
|
39
119
|
}, [], { layoutRef: innerLayout });
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
120
|
+
const getInnerLayout = (layout) => {
|
|
121
|
+
innerLayout.current = layout.current;
|
|
122
|
+
};
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (range && pickerRef.current && mode === "multiSelector" /* PickerMode.MULTI_SELECTOR */) {
|
|
125
|
+
pickerRef.current.updateRange?.(range);
|
|
126
|
+
}
|
|
127
|
+
}, [JSON.stringify(range)]);
|
|
128
|
+
/** --- form 表单组件内部方法 --- */
|
|
129
|
+
const getValue = () => {
|
|
130
|
+
return pickerValue.current;
|
|
131
|
+
};
|
|
132
|
+
const resetValue = () => {
|
|
133
|
+
const defalutValue = getDefaultValue(mode); // 默认值
|
|
134
|
+
pickerRef.current.updateValue?.(defalutValue);
|
|
47
135
|
};
|
|
48
136
|
const formContext = useContext(FormContext);
|
|
49
137
|
let formValuesMap;
|
|
50
|
-
// 判断 context 是否存在,存在的话读取 context 中存的 formValuesMap
|
|
51
138
|
if (formContext) {
|
|
52
139
|
formValuesMap = formContext.formValuesMap;
|
|
53
140
|
}
|
|
54
|
-
const resetValue = () => {
|
|
55
|
-
const defalutValue = (defaultValues[mode] !== undefined ? defaultValues[mode] : value);
|
|
56
|
-
setPickerValue(defalutValue);
|
|
57
|
-
};
|
|
58
|
-
const getValue = () => {
|
|
59
|
-
return pickerValue;
|
|
60
|
-
};
|
|
61
141
|
if (formValuesMap) {
|
|
62
142
|
if (!props.name) {
|
|
63
143
|
warn('If a form component is used, the name attribute is required.');
|
|
@@ -66,76 +146,78 @@ const _Picker = forwardRef((props, ref) => {
|
|
|
66
146
|
formValuesMap.set(props.name, { getValue, resetValue });
|
|
67
147
|
}
|
|
68
148
|
}
|
|
69
|
-
|
|
70
|
-
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
return () => {
|
|
151
|
+
if (formValuesMap && props.name) {
|
|
152
|
+
formValuesMap.delete(props.name);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}, []);
|
|
156
|
+
/** --- form 表单组件内部方法 --- */
|
|
157
|
+
const onChange = (e) => {
|
|
158
|
+
const { value } = e.detail;
|
|
159
|
+
pickerValue.current = value;
|
|
160
|
+
};
|
|
161
|
+
const onColumnChange = (columnIndex, value) => {
|
|
162
|
+
if (mode !== "multiSelector" /* PickerMode.MULTI_SELECTOR */) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const eventData = getCustomEvent('columnchange', {}, { detail: { column: columnIndex, value }, layoutRef: innerLayout });
|
|
166
|
+
props.bindcolumnchange?.(eventData);
|
|
71
167
|
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
setPickerValue(event.detail.value);
|
|
168
|
+
const onCancel = () => {
|
|
169
|
+
bindcancel?.();
|
|
170
|
+
hide();
|
|
76
171
|
};
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
172
|
+
const onConfirm = () => {
|
|
173
|
+
const eventData = getCustomEvent('change', {}, { detail: { value: pickerValue.current }, layoutRef: innerLayout });
|
|
174
|
+
bindchange?.(eventData);
|
|
175
|
+
hide();
|
|
81
176
|
};
|
|
82
|
-
const
|
|
83
|
-
...innerProps,
|
|
177
|
+
const specificProps = extendObject(innerProps, {
|
|
84
178
|
mode,
|
|
85
179
|
children,
|
|
86
180
|
bindchange: onChange,
|
|
87
|
-
bindcolumnchange:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
};
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
value
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
...commonProps,
|
|
118
|
-
value: pickerValue,
|
|
119
|
-
level: props.level || 'sub-district'
|
|
181
|
+
bindcolumnchange: onColumnChange,
|
|
182
|
+
getInnerLayout,
|
|
183
|
+
getRange: () => range
|
|
184
|
+
});
|
|
185
|
+
const renderPickerContent = () => {
|
|
186
|
+
if (disabled) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const _mode = mode ?? "selector" /* PickerMode.SELECTOR */;
|
|
190
|
+
if (!(_mode in pickerModalMap)) {
|
|
191
|
+
return warn(`[Mpx runtime warn]: Unsupported <picker> mode: ${mode}`);
|
|
192
|
+
}
|
|
193
|
+
const _value = value;
|
|
194
|
+
const PickerModal = pickerModalMap[_mode];
|
|
195
|
+
const renderPickerModal = (<>
|
|
196
|
+
{headerText && (<View style={[styles.header]}>
|
|
197
|
+
<Text style={[styles.headerText]}>{headerText}</Text>
|
|
198
|
+
</View>)}
|
|
199
|
+
<PickerModal {...specificProps} value={_value} ref={pickerRef}></PickerModal>
|
|
200
|
+
<View style={[styles.footer]}>
|
|
201
|
+
<View onTouchEnd={onCancel} style={[styles.footerItem, styles.cancelButton]}>
|
|
202
|
+
<Text style={[styles.cancelText]}>{buttonText.cancel}</Text>
|
|
203
|
+
</View>
|
|
204
|
+
<View onTouchEnd={onConfirm} style={[styles.footerItem, styles.confirmButton]}>
|
|
205
|
+
<Text style={[styles.confirmText]}>{buttonText.confirm}</Text>
|
|
206
|
+
</View>
|
|
207
|
+
</View>
|
|
208
|
+
</>);
|
|
209
|
+
const contentHeight = headerText ? 350 : 310;
|
|
210
|
+
open(renderPickerModal, pageId, { contentHeight });
|
|
120
211
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
else if (mode === 'date') {
|
|
131
|
-
return <DateSelector {...dateProps}></DateSelector>;
|
|
132
|
-
}
|
|
133
|
-
else if (mode === 'region') {
|
|
134
|
-
return <RegionSelector {...regionProps}></RegionSelector>;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
return <View>只支持selector, multiSelector, time, date, region 这些类型</View>;
|
|
138
|
-
}
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
renderPickerContent();
|
|
214
|
+
return () => {
|
|
215
|
+
remove();
|
|
216
|
+
};
|
|
217
|
+
}, []);
|
|
218
|
+
return (<TouchableWithoutFeedback onPress={show}>
|
|
219
|
+
{children}
|
|
220
|
+
</TouchableWithoutFeedback>);
|
|
139
221
|
});
|
|
140
|
-
|
|
141
|
-
export default
|
|
222
|
+
Picker.displayName = 'MpxPicker';
|
|
223
|
+
export default Picker;
|