@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.
Files changed (103) 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 +3 -6
  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 +2 -6
  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/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
  99. /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
  100. /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
  101. /package/lib/runtime/components/react/{pickerVIewContext.ts → mpx-picker-view/pickerVIewContext.ts} +0 -0
  102. /package/lib/runtime/components/react/{pickerViewIndicator.tsx → mpx-picker-view-column/pickerViewIndicator.tsx} +0 -0
  103. /package/lib/runtime/components/react/{pickerViewMask.tsx → mpx-picker-view-column/pickerViewMask.tsx} +0 -0
@@ -1,16 +1,17 @@
1
- import { View } from 'react-native'
2
- import { PickerValue } from '@ant-design/react-native'
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 useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
7
- import Selector from './selector'
8
- import TimeSelector from './time'
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
- * header-text
31
- * bindcolumnchange
31
+ * header-text
32
+ * bindcolumnchange
32
33
  */
33
34
 
34
- const _Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>((props: PickerProps, ref): React.JSX.Element => {
35
- const { mode = 'selector', value, bindcancel, bindchange, children, bindcolumnchange, style } = props
36
- const innerLayout = useRef({})
37
- const nodeRef = useRef(null)
38
- useNodesRef<View, PickerProps>(props, ref, nodeRef, {
39
- style
40
- })
41
- const innerProps = useInnerProps(props, {
42
- ref: nodeRef
43
- }, [], { layoutRef: innerLayout })
44
-
45
- const [pickerValue, setPickerValue] = useState(value as ValueType)
46
- const defaultValues = {
47
- selector: 0,
48
- multiSelector: [0],
49
- time: props.start,
50
- date: props.start,
51
- region: undefined
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
- const formContext = useContext(FormContext)
55
-
56
- let formValuesMap: Map<string, FormFieldValue> | undefined
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
- // 判断 context 是否存在,存在的话读取 context 中存的 formValuesMap
59
- if (formContext) {
60
- formValuesMap = formContext.formValuesMap
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
- const resetValue = () => {
64
- type curMode = keyof typeof defaultValues
65
- const defalutValue = (defaultValues[mode as curMode] !== undefined ? defaultValues[mode as curMode] : value) as ValueType
66
- setPickerValue(defalutValue)
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
- const getValue = () => {
70
- return pickerValue
71
- }
72
- if (formValuesMap) {
73
- if (!props.name) {
74
- warn('If a form component is used, the name attribute is required.')
75
- } else {
76
- formValuesMap.set(props.name, { getValue, resetValue })
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
- const getInnerLayout = (layout: React.MutableRefObject<{}>) => {
81
- innerLayout.current = layout.current
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
- const onChange = (event: EventType) => {
85
- const eventData = getCustomEvent('change', {}, { detail: event.detail, layoutRef: innerLayout })
86
- bindchange && bindchange(eventData)
87
- setPickerValue(event.detail.value as ValueType)
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
- const columnChange = (value: PickerValue[], index: number) => {
91
- // type: "columnchange", detail: {column: 1, value: 2}
92
- const eventData = getCustomEvent('columnchange', {}, { detail: { column: index, value }, layoutRef: innerLayout })
93
- bindcolumnchange && bindcolumnchange(eventData)
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
- const selectorProps = {
106
- ...commonProps,
107
- value: pickerValue as PickerValue,
108
- range: props.range,
109
- 'range-key': props['range-key']
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
- const multiProps = {
113
- ...commonProps,
114
- value: pickerValue as Array<number>,
115
- range: props.range,
116
- 'range-key': props['range-key']
117
- }
200
+ const onCancel = () => {
201
+ bindcancel?.()
202
+ hide()
203
+ }
118
204
 
119
- const timeProps = {
120
- ...commonProps,
121
- value: pickerValue as string,
122
- start: props.start,
123
- end: props.end
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
- const dateProps = {
127
- ...commonProps,
128
- value: pickerValue as string,
129
- start: props.start,
130
- end: props.end,
131
- fileds: props.fields || 'day'
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
- const regionProps = {
135
- ...commonProps,
136
- value: pickerValue as Array<string>,
137
- level: props.level || 'sub-district'
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
- if (mode === 'selector') {
141
- return <Selector {...selectorProps}></Selector>
142
- } else if (mode === 'multiSelector') {
143
- return <MultiSelector {...multiProps}></MultiSelector>
144
- } else if (mode === 'time') {
145
- return <TimeSelector {...timeProps}></TimeSelector>
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
- _Picker.displayName = 'mpx-picker'
269
+ return (
270
+ <TouchableWithoutFeedback onPress={show}>
271
+ {children}
272
+ </TouchableWithoutFeedback>
273
+ )
274
+ }
275
+ )
156
276
 
157
- export default _Picker
277
+ Picker.displayName = 'MpxPicker'
278
+ export default Picker
@@ -1,160 +1,117 @@
1
- import { View, TouchableWithoutFeedback } from 'react-native'
2
- import { Picker, PickerValue } from '@ant-design/react-native'
3
- import React, { forwardRef, useState, useRef, useEffect } from 'react'
4
- import { MultiSelectorProps, LayoutType } from './type'
5
- import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
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
- function convertToObj (item?: any, rangeKey = ''): any {
8
- if (typeof item === 'object') {
9
- return { value: item[rangeKey], label: item[rangeKey] }
10
- } else {
11
- return { value: item, label: item }
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
- // eslint-disable-next-line default-param-last
16
- function formatRangeFun (range: any[][] = [], rangeKey?: string): any[] {
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
- function getIndexByValues (range: any[] = [], value: any[] = []): number[] {
35
- let tmp = range
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
- // [1,1,2] 寻找出[]
47
- function getInnerValueByIndex (range: any[] = [], value: any[] = []): string[] {
48
- let tmp = range
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 _MultiSelectorPicker = forwardRef<HandlerRef<View, MultiSelectorProps>, MultiSelectorProps>((props: MultiSelectorProps, ref): React.JSX.Element => {
83
- const { range, value, disabled, bindchange, bindcancel, children, bindcolumnchange, style } = props
84
- const formatRange = formatRangeFun(range, props['range-key'])
85
- const initValue = getInnerValueByIndex(formatRange, value)
86
- // 选中的索引值
87
- const [selected, setSelected] = useState(initValue)
88
- // range数据源
89
- const [data, setData] = useState(formatRange || [])
90
- // 存储layout布局信息
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
- useEffect(() => {
99
- if (range) {
100
- const newFormatRange = formatRangeFun(range, props['range-key'])
101
- setData(newFormatRange)
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
- const newValue = getInnerValueByIndex(formatRange, value)
104
- value && setSelected(newValue)
105
- }, [range, value])
55
+ }, [formatValue])
106
56
 
107
- const onChange = (value: PickerValue[]) => {
108
- // e.detail.value 都是索引multi
109
- const strIndex = getIndexByValues(data, value)
110
- bindchange && bindchange({
111
- detail: {
112
- value: strIndex
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 onPickerChange = (value: PickerValue[], column: number) => {
118
- // onPickerChange--- ["无脊柱动物", "节肢动物", "吸血虫"] 1 拿着column
119
- const changeIndex = getColumnIndexByValue(data, column, value)
120
- bindcolumnchange && bindcolumnchange(changeIndex, column)
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 onElementLayout = () => {
124
- viewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
125
- layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
126
- props.getInnerLayout && props.getInnerLayout(layoutRef)
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 antPickerProps = {
131
- ref: nodeRef,
132
- data,
133
- value: selected,
134
- cols: range.length,
135
- defaultValue: initValue,
136
- disabled,
137
- itemHeight: 40,
138
- onChange,
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 (<Picker {...antPickerProps}>
149
- <TouchableWithoutFeedback>
150
- <View {...touchProps}>
151
- {children}
152
- </View>
153
- </TouchableWithoutFeedback>
154
- </Picker>
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
- _MultiSelectorPicker.displayName = 'mpx-picker-multiselector'
159
-
160
- export default _MultiSelectorPicker
116
+ PickerMultiSelector.displayName = 'MpxPickerMultiSelector'
117
+ export default PickerMultiSelector