@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.
Files changed (104) hide show
  1. package/lib/config.js +2 -1
  2. package/lib/index.js +1 -1
  3. package/lib/platform/json/wx/index.js +6 -3
  4. package/lib/platform/style/wx/index.js +23 -12
  5. package/lib/platform/template/wx/component-config/button.js +19 -2
  6. package/lib/platform/template/wx/component-config/canvas.js +4 -0
  7. package/lib/platform/template/wx/component-config/checkbox-group.js +4 -0
  8. package/lib/platform/template/wx/component-config/checkbox.js +4 -0
  9. package/lib/platform/template/wx/component-config/cover-image.js +7 -1
  10. package/lib/platform/template/wx/component-config/cover-view.js +4 -0
  11. package/lib/platform/template/wx/component-config/fix-component-name.js +3 -2
  12. package/lib/platform/template/wx/component-config/form.js +7 -1
  13. package/lib/platform/template/wx/component-config/icon.js +4 -0
  14. package/lib/platform/template/wx/component-config/image.js +7 -1
  15. package/lib/platform/template/wx/component-config/input.js +18 -3
  16. package/lib/platform/template/wx/component-config/label.js +4 -0
  17. package/lib/platform/template/wx/component-config/movable-area.js +7 -1
  18. package/lib/platform/template/wx/component-config/movable-view.js +12 -3
  19. package/lib/platform/template/wx/component-config/navigator.js +4 -0
  20. package/lib/platform/template/wx/component-config/picker-view-column.js +4 -0
  21. package/lib/platform/template/wx/component-config/picker-view.js +7 -1
  22. package/lib/platform/template/wx/component-config/picker.js +7 -1
  23. package/lib/platform/template/wx/component-config/radio-group.js +4 -0
  24. package/lib/platform/template/wx/component-config/radio.js +4 -0
  25. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  26. package/lib/platform/template/wx/component-config/root-portal.js +4 -0
  27. package/lib/platform/template/wx/component-config/scroll-view.js +10 -2
  28. package/lib/platform/template/wx/component-config/swiper-item.js +7 -1
  29. package/lib/platform/template/wx/component-config/swiper.js +12 -3
  30. package/lib/platform/template/wx/component-config/switch.js +4 -0
  31. package/lib/platform/template/wx/component-config/text.js +24 -3
  32. package/lib/platform/template/wx/component-config/textarea.js +17 -2
  33. package/lib/platform/template/wx/component-config/unsupported.js +7 -0
  34. package/lib/platform/template/wx/component-config/video.js +10 -2
  35. package/lib/platform/template/wx/component-config/view.js +11 -1
  36. package/lib/platform/template/wx/component-config/web-view.js +4 -0
  37. package/lib/platform/template/wx/index.js +42 -75
  38. package/lib/react/processScript.js +1 -18
  39. package/lib/runtime/components/react/dist/event.config.js +1 -0
  40. package/lib/runtime/components/react/dist/getInnerListeners.js +18 -7
  41. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +1 -1
  42. package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
  43. package/lib/runtime/components/react/dist/mpx-input.jsx +13 -13
  44. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +2 -2
  45. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
  46. package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
  47. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +178 -96
  48. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
  49. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
  50. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
  51. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
  52. package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +3 -3
  53. package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +64 -16
  54. package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +8 -5
  55. package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
  56. package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
  57. package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
  58. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +192 -25
  59. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +8 -7
  60. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
  61. package/lib/runtime/components/react/dist/mpx-video.jsx +3 -3
  62. package/lib/runtime/components/react/dist/mpx-web-view.jsx +7 -4
  63. package/lib/runtime/components/react/dist/utils.jsx +2 -1
  64. package/lib/runtime/components/react/event.config.ts +2 -0
  65. package/lib/runtime/components/react/getInnerListeners.ts +28 -25
  66. package/lib/runtime/components/react/mpx-canvas/index.tsx +2 -2
  67. package/lib/runtime/components/react/mpx-inline-text.tsx +18 -0
  68. package/lib/runtime/components/react/mpx-input.tsx +11 -13
  69. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
  70. package/lib/runtime/components/react/mpx-picker/date.tsx +226 -69
  71. package/lib/runtime/components/react/mpx-picker/dateData.ts +22 -0
  72. package/lib/runtime/components/react/mpx-picker/index.tsx +239 -118
  73. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +96 -139
  74. package/lib/runtime/components/react/mpx-picker/region.tsx +217 -89
  75. package/lib/runtime/components/react/mpx-picker/selector.tsx +75 -80
  76. package/lib/runtime/components/react/mpx-picker/time.tsx +119 -236
  77. package/lib/runtime/components/react/mpx-picker/type.ts +85 -71
  78. package/lib/runtime/components/react/{mpx-picker-view.tsx → mpx-picker-view/index.tsx} +7 -7
  79. package/lib/runtime/components/react/{mpx-picker-view-column.tsx → mpx-picker-view-column/index.tsx} +70 -19
  80. package/lib/runtime/components/react/{mpx-picker-view-column-item.tsx → mpx-picker-view-column/pickerViewColumnItem.tsx} +8 -5
  81. package/lib/runtime/components/react/{pickerFaces.ts → mpx-picker-view-column/pickerViewFaces.ts} +7 -0
  82. package/lib/runtime/components/react/mpx-popup/index.tsx +86 -0
  83. package/lib/runtime/components/react/mpx-popup/popupBase.tsx +130 -0
  84. package/lib/runtime/components/react/mpx-scroll-view.tsx +249 -43
  85. package/lib/runtime/components/react/mpx-simple-text.tsx +10 -8
  86. package/lib/runtime/components/react/mpx-simple-view.tsx +11 -16
  87. package/lib/runtime/components/react/mpx-video.tsx +2 -2
  88. package/lib/runtime/components/react/mpx-web-view.tsx +7 -4
  89. package/lib/runtime/components/react/types/getInnerListeners.d.ts +5 -1
  90. package/lib/runtime/components/react/types/global.d.ts +1 -1
  91. package/lib/runtime/components/react/utils.tsx +3 -2
  92. package/lib/runtime/components/web/mini-video-controls.min.js +1 -1
  93. package/lib/runtime/components/web/mpx-input.vue +1 -1
  94. package/lib/runtime/stringify.wxs +2 -2
  95. package/lib/template-compiler/compiler.js +8 -8
  96. package/lib/utils/env.js +1 -1
  97. package/package.json +4 -5
  98. package/LICENSE +0 -433
  99. /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
  100. /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
  101. /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
  102. /package/lib/runtime/components/react/{pickerVIewContext.ts → mpx-picker-view/pickerVIewContext.ts} +0 -0
  103. /package/lib/runtime/components/react/{pickerViewIndicator.tsx → mpx-picker-view-column/pickerViewIndicator.tsx} +0 -0
  104. /package/lib/runtime/components/react/{pickerViewMask.tsx → mpx-picker-view-column/pickerViewMask.tsx} +0 -0
