@mpxjs/webpack-plugin 2.10.3 → 2.10.4-beta.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/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 +13 -13
- 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 +11 -13
- 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/LICENSE +0 -433
- /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,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;
|
|
@@ -1,147 +1,87 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState } 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
|
+
const styles = StyleSheet.create({
|
|
6
|
+
pickerContainer: {
|
|
7
|
+
height: 240,
|
|
8
|
+
paddingHorizontal: 10,
|
|
9
|
+
borderTopLeftRadius: 10,
|
|
10
|
+
borderTopRightRadius: 10
|
|
11
|
+
},
|
|
12
|
+
pickerIndicator: {
|
|
13
|
+
height: 45
|
|
14
|
+
},
|
|
15
|
+
pickerItem: {
|
|
16
|
+
fontSize: 18,
|
|
17
|
+
lineHeight: 45,
|
|
18
|
+
textAlign: 'center'
|
|
8
19
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return convertToObj(item, rangeKey);
|
|
23
|
-
});
|
|
24
|
-
tmp.forEach(item => {
|
|
25
|
-
item.children = nextColData;
|
|
26
|
-
});
|
|
27
|
-
tmp = nextColData;
|
|
28
|
-
}
|
|
29
|
-
return result;
|
|
30
|
-
}
|
|
31
|
-
function getIndexByValues(range = [], value = []) {
|
|
32
|
-
let tmp = range;
|
|
33
|
-
return value.map(v => {
|
|
34
|
-
for (let i = 0; i < tmp.length; i++) {
|
|
35
|
-
if (tmp[i].value === v) {
|
|
36
|
-
tmp = tmp[i].children || [];
|
|
37
|
-
return i;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return 0;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
// [1,1,2] 寻找出[]
|
|
44
|
-
function getInnerValueByIndex(range = [], value = []) {
|
|
45
|
-
let tmp = range;
|
|
46
|
-
return value.map(v => {
|
|
47
|
-
const current = tmp[v].value;
|
|
48
|
-
tmp = tmp[v].children;
|
|
49
|
-
return current;
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
// column = 1 value = ['无脊柱动物', '扁性动物', '吸血虫'] 根据column 和value 获取到当前列变动选择的值所在当前列的索引
|
|
53
|
-
function getColumnIndexByValue(range = [], column, value = []) {
|
|
54
|
-
let curRange = range;
|
|
55
|
-
let changeIndex = 0;
|
|
56
|
-
let tmpRange = [];
|
|
57
|
-
value.map((item, index) => {
|
|
58
|
-
if (column === index) {
|
|
59
|
-
curRange.map((ritem, rindex) => {
|
|
60
|
-
if (ritem.value === item) {
|
|
61
|
-
changeIndex = rindex;
|
|
62
|
-
}
|
|
63
|
-
return ritem;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
curRange.map((citem, cindex) => {
|
|
68
|
-
if (citem.value === item) {
|
|
69
|
-
tmpRange = citem.children;
|
|
70
|
-
}
|
|
71
|
-
return citem;
|
|
72
|
-
});
|
|
73
|
-
curRange = tmpRange;
|
|
74
|
-
}
|
|
75
|
-
return item;
|
|
76
|
-
});
|
|
77
|
-
return changeIndex;
|
|
78
|
-
}
|
|
79
|
-
const _MultiSelectorPicker = forwardRef((props, ref) => {
|
|
80
|
-
const { range, value, disabled, bindchange, bindcancel, children, bindcolumnchange, style } = props;
|
|
81
|
-
const formatRange = formatRangeFun(range, props['range-key']);
|
|
82
|
-
const initValue = getInnerValueByIndex(formatRange, value);
|
|
83
|
-
// 选中的索引值
|
|
84
|
-
const [selected, setSelected] = useState(initValue);
|
|
85
|
-
// range数据源
|
|
86
|
-
const [data, setData] = useState(formatRange || []);
|
|
87
|
-
// 存储layout布局信息
|
|
88
|
-
const layoutRef = useRef({});
|
|
89
|
-
const viewRef = useRef(null);
|
|
20
|
+
});
|
|
21
|
+
const formatRangeFun = (range, rangeKey = '') => rangeKey ? range.map((item) => item[rangeKey]) : range;
|
|
22
|
+
const formatValueFn = (value) => {
|
|
23
|
+
return Array.isArray(value) ? value : [value];
|
|
24
|
+
};
|
|
25
|
+
const hasDiff = (a, b) => {
|
|
26
|
+
return a.length !== b.length || a.some((item, index) => item !== b[index]);
|
|
27
|
+
};
|
|
28
|
+
const PickerMultiSelector = forwardRef((props, ref) => {
|
|
29
|
+
const { value = [], range = [], bindchange, bindcolumnchange } = props;
|
|
30
|
+
const _value = formatValueFn(value);
|
|
31
|
+
const [formatValue, setFormatValue] = useState(_value);
|
|
32
|
+
const [formatRange, setFormatRange] = useState(formatRangeFun(range, props['range-key']));
|
|
90
33
|
const nodeRef = useRef(null);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (range) {
|
|
96
|
-
const newFormatRange = formatRangeFun(range, props['range-key']);
|
|
97
|
-
setData(newFormatRange);
|
|
34
|
+
const updateValue = useCallback((value = []) => {
|
|
35
|
+
let newValue = formatValueFn(value);
|
|
36
|
+
if (newValue.length === 0) {
|
|
37
|
+
newValue = formatValue.map(() => 0);
|
|
98
38
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
value: strIndex
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
};
|
|
111
|
-
const onPickerChange = (value, column) => {
|
|
112
|
-
// onPickerChange--- ["无脊柱动物", "节肢动物", "吸血虫"] 1 拿着column
|
|
113
|
-
const changeIndex = getColumnIndexByValue(data, column, value);
|
|
114
|
-
bindcolumnchange && bindcolumnchange(changeIndex, column);
|
|
39
|
+
checkColumnChange(newValue, formatValue);
|
|
40
|
+
if (hasDiff(newValue, formatValue)) {
|
|
41
|
+
setFormatValue(newValue);
|
|
42
|
+
}
|
|
43
|
+
}, [formatValue]);
|
|
44
|
+
const updateRange = (newRange) => {
|
|
45
|
+
const range = formatRangeFun(newRange.slice(), props['range-key']);
|
|
46
|
+
setFormatRange(range);
|
|
115
47
|
};
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
48
|
+
const _props = useRef(props);
|
|
49
|
+
_props.current = props;
|
|
50
|
+
useImperativeHandle(ref, () => ({
|
|
51
|
+
updateValue,
|
|
52
|
+
updateRange,
|
|
53
|
+
getNodeInstance: () => ({
|
|
54
|
+
props: _props,
|
|
55
|
+
nodeRef,
|
|
56
|
+
instance: {
|
|
57
|
+
style: {}
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}));
|
|
61
|
+
const onChange = (e) => {
|
|
62
|
+
const { value } = e.detail;
|
|
63
|
+
checkColumnChange(value, formatValue);
|
|
64
|
+
bindchange?.({ detail: { value: value } });
|
|
65
|
+
if (hasDiff(value, formatValue)) {
|
|
66
|
+
setFormatValue(value.slice());
|
|
67
|
+
}
|
|
121
68
|
};
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
defaultValue: initValue,
|
|
128
|
-
disabled,
|
|
129
|
-
itemHeight: 40,
|
|
130
|
-
onChange,
|
|
131
|
-
onDismiss: bindcancel && bindcancel,
|
|
132
|
-
onPickerChange: onPickerChange
|
|
69
|
+
const checkColumnChange = (value, formatValue) => {
|
|
70
|
+
const index = value.findIndex((v, i) => v !== formatValue[i]);
|
|
71
|
+
if (index !== -1) {
|
|
72
|
+
bindcolumnchange?.(index, value[index]);
|
|
73
|
+
}
|
|
133
74
|
};
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
75
|
+
const renderColumn = (columnData, index) => {
|
|
76
|
+
return (
|
|
77
|
+
// @ts-expect-error ignore
|
|
78
|
+
<MpxPickerViewColumn key={index}>
|
|
79
|
+
{columnData.map((item, index) => (<Text key={index} style={styles.pickerItem}>{item}</Text>))}
|
|
80
|
+
</MpxPickerViewColumn>);
|
|
137
81
|
};
|
|
138
|
-
return (<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
{children}
|
|
142
|
-
</View>
|
|
143
|
-
</TouchableWithoutFeedback>
|
|
144
|
-
</Picker>);
|
|
82
|
+
return (<MpxPickerView style={styles.pickerContainer} indicator-style={styles.pickerIndicator} value={formatValue} bindchange={onChange}>
|
|
83
|
+
{formatRange.map((item, index) => (renderColumn(item, index)))}
|
|
84
|
+
</MpxPickerView>);
|
|
145
85
|
});
|
|
146
|
-
|
|
147
|
-
export default
|
|
86
|
+
PickerMultiSelector.displayName = 'MpxPickerMultiSelector';
|
|
87
|
+
export default PickerMultiSelector;
|