@mpxjs/webpack-plugin 2.10.3-beta.4 → 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/LICENSE +433 -0
- package/lib/index.js +1 -1
- package/lib/platform/template/wx/component-config/input.js +1 -1
- package/lib/platform/template/wx/component-config/text.js +18 -3
- package/lib/platform/template/wx/component-config/view.js +0 -2
- package/lib/platform/template/wx/index.js +41 -93
- 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-swiper.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-video.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +4 -4
- package/lib/runtime/components/react/dist/utils.jsx +1 -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-swiper.tsx +2 -4
- package/lib/runtime/components/react/mpx-video.tsx +2 -2
- package/lib/runtime/components/react/mpx-web-view.tsx +4 -4
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +5 -1
- package/lib/runtime/components/react/utils.tsx +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 +7 -7
- 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,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
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'
|
|
4
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, FormFieldValue, RouteContext } from '../context'
|
|
10
|
+
import useNodesRef, { HandlerRef } from '../useNodesRef'
|
|
5
11
|
import useInnerProps, { getCustomEvent } from '../getInnerListeners'
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import DateSelector from './date'
|
|
10
|
-
import MultiSelector from './multiSelector'
|
|
11
|
-
import RegionSelector from './region'
|
|
12
|
-
import { PickerProps, EventType, ValueType } from './type'
|
|
13
|
-
import { FormContext, FormFieldValue } from '../context'
|
|
12
|
+
import { extendObject } from '../utils'
|
|
13
|
+
import { createPopupManager } from '../mpx-popup'
|
|
14
|
+
import { EventType, LanguageCode, PickerMode, PickerProps } from './type'
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* ✔ mode
|
|
@@ -27,131 +28,251 @@ import { FormContext, FormFieldValue } from '../context'
|
|
|
27
28
|
* ✔ custom-item
|
|
28
29
|
* ✔ level 选择器层级 province,city,region,<sub-district不支持>
|
|
29
30
|
* ✔ level
|
|
30
|
-
*
|
|
31
|
-
*
|
|
31
|
+
* ✔ header-text
|
|
32
|
+
* ✔ bindcolumnchange
|
|
32
33
|
*/
|
|
33
34
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
const styles = StyleSheet.create({
|
|
36
|
+
header: {
|
|
37
|
+
height: 40,
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
justifyContent: 'center',
|
|
40
|
+
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
41
|
+
borderBottomColor: '#eeeeee'
|
|
42
|
+
},
|
|
43
|
+
headerText: {
|
|
44
|
+
color: '#333333',
|
|
45
|
+
fontSize: 18,
|
|
46
|
+
textAlign: 'center'
|
|
47
|
+
},
|
|
48
|
+
footer: {
|
|
49
|
+
gap: 20,
|
|
50
|
+
height: 50,
|
|
51
|
+
marginBottom: 20,
|
|
52
|
+
alignItems: 'center',
|
|
53
|
+
flexDirection: 'row',
|
|
54
|
+
justifyContent: 'center'
|
|
55
|
+
},
|
|
56
|
+
footerItem: {
|
|
57
|
+
alignItems: 'center',
|
|
58
|
+
justifyContent: 'center',
|
|
59
|
+
height: 40,
|
|
60
|
+
width: 110,
|
|
61
|
+
borderRadius: 5
|
|
62
|
+
},
|
|
63
|
+
cancelButton: {
|
|
64
|
+
backgroundColor: '#eeeeee'
|
|
65
|
+
},
|
|
66
|
+
confirmButton: {
|
|
67
|
+
backgroundColor: '#1AAD19'
|
|
68
|
+
},
|
|
69
|
+
cancelText: {
|
|
70
|
+
color: 'green',
|
|
71
|
+
fontSize: 18,
|
|
72
|
+
textAlign: 'center'
|
|
73
|
+
},
|
|
74
|
+
confirmText: {
|
|
75
|
+
color: '#FFFFFF',
|
|
76
|
+
fontSize: 18,
|
|
77
|
+
textAlign: 'center'
|
|
52
78
|
}
|
|
79
|
+
})
|
|
53
80
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
81
|
+
const pickerModalMap: Record<PickerMode, React.ComponentType<PickerProps>> = {
|
|
82
|
+
[PickerMode.SELECTOR]: PickerSelector,
|
|
83
|
+
[PickerMode.MULTI_SELECTOR]: PickerMultiSelector,
|
|
84
|
+
[PickerMode.TIME]: PickerTime,
|
|
85
|
+
[PickerMode.DATE]: PickerDate,
|
|
86
|
+
[PickerMode.REGION]: PickerRegion
|
|
87
|
+
}
|
|
57
88
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
89
|
+
const getDefaultValue = (mode: PickerMode) => {
|
|
90
|
+
switch (mode) {
|
|
91
|
+
case PickerMode.SELECTOR:
|
|
92
|
+
case PickerMode.MULTI_SELECTOR:
|
|
93
|
+
case PickerMode.REGION:
|
|
94
|
+
return []
|
|
95
|
+
case PickerMode.TIME:
|
|
96
|
+
case PickerMode.DATE:
|
|
97
|
+
default:
|
|
98
|
+
return ''
|
|
61
99
|
}
|
|
100
|
+
}
|
|
62
101
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
102
|
+
const buttonTextMap: Record<LanguageCode, { cancel: string; confirm: string }> = {
|
|
103
|
+
'zh-CN': {
|
|
104
|
+
cancel: '取消',
|
|
105
|
+
confirm: '确定'
|
|
106
|
+
},
|
|
107
|
+
'en-US': {
|
|
108
|
+
cancel: 'Cancel',
|
|
109
|
+
confirm: 'Confirm'
|
|
67
110
|
}
|
|
111
|
+
}
|
|
68
112
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
113
|
+
const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
|
|
114
|
+
(props: PickerProps, ref): React.JSX.Element => {
|
|
115
|
+
const {
|
|
116
|
+
mode,
|
|
117
|
+
value,
|
|
118
|
+
range = null,
|
|
119
|
+
children,
|
|
120
|
+
disabled,
|
|
121
|
+
bindcancel,
|
|
122
|
+
bindchange,
|
|
123
|
+
'header-text': headerText = ''
|
|
124
|
+
} = props
|
|
125
|
+
|
|
126
|
+
const { pageId } = useContext(RouteContext) || {}
|
|
127
|
+
const buttonText = buttonTextMap[(global.__mpx?.i18n?.locale as LanguageCode) || 'zh-CN']
|
|
128
|
+
const pickerValue = useRef(value)
|
|
129
|
+
pickerValue.current = Array.isArray(value) ? value.slice() : value
|
|
130
|
+
const innerLayout = useRef({})
|
|
131
|
+
const nodeRef = useRef(null)
|
|
132
|
+
const pickerRef = useRef<any>(null)
|
|
133
|
+
const { open, show, hide, remove } = useRef(createPopupManager()).current
|
|
134
|
+
|
|
135
|
+
useNodesRef<View, PickerProps>(props, ref, nodeRef)
|
|
136
|
+
const innerProps = useInnerProps(
|
|
137
|
+
props,
|
|
138
|
+
{
|
|
139
|
+
ref: nodeRef
|
|
140
|
+
},
|
|
141
|
+
[],
|
|
142
|
+
{ layoutRef: innerLayout }
|
|
143
|
+
)
|
|
144
|
+
const getInnerLayout = (layout: React.MutableRefObject<{}>) => {
|
|
145
|
+
innerLayout.current = layout.current
|
|
77
146
|
}
|
|
78
|
-
}
|
|
79
147
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
if (range && pickerRef.current && mode === PickerMode.MULTI_SELECTOR) {
|
|
150
|
+
pickerRef.current.updateRange?.(range)
|
|
151
|
+
}
|
|
152
|
+
}, [JSON.stringify(range)])
|
|
83
153
|
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
154
|
+
/** --- form 表单组件内部方法 --- */
|
|
155
|
+
const getValue = () => {
|
|
156
|
+
return pickerValue.current
|
|
157
|
+
}
|
|
158
|
+
const resetValue = () => {
|
|
159
|
+
const defalutValue = getDefaultValue(mode) // 默认值
|
|
160
|
+
pickerRef.current.updateValue?.(defalutValue)
|
|
161
|
+
}
|
|
162
|
+
const formContext = useContext(FormContext)
|
|
163
|
+
let formValuesMap: Map<string, FormFieldValue> | undefined
|
|
164
|
+
if (formContext) {
|
|
165
|
+
formValuesMap = formContext.formValuesMap
|
|
166
|
+
}
|
|
167
|
+
if (formValuesMap) {
|
|
168
|
+
if (!props.name) {
|
|
169
|
+
warn('If a form component is used, the name attribute is required.')
|
|
170
|
+
} else {
|
|
171
|
+
formValuesMap.set(props.name, { getValue, resetValue })
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
return () => {
|
|
176
|
+
if (formValuesMap && props.name) {
|
|
177
|
+
formValuesMap.delete(props.name)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}, [])
|
|
181
|
+
/** --- form 表单组件内部方法 --- */
|
|
89
182
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
const commonProps = {
|
|
96
|
-
...innerProps,
|
|
97
|
-
mode,
|
|
98
|
-
children,
|
|
99
|
-
bindchange: onChange,
|
|
100
|
-
bindcolumnchange: columnChange,
|
|
101
|
-
bindcancel,
|
|
102
|
-
getInnerLayout
|
|
103
|
-
}
|
|
183
|
+
const onChange = (e: EventType) => {
|
|
184
|
+
const { value } = e.detail
|
|
185
|
+
pickerValue.current = value
|
|
186
|
+
}
|
|
104
187
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
188
|
+
const onColumnChange = (columnIndex: number, value: number) => {
|
|
189
|
+
if (mode !== PickerMode.MULTI_SELECTOR) {
|
|
190
|
+
return
|
|
191
|
+
}
|
|
192
|
+
const eventData = getCustomEvent(
|
|
193
|
+
'columnchange',
|
|
194
|
+
{},
|
|
195
|
+
{ detail: { column: columnIndex, value }, layoutRef: innerLayout }
|
|
196
|
+
)
|
|
197
|
+
props.bindcolumnchange?.(eventData)
|
|
198
|
+
}
|
|
111
199
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
'range-key': props['range-key']
|
|
117
|
-
}
|
|
200
|
+
const onCancel = () => {
|
|
201
|
+
bindcancel?.()
|
|
202
|
+
hide()
|
|
203
|
+
}
|
|
118
204
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
205
|
+
const onConfirm = () => {
|
|
206
|
+
const eventData = getCustomEvent(
|
|
207
|
+
'change',
|
|
208
|
+
{},
|
|
209
|
+
{ detail: { value: pickerValue.current }, layoutRef: innerLayout }
|
|
210
|
+
)
|
|
211
|
+
bindchange?.(eventData)
|
|
212
|
+
hide()
|
|
213
|
+
}
|
|
125
214
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
215
|
+
const specificProps = extendObject(innerProps, {
|
|
216
|
+
mode,
|
|
217
|
+
children,
|
|
218
|
+
bindchange: onChange,
|
|
219
|
+
bindcolumnchange: onColumnChange,
|
|
220
|
+
getInnerLayout,
|
|
221
|
+
getRange: () => range
|
|
222
|
+
})
|
|
133
223
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
224
|
+
const renderPickerContent = () => {
|
|
225
|
+
if (disabled) {
|
|
226
|
+
return null
|
|
227
|
+
}
|
|
228
|
+
const _mode = mode ?? PickerMode.SELECTOR
|
|
229
|
+
if (!(_mode in pickerModalMap)) {
|
|
230
|
+
return warn(`[Mpx runtime warn]: Unsupported <picker> mode: ${mode}`)
|
|
231
|
+
}
|
|
232
|
+
const _value: any = value
|
|
233
|
+
const PickerModal = pickerModalMap[_mode]
|
|
234
|
+
const renderPickerModal = (
|
|
235
|
+
<>
|
|
236
|
+
{headerText && (
|
|
237
|
+
<View style={[styles.header]}>
|
|
238
|
+
<Text style={[styles.headerText]}>{headerText}</Text>
|
|
239
|
+
</View>
|
|
240
|
+
)}
|
|
241
|
+
<PickerModal {...specificProps} value={_value} ref={pickerRef}></PickerModal>
|
|
242
|
+
<View style={[styles.footer]}>
|
|
243
|
+
<View
|
|
244
|
+
onTouchEnd={onCancel}
|
|
245
|
+
style={[styles.footerItem, styles.cancelButton]}
|
|
246
|
+
>
|
|
247
|
+
<Text style={[styles.cancelText]}>{buttonText.cancel}</Text>
|
|
248
|
+
</View>
|
|
249
|
+
<View
|
|
250
|
+
onTouchEnd={onConfirm}
|
|
251
|
+
style={[styles.footerItem, styles.confirmButton]}
|
|
252
|
+
>
|
|
253
|
+
<Text style={[styles.confirmText]}>{buttonText.confirm}</Text>
|
|
254
|
+
</View>
|
|
255
|
+
</View>
|
|
256
|
+
</>
|
|
257
|
+
)
|
|
258
|
+
const contentHeight = headerText ? 350 : 310
|
|
259
|
+
open(renderPickerModal, pageId, { contentHeight })
|
|
260
|
+
}
|
|
139
261
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
} else if (mode === 'date') {
|
|
147
|
-
return <DateSelector {...dateProps}></DateSelector>
|
|
148
|
-
} else if (mode === 'region') {
|
|
149
|
-
return <RegionSelector {...regionProps}></RegionSelector>
|
|
150
|
-
} else {
|
|
151
|
-
return <View>只支持selector, multiSelector, time, date, region 这些类型</View>
|
|
152
|
-
}
|
|
153
|
-
})
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
renderPickerContent()
|
|
264
|
+
return () => {
|
|
265
|
+
remove()
|
|
266
|
+
}
|
|
267
|
+
}, [])
|
|
154
268
|
|
|
155
|
-
|
|
269
|
+
return (
|
|
270
|
+
<TouchableWithoutFeedback onPress={show}>
|
|
271
|
+
{children}
|
|
272
|
+
</TouchableWithoutFeedback>
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
)
|
|
156
276
|
|
|
157
|
-
|
|
277
|
+
Picker.displayName = 'MpxPicker'
|
|
278
|
+
export default Picker
|
|
@@ -1,160 +1,117 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react'
|
|
2
|
+
import { StyleSheet, Text, View } from 'react-native'
|
|
3
|
+
import { MultiSelectorProps, Obj, RangeItem } from './type'
|
|
4
|
+
import MpxPickerView from '../mpx-picker-view'
|
|
5
|
+
import MpxPickerViewColumn from '../mpx-picker-view-column'
|
|
6
|
+
import { HandlerRef } from '../useNodesRef' // 引入辅助函数
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const styles = StyleSheet.create({
|
|
9
|
+
pickerContainer: {
|
|
10
|
+
height: 240,
|
|
11
|
+
paddingHorizontal: 10,
|
|
12
|
+
borderTopLeftRadius: 10,
|
|
13
|
+
borderTopRightRadius: 10
|
|
14
|
+
},
|
|
15
|
+
pickerIndicator: {
|
|
16
|
+
height: 45
|
|
17
|
+
},
|
|
18
|
+
pickerItem: {
|
|
19
|
+
fontSize: 18,
|
|
20
|
+
lineHeight: 45,
|
|
21
|
+
textAlign: 'center'
|
|
12
22
|
}
|
|
13
|
-
}
|
|
23
|
+
})
|
|
14
24
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const result = (range[0] || []).map(item => {
|
|
18
|
-
return convertToObj(item, rangeKey)
|
|
19
|
-
})
|
|
20
|
-
let tmp = result
|
|
21
|
-
for (let i = 1; i < range.length; i++) {
|
|
22
|
-
const child = Array.isArray(range[i]) ? range[i] : []
|
|
23
|
-
const nextColData = child.map(item => {
|
|
24
|
-
return convertToObj(item, rangeKey)
|
|
25
|
-
})
|
|
26
|
-
tmp.forEach(item => {
|
|
27
|
-
item.children = nextColData
|
|
28
|
-
})
|
|
29
|
-
tmp = nextColData
|
|
30
|
-
}
|
|
31
|
-
return result
|
|
32
|
-
}
|
|
25
|
+
const formatRangeFun = (range: RangeItem[], rangeKey = '') =>
|
|
26
|
+
rangeKey ? range.map((item: Obj) => item[rangeKey]) : range
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return value.map(v => {
|
|
37
|
-
for (let i = 0; i < tmp.length; i++) {
|
|
38
|
-
if (tmp[i].value === v) {
|
|
39
|
-
tmp = tmp[i].children || []
|
|
40
|
-
return i
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return 0
|
|
44
|
-
})
|
|
28
|
+
const formatValueFn = (value: number | number[]) => {
|
|
29
|
+
return Array.isArray(value) ? value : [value]
|
|
45
30
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return value.map(v => {
|
|
50
|
-
const current = tmp[v].value
|
|
51
|
-
tmp = tmp[v].children
|
|
52
|
-
return current
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
// column = 1 value = ['无脊柱动物', '扁性动物', '吸血虫'] 根据column 和value 获取到当前列变动选择的值所在当前列的索引
|
|
56
|
-
function getColumnIndexByValue (range: any[] = [], column: number, value: any[] = []): number {
|
|
57
|
-
let curRange = range
|
|
58
|
-
let changeIndex = 0
|
|
59
|
-
let tmpRange: any[] = []
|
|
60
|
-
value.map((item, index) => {
|
|
61
|
-
if (column === index) {
|
|
62
|
-
curRange.map((ritem, rindex) => {
|
|
63
|
-
if (ritem.value === item) {
|
|
64
|
-
changeIndex = rindex
|
|
65
|
-
}
|
|
66
|
-
return ritem
|
|
67
|
-
})
|
|
68
|
-
} else {
|
|
69
|
-
curRange.map((citem, cindex) => {
|
|
70
|
-
if (citem.value === item) {
|
|
71
|
-
tmpRange = citem.children
|
|
72
|
-
}
|
|
73
|
-
return citem
|
|
74
|
-
})
|
|
75
|
-
curRange = tmpRange
|
|
76
|
-
}
|
|
77
|
-
return item
|
|
78
|
-
})
|
|
79
|
-
return changeIndex
|
|
31
|
+
|
|
32
|
+
const hasDiff = (a: number[], b: number[]) => {
|
|
33
|
+
return a.length !== b.length || a.some((item, index) => item !== b[index])
|
|
80
34
|
}
|
|
81
35
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
const [
|
|
90
|
-
|
|
91
|
-
const layoutRef = useRef({})
|
|
92
|
-
const viewRef = useRef<View>(null)
|
|
93
|
-
const nodeRef = useRef<View>(null)
|
|
94
|
-
useNodesRef<View, MultiSelectorProps>(props, ref, nodeRef, {
|
|
95
|
-
style
|
|
96
|
-
})
|
|
36
|
+
const PickerMultiSelector = forwardRef<
|
|
37
|
+
HandlerRef<View, MultiSelectorProps>,
|
|
38
|
+
MultiSelectorProps
|
|
39
|
+
>((props: MultiSelectorProps, ref): React.JSX.Element => {
|
|
40
|
+
const { value = [], range = [], bindchange, bindcolumnchange } = props
|
|
41
|
+
const _value = formatValueFn(value)
|
|
42
|
+
const [formatValue, setFormatValue] = useState<number[]>(_value)
|
|
43
|
+
const [formatRange, setFormatRange] = useState(formatRangeFun(range, props['range-key']))
|
|
44
|
+
const nodeRef = useRef(null)
|
|
97
45
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
46
|
+
const updateValue = useCallback((value: number[] = []) => {
|
|
47
|
+
let newValue = formatValueFn(value)
|
|
48
|
+
if (newValue.length === 0) {
|
|
49
|
+
newValue = formatValue.map(() => 0)
|
|
50
|
+
}
|
|
51
|
+
checkColumnChange(newValue, formatValue)
|
|
52
|
+
if (hasDiff(newValue, formatValue)) {
|
|
53
|
+
setFormatValue(newValue)
|
|
102
54
|
}
|
|
103
|
-
|
|
104
|
-
value && setSelected(newValue)
|
|
105
|
-
}, [range, value])
|
|
55
|
+
}, [formatValue])
|
|
106
56
|
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
57
|
+
const updateRange = (newRange: RangeItem[]) => {
|
|
58
|
+
const range = formatRangeFun(newRange.slice(), props['range-key'])
|
|
59
|
+
setFormatRange(range)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const _props = useRef(props)
|
|
63
|
+
_props.current = props
|
|
64
|
+
useImperativeHandle(ref, () => ({
|
|
65
|
+
updateValue,
|
|
66
|
+
updateRange,
|
|
67
|
+
getNodeInstance: () => ({
|
|
68
|
+
props: _props,
|
|
69
|
+
nodeRef,
|
|
70
|
+
instance: {
|
|
71
|
+
style: {}
|
|
113
72
|
}
|
|
114
73
|
})
|
|
115
|
-
}
|
|
74
|
+
}))
|
|
116
75
|
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
76
|
+
const onChange = (e: { detail: { value: number[] } }) => {
|
|
77
|
+
const { value } = e.detail
|
|
78
|
+
checkColumnChange(value, formatValue)
|
|
79
|
+
bindchange?.({ detail: { value: value } })
|
|
80
|
+
if (hasDiff(value, formatValue)) {
|
|
81
|
+
setFormatValue(value.slice())
|
|
82
|
+
}
|
|
121
83
|
}
|
|
122
84
|
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
85
|
+
const checkColumnChange = (value: number[], formatValue: number[]) => {
|
|
86
|
+
const index = value.findIndex((v, i) => v !== formatValue[i])
|
|
87
|
+
if (index !== -1) {
|
|
88
|
+
bindcolumnchange?.(index, value[index])
|
|
89
|
+
}
|
|
128
90
|
}
|
|
129
91
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
onDismiss: bindcancel && bindcancel,
|
|
140
|
-
onPickerChange: onPickerChange
|
|
141
|
-
} as any
|
|
142
|
-
|
|
143
|
-
const touchProps = {
|
|
144
|
-
onLayout: onElementLayout,
|
|
145
|
-
ref: viewRef
|
|
92
|
+
const renderColumn = (columnData: any[], index: number) => {
|
|
93
|
+
return (
|
|
94
|
+
// @ts-expect-error ignore
|
|
95
|
+
<MpxPickerViewColumn key={index}>
|
|
96
|
+
{columnData.map((item, index) => (
|
|
97
|
+
<Text key={index} style={styles.pickerItem}>{item}</Text>
|
|
98
|
+
))}
|
|
99
|
+
</MpxPickerViewColumn>
|
|
100
|
+
)
|
|
146
101
|
}
|
|
147
102
|
|
|
148
|
-
return (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
103
|
+
return (
|
|
104
|
+
<MpxPickerView
|
|
105
|
+
style={styles.pickerContainer}
|
|
106
|
+
indicator-style={styles.pickerIndicator}
|
|
107
|
+
value={formatValue}
|
|
108
|
+
bindchange={onChange}
|
|
109
|
+
>
|
|
110
|
+
{formatRange.map((item, index) => (
|
|
111
|
+
renderColumn(item, index)
|
|
112
|
+
))}
|
|
113
|
+
</MpxPickerView>)
|
|
156
114
|
})
|
|
157
115
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
export default _MultiSelectorPicker
|
|
116
|
+
PickerMultiSelector.displayName = 'MpxPickerMultiSelector'
|
|
117
|
+
export default PickerMultiSelector
|