@@ -1,14 +1,16 @@
1
- import { View } from 'react-native';
2
- import React, { forwardRef, useRef, useContext, useState } from 'react';
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 useNodesRef from '../useNodesRef'; // 引入辅助函数
6
- import Selector from './selector';
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
- * header-text
28
- * bindcolumnchange
29
+ * header-text
30
+ * bindcolumnchange
29
31
  */
30
- const _Picker = forwardRef((props, ref) => {
31
- const { mode = 'selector', value, bindcancel, bindchange, children, bindcolumnchange, style } = props;
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
- useNodesRef(props, ref, nodeRef, {
35
- style
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 [pickerValue, setPickerValue] = useState(value);
41
- const defaultValues = {
42
- selector: 0,
43
- multiSelector: [0],
44
- time: props.start,
45
- date: props.start,
46
- region: undefined
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
- const getInnerLayout = (layout) => {
70
- innerLayout.current = layout.current;
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 onChange = (event) => {
73
- const eventData = getCustomEvent('change', {}, { detail: event.detail, layoutRef: innerLayout });
74
- bindchange && bindchange(eventData);
75
- setPickerValue(event.detail.value);
168
+ const onCancel = () => {
169
+ bindcancel?.();
170
+ hide();
76
171
  };
77
- const columnChange = (value, index) => {
78
- // type: "columnchange", detail: {column: 1, value: 2}
79
- const eventData = getCustomEvent('columnchange', {}, { detail: { column: index, value }, layoutRef: innerLayout });
80
- bindcolumnchange && bindcolumnchange(eventData);
172
+ const onConfirm = () => {
173
+ const eventData = getCustomEvent('change', {}, { detail: { value: pickerValue.current }, layoutRef: innerLayout });
174
+ bindchange?.(eventData);
175
+ hide();
81
176
  };
82
- const commonProps = {
83
- ...innerProps,
177
+ const specificProps = extendObject(innerProps, {
84
178
  mode,
85
179
  children,
86
180
  bindchange: onChange,
87
- bindcolumnchange: columnChange,
88
- bindcancel,
89
- getInnerLayout
90
- };
91
- const selectorProps = {
92
- ...commonProps,
93
- value: pickerValue,
94
- range: props.range,
95
- 'range-key': props['range-key']
96
- };
97
- const multiProps = {
98
- ...commonProps,
99
- value: pickerValue,
100
- range: props.range,
101
- 'range-key': props['range-key']
102
- };
103
- const timeProps = {
104
- ...commonProps,
105
- value: pickerValue,
106
- start: props.start,
107
- end: props.end
108
- };
109
- const dateProps = {
110
- ...commonProps,
111
- value: pickerValue,
112
- start: props.start,
113
- end: props.end,
114
- fileds: props.fields || 'day'
115
- };
116
- const regionProps = {
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
- if (mode === 'selector') {
122
- return <Selector {...selectorProps}></Selector>;
123
- }
124
- else if (mode === 'multiSelector') {
125
- return <MultiSelector {...multiProps}></MultiSelector>;
126
- }
127
- else if (mode === 'time') {
128
- return <TimeSelector {...timeProps}></TimeSelector>;
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
- _Picker.displayName = 'mpx-picker';
141
- export default _Picker;
222
+ Picker.displayName = 'MpxPicker';
223
+ export default Picker;
@@ -1,147 +1,87 @@
1
- import { View, TouchableWithoutFeedback } from 'react-native';
2
- import { Picker } from '@ant-design/react-native';
3
- import React, { forwardRef, useState, useRef, useEffect } from 'react';
4
- import useNodesRef from '../useNodesRef'; // 引入辅助函数
5
- function convertToObj(item, rangeKey = '') {
6
- if (typeof item === 'object') {
7
- return { value: item[rangeKey], label: item[rangeKey] };
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
- else {
10
- return { value: item, label: item };
11
- }
12
- }
13
- // eslint-disable-next-line default-param-last
14
- function formatRangeFun(range = [], rangeKey) {
15
- const result = (range[0] || []).map(item => {
16
- return convertToObj(item, rangeKey);
17
- });
18
- let tmp = result;
19
- for (let i = 1; i < range.length; i++) {
20
- const child = Array.isArray(range[i]) ? range[i] : [];
21
- const nextColData = child.map(item => {
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
- useNodesRef(props, ref, nodeRef, {
92
- style
93
- });
94
- useEffect(() => {
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
- const newValue = getInnerValueByIndex(formatRange, value);
100
- value && setSelected(newValue);
101
- }, [range, value]);
102
- const onChange = (value) => {
103
- // e.detail.value 都是索引multi
104
- const strIndex = getIndexByValues(data, value);
105
- bindchange && bindchange({
106
- detail: {
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 onElementLayout = () => {
117
- viewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
118
- layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
119
- props.getInnerLayout && props.getInnerLayout(layoutRef);
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 antPickerProps = {
123
- ref: nodeRef,
124
- data,
125
- value: selected,
126
- cols: range.length,
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 touchProps = {
135
- onLayout: onElementLayout,
136
- ref: viewRef
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 (<Picker {...antPickerProps}>
139
- <TouchableWithoutFeedback>
140
- <View {...touchProps}>
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
- _MultiSelectorPicker.displayName = 'mpx-picker-multiselector';
147
- export default _MultiSelectorPicker;
86
+ PickerMultiSelector.displayName = 'MpxPickerMultiSelector';
87
+ export default PickerMultiSelector;