@mpxjs/webpack-plugin 2.9.59 → 2.9.62

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 (106) hide show
  1. package/lib/platform/style/wx/index.js +314 -254
  2. package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
  3. package/lib/platform/template/wx/component-config/checkbox.js +8 -0
  4. package/lib/platform/template/wx/component-config/cover-image.js +15 -0
  5. package/lib/platform/template/wx/component-config/cover-view.js +9 -0
  6. package/lib/platform/template/wx/component-config/form.js +13 -1
  7. package/lib/platform/template/wx/component-config/icon.js +8 -0
  8. package/lib/platform/template/wx/component-config/index.js +5 -1
  9. package/lib/platform/template/wx/component-config/label.js +15 -0
  10. package/lib/platform/template/wx/component-config/movable-area.js +18 -1
  11. package/lib/platform/template/wx/component-config/movable-view.js +18 -1
  12. package/lib/platform/template/wx/component-config/navigator.js +8 -0
  13. package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
  14. package/lib/platform/template/wx/component-config/picker-view.js +18 -2
  15. package/lib/platform/template/wx/component-config/picker.js +14 -1
  16. package/lib/platform/template/wx/component-config/radio-group.js +8 -0
  17. package/lib/platform/template/wx/component-config/radio.js +8 -0
  18. package/lib/platform/template/wx/component-config/root-portal.js +15 -0
  19. package/lib/platform/template/wx/component-config/switch.js +8 -0
  20. package/lib/platform/template/wx/component-config/unsupported.js +1 -3
  21. package/lib/react/processScript.js +2 -0
  22. package/lib/runtime/components/react/context.ts +38 -0
  23. package/lib/runtime/components/react/dist/context.js +7 -0
  24. package/lib/runtime/components/react/dist/getInnerListeners.js +22 -11
  25. package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
  26. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
  27. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
  28. package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
  29. package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
  30. package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
  31. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
  32. package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
  33. package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
  34. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
  35. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
  36. package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
  37. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
  38. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  45. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
  46. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
  47. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
  48. package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
  49. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
  50. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
  51. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
  52. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
  53. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
  54. package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
  55. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
  56. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  57. package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
  58. package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
  59. package/lib/runtime/components/react/dist/types/common.js +1 -0
  60. package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
  61. package/lib/runtime/components/react/dist/utils.js +82 -14
  62. package/lib/runtime/components/react/getInnerListeners.ts +25 -13
  63. package/lib/runtime/components/react/mpx-button.tsx +87 -67
  64. package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
  65. package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
  66. package/lib/runtime/components/react/mpx-form.tsx +89 -0
  67. package/lib/runtime/components/react/mpx-icon.tsx +103 -0
  68. package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
  69. package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
  70. package/lib/runtime/components/react/mpx-input.tsx +54 -26
  71. package/lib/runtime/components/react/mpx-label.tsx +115 -0
  72. package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
  73. package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
  74. package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
  75. package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
  76. package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
  77. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
  78. package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
  79. package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
  80. package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
  81. package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
  82. package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
  83. package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
  84. package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
  85. package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
  86. package/lib/runtime/components/react/mpx-radio.tsx +246 -0
  87. package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
  88. package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
  89. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
  90. package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
  91. package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
  92. package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
  93. package/lib/runtime/components/react/mpx-switch.tsx +127 -0
  94. package/lib/runtime/components/react/mpx-text.tsx +52 -68
  95. package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
  96. package/lib/runtime/components/react/mpx-view.tsx +373 -140
  97. package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
  98. package/lib/runtime/components/react/types/common.ts +12 -0
  99. package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
  100. package/lib/runtime/components/react/types/global.d.ts +4 -0
  101. package/lib/runtime/components/react/useNodesRef.ts +3 -8
  102. package/lib/runtime/components/react/utils.ts +93 -15
  103. package/lib/runtime/optionProcessor.js +19 -17
  104. package/lib/template-compiler/compiler.js +56 -41
  105. package/lib/template-compiler/gen-node-react.js +7 -7
  106. package/package.json +6 -3
@@ -0,0 +1,92 @@
1
+ /**
2
+ * 普通选择器,range可以是Array<Obj> 也可以是Array
3
+ */
4
+ import { View, TouchableWithoutFeedback } from 'react-native'
5
+ import React, { forwardRef, useState, useRef, useEffect } from 'react'
6
+ import { Picker, PickerColumn, PickerValue } from '@ant-design/react-native'
7
+ import { SelectorProps, Obj, LayoutType } from './type'
8
+ import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
9
+
10
+ type RangeItemType = Obj | number | string
11
+
12
+ const formatRangeFun = (range: Array<RangeItemType>, rangeKey = ''): any => {
13
+ let newRange: Object[] = []
14
+ newRange = (range || []).map((item: RangeItemType, index) => {
15
+ if (typeof item === 'object') {
16
+ return { value: index, label: item[rangeKey as string] }
17
+ } else {
18
+ return { value: index, label: item }
19
+ }
20
+ })
21
+ return newRange as PickerColumn
22
+ }
23
+
24
+ const _SelectorPicker = forwardRef<HandlerRef<View, SelectorProps>, SelectorProps>((props: SelectorProps, ref): React.JSX.Element => {
25
+ const { range, children, value, disabled, bindchange, bindcancel } = props
26
+ // 格式化数据为Array<*>
27
+ let formatRange: PickerColumn = formatRangeFun(range, props['range-key'])
28
+ // 选中的索引值
29
+ const [selected, setSelected] = useState<PickerValue>(value || 0)
30
+ // range数据源
31
+ const [data, setData] = useState(formatRange || [])
32
+ // 存储layout布局信息
33
+ const layoutRef = useRef({})
34
+ const { nodeRef: viewRef } = useNodesRef<View, SelectorProps>(props, ref, {
35
+ })
36
+
37
+ useEffect(() => {
38
+ if (range) {
39
+ const newFormatRange = formatRangeFun(range, props['range-key'])
40
+ setData(newFormatRange)
41
+ }
42
+ setSelected(() => {
43
+ return value
44
+ })
45
+ }, [range, value])
46
+ const defaultValue = [value]
47
+
48
+ const onChange = (value: PickerValue[]) => {
49
+ bindchange && bindchange({
50
+ detail: {
51
+ value: value && value[0]
52
+ }
53
+ })
54
+ }
55
+
56
+ const onElementLayout = (layout: LayoutType) => {
57
+ viewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
58
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
59
+ props.getInnerLayout && props.getInnerLayout(layoutRef)
60
+ })
61
+ }
62
+
63
+
64
+ const antPickerProps = {
65
+ data,
66
+ value: [selected],
67
+ cols: 1,
68
+ defaultValue,
69
+ itemHeight: 40,
70
+ onChange,
71
+ onDismiss: bindcancel && bindcancel
72
+ } as any
73
+
74
+ const touchProps = {
75
+ onLayout: onElementLayout,
76
+ ref: viewRef
77
+ }
78
+ return (
79
+ <Picker
80
+ {...antPickerProps}>
81
+ <TouchableWithoutFeedback>
82
+ <View {...touchProps}>
83
+ {children}
84
+ </View>
85
+ </TouchableWithoutFeedback>
86
+ </Picker>
87
+ )
88
+ })
89
+
90
+ _SelectorPicker.displayName = 'mpx-picker-selector';
91
+
92
+ export default _SelectorPicker
@@ -0,0 +1,274 @@
1
+ import { View, Text, Modal, TouchableWithoutFeedback } from 'react-native'
2
+ import { PickerView } from '@ant-design/react-native'
3
+ import React, { forwardRef, useState, useRef, useEffect } from 'react'
4
+ import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
5
+ import { TimeProps } from './type'
6
+
7
+ // 可见应用窗口的大小。
8
+ // const { height: dHeight, width: dWidth } = Dimensions.get('window');
9
+ // modal属性: {"height": 298.33331298828125, "offsetLeft": 0, "offsetTop": 513.6666870117188, "width": 375, "x": 0, "y": 513.6666870117188}
10
+ // const { height: sHeight, width: sWidth } = Dimensions.get('screen');
11
+ // 设备屏幕的大小。 screen
12
+
13
+ const styles: { [key: string]: Object } = {
14
+ showModal: {
15
+ backgroundColor: "black",
16
+ opacity: 0.5,
17
+ position: "absolute",
18
+ width: "100%"
19
+ },
20
+ hideModal: {
21
+ opacity: 1,
22
+ height: 0
23
+ },
24
+ modal: {
25
+ backgroundColor: "black",
26
+ opacity: 0.5
27
+ },
28
+ centeredView: {
29
+ position: 'absolute',
30
+ bottom: 0,
31
+ width: "100%",
32
+ overflow: 'scroll'
33
+ },
34
+ btnLine: {
35
+ width: "100%",
36
+ flex: 1,
37
+ flexDirection: "row",
38
+ justifyContent: "space-between",
39
+ borderColor: 20,
40
+ borderBottomWidth: 1,
41
+ backgroundColor: "white",
42
+ paddingLeft: 40,
43
+ paddingRight: 40
44
+ },
45
+ cancel: {
46
+ height: 50,
47
+ display: "flex",
48
+ justifyContent: 'center'
49
+ },
50
+ ok: {
51
+ height: 50,
52
+ display: "flex",
53
+ justifyContent: 'center'
54
+ },
55
+ btntext: {
56
+ color: '#0ae',
57
+ fontSize: 18
58
+ }
59
+ }
60
+
61
+ function formatStrToInt(timestr: string) {
62
+ let [start, end] = timestr.split(':')
63
+ return [parseInt(start), parseInt(end)]
64
+ }
65
+ // [9, 59] to 09:59
66
+ function formatStr(arr: any[]) {
67
+ let [hour, minute] = arr
68
+ if (hour < 10) {
69
+ hour = '0' + hour
70
+ }
71
+ if (minute < 10) {
72
+ minute = '0' + minute
73
+ }
74
+ return hour + ':' + minute
75
+ }
76
+
77
+ function generateMinute() {
78
+ let arrMinute: any[] = []
79
+ for (let i = 0; i <= 59; i++) {
80
+ let obj = {
81
+ label: toSingleStr(i),
82
+ value: i,
83
+ children: []
84
+ }
85
+ arrMinute.push(obj)
86
+ }
87
+ return arrMinute
88
+ }
89
+ function generateColumns(): any[] {
90
+ let pickData: any[] = []
91
+ for (let i = 0; i <= 23; i++) {
92
+ let obj = {
93
+ label: toSingleStr(i),
94
+ value: i,
95
+ children: generateMinute()
96
+ }
97
+ pickData.push(obj)
98
+ }
99
+
100
+ return pickData
101
+ }
102
+
103
+ function toSingleStr(str: number) {
104
+ return str < 10 ? '0' + str : str
105
+ }
106
+
107
+ function toStr(time: string): string {
108
+ const [hour, minute]: any = formatStrToInt(time)
109
+ const newHour = toSingleStr(hour)
110
+ const newMinute = toSingleStr(minute)
111
+ return '' + newHour + newMinute
112
+ }
113
+
114
+ function checkSelectedIsValid(strStart: string, strEnd: string, selected: number[]): Boolean {
115
+ const strSel = '' + toSingleStr(selected[0]) + toSingleStr(selected[1])
116
+ if (strSel < strStart || strSel > strEnd) return false
117
+ return true
118
+ }
119
+ /**
120
+ * [{label:'', value: '', key: '', children: []}]
121
+ label: string | ReactNode
122
+ value: string | number
123
+ key?: string | number
124
+ children?: PickerColumnItem[]
125
+ */
126
+ // start="02:10" end = 23:01
127
+
128
+ const _TimePicker = forwardRef<HandlerRef<View, TimeProps>, TimeProps>((props: TimeProps, ref): React.JSX.Element => {
129
+ const { children, start, end, value, bindchange, bindcancel, disabled } = props
130
+ const defaultProps = {
131
+ start: '00:10',
132
+ end: '23:59'
133
+ }
134
+ const defaultValue = formatStrToInt(value)
135
+ const [timevalue, setTimeValue] = useState(defaultValue)
136
+ // 存储layout布局信息
137
+ const layoutRef = useRef({})
138
+ const { nodeRef: viewRef } = useNodesRef<View, TimeProps>(props, ref, {})
139
+ // 存储modal的布局信息
140
+ const modalLayoutRef = useRef({})
141
+ const { nodeRef: modalRef } = useNodesRef<View, TimeProps>(props, ref, {})
142
+ const [visible, setVisible] = useState(false)
143
+ const columnData = generateColumns()
144
+ const [data, setData] = useState(columnData)
145
+ const [offsetTop, setOffsetTop] = useState(0)
146
+ const strStart = toStr(start)
147
+ const strEnd = toStr(end)
148
+
149
+ useEffect(() => {
150
+ const newColumnData = generateColumns()
151
+ setData(newColumnData)
152
+ }, [start, end])
153
+
154
+ useEffect(() => {
155
+ if (value) {
156
+ const nValue = formatStrToInt(value)
157
+ nValue && setTimeValue(nValue)
158
+ }
159
+ }, [value])
160
+
161
+ // console.log('---------------visible---', visible, JSON.stringify(columnData))
162
+ const handleModalStatus = (status: boolean) => {
163
+ setVisible(status)
164
+ }
165
+ const handleConfirm = () => {
166
+ handleModalStatus(false)
167
+ bindchange && bindchange({
168
+ detail: {
169
+ value: formatStr(timevalue)
170
+ }
171
+ })
172
+ }
173
+
174
+ const handleCancel = () => {
175
+ handleModalStatus(false)
176
+ bindcancel && bindcancel()
177
+ }
178
+
179
+ const handleChildClick = () => {
180
+ handleModalStatus(true)
181
+ }
182
+
183
+ const handlePickChange = (date: number[]): void => {
184
+ // 不是有效的值
185
+ if (!checkSelectedIsValid(strStart, strEnd, date)) {
186
+ setTimeValue(timevalue)
187
+ } else {
188
+ // [9, 13]
189
+ setTimeValue(date)
190
+ const strDate = formatStr(date)
191
+ bindchange && bindchange({
192
+ detail: {
193
+ value: strDate
194
+ }
195
+ })
196
+ }
197
+ }
198
+
199
+
200
+ const onElementLayout = () => {
201
+ viewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
202
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
203
+ props.getInnerLayout && props.getInnerLayout(layoutRef)
204
+ })
205
+ }
206
+
207
+ const onModalLayout = () => {
208
+ modalRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
209
+ modalLayoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
210
+ setOffsetTop(offsetTop)
211
+ })
212
+ }
213
+
214
+
215
+ const renderModalChildren = () => {
216
+ const pickerProps = {
217
+ data,
218
+ value: timevalue,
219
+ defaultValue: timevalue,
220
+ cols: 2,
221
+ onChange: handlePickChange
222
+ }
223
+ return (
224
+ <View style={styles.centeredView} ref={modalRef} onLayout={onModalLayout}>
225
+ <View style={styles.btnLine}>
226
+ <View style={styles.cancel}>
227
+ <TouchableWithoutFeedback onPress={handleCancel}>
228
+ <Text style={styles.btntext}>取消</Text>
229
+ </TouchableWithoutFeedback>
230
+ </View>
231
+ <View style={styles.ok}>
232
+ <TouchableWithoutFeedback onPress={handleConfirm}>
233
+ <Text style={styles.btntext}>确定</Text>
234
+ </TouchableWithoutFeedback>
235
+ </View>
236
+ </View>
237
+ <PickerView {...pickerProps}></PickerView>
238
+ </View>
239
+ )
240
+ }
241
+
242
+ const renderChildren = () => {
243
+ const touchProps = {
244
+ onLayout: onElementLayout,
245
+ ref: viewRef
246
+ }
247
+ return <View>
248
+ <TouchableWithoutFeedback onPress={handleChildClick}>
249
+ <View {...touchProps}>{children}</View>
250
+ </TouchableWithoutFeedback>
251
+ </View>
252
+ }
253
+ const strStyle = visible ? styles['showModal'] : styles['hideModal']
254
+ const mheight = Math.floor(offsetTop)
255
+
256
+ // Animated.View
257
+ return (<>
258
+ <View style={{ ...strStyle, height: visible ? mheight : 0, bottom: 0 }}>
259
+ <Modal
260
+ animationType="slide"
261
+ transparent={true}
262
+ visible={visible}
263
+ >
264
+ {renderModalChildren()}
265
+ </Modal>
266
+ </View>
267
+ {renderChildren()}
268
+ </>)
269
+ })
270
+
271
+ _TimePicker.displayName = 'mpx-picker-time'
272
+
273
+ export default _TimePicker
274
+
@@ -0,0 +1,107 @@
1
+ import { ReactNode } from 'react'
2
+ import { PickerValue } from '@ant-design/react-native'
3
+
4
+ export type Obj = Record<string, any>
5
+ export type SelectorProps = {
6
+ mode: string,
7
+ // 表示选择了 range 中的第几个(下标从 0 开始)
8
+ value: PickerValue
9
+ disabled?: boolean,
10
+ children: ReactNode,
11
+ bindcancel?: Function,
12
+ bindchange: Function,
13
+ // mode 为 selector 或 multiSelector 时,range 有效
14
+ range: Array<number|string|Obj>,
15
+ // 当 range 是一个 Object Array 时,通过 range-key 来指定 Object 中 key 的值作为选择器《显示内容》 对象中的属性
16
+ 'range-key': string,
17
+ getInnerLayout: Function
18
+ // bindcolumnchange?: Function
19
+ }
20
+
21
+ export type MultiSelectorProps = {
22
+ mode: string,
23
+ // 表示选择了 range 中的第几个(下标从 0 开始)
24
+ value: Array<number>,
25
+ disabled?: boolean,
26
+ children: ReactNode,
27
+ bindcancel?: Function,
28
+ bindchange: Function,
29
+ bindcolumnchange?: Function,
30
+ // mode 为 selector 或 multiSelector 时,range 有效
31
+ range: Array<Array<any>>,
32
+ // 当 range 是一个 Object Array 时,通过 range-key 来指定 Object 中 key 的值作为选择器《显示内容》 对象中的属性
33
+ 'range-key': string,
34
+ getInnerLayout: Function
35
+ }
36
+
37
+ export type TimeProps = {
38
+ mode: string,
39
+ // 表示选择了 range 中的第几个(下标从 0 开始)
40
+ value: string,
41
+ disabled?: boolean,
42
+ children: ReactNode,
43
+ bindcancel?: Function,
44
+ bindchange: Function,
45
+ start: string,
46
+ end: string,
47
+ getInnerLayout: Function
48
+ }
49
+
50
+ export type DateProps = {
51
+ mode: string,
52
+ // 表示选择了 range 中的第几个(下标从 0 开始)
53
+ value: string,
54
+ fields?: 'day' | 'month' | 'year',
55
+ disabled?: boolean,
56
+ children: ReactNode,
57
+ bindcancel?: Function,
58
+ bindchange: Function,
59
+ start: string,
60
+ end: string,
61
+ getInnerLayout: Function
62
+ }
63
+
64
+ export type RegionProps = {
65
+ mode: string,
66
+ // 表示选择了 range 中的第几个(下标从 0 开始)
67
+ value: Array<string>,
68
+ level: 'province' | 'city' | 'region' | 'sub-district'
69
+ 'custom-item'?: string,
70
+ disabled?: boolean,
71
+ children: ReactNode,
72
+ bindcancel?: Function,
73
+ bindchange: Function,
74
+ getInnerLayout: Function
75
+ }
76
+
77
+ export type RegionObj = {
78
+ value: string,
79
+ code: string
80
+ postcode?: string
81
+ children?: RegionObj[]
82
+ }
83
+
84
+ export type PickerData = {
85
+ value: string,
86
+ label: string,
87
+ children?: Array<Object>
88
+ }
89
+
90
+ export type EventType = {
91
+ detail: {
92
+ value: PickerValue[]
93
+ }
94
+ }
95
+
96
+ export type LayoutType = {
97
+ nativeEvent: {
98
+ layout: Obj
99
+ }
100
+ }
101
+
102
+ type FormType = {
103
+ name: string
104
+ }
105
+
106
+ export type PickerProps = SelectorProps & MultiSelectorProps & TimeProps & DateProps & RegionProps & FormType
107
+ export type ValueType = string | number | Array<number> | Array<string>
@@ -0,0 +1,28 @@
1
+
2
+ import { View } from 'react-native'
3
+ import React, { forwardRef, useRef } from 'react'
4
+ import useInnerProps from './getInnerListeners'
5
+ import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
6
+
7
+ interface ColumnProps {
8
+ children: React.ReactNode
9
+ }
10
+
11
+ const _PickerViewColumn = forwardRef<HandlerRef<View, ColumnProps>, ColumnProps>((props: ColumnProps, ref) => {
12
+ const { children } = props
13
+ const layoutRef = useRef({})
14
+ const { nodeRef } = useNodesRef(props, ref, {})
15
+ const innerProps = useInnerProps(props, {}, [], { layoutRef })
16
+ return (
17
+ <View
18
+ ref={nodeRef}
19
+ {...innerProps}>
20
+ {children}
21
+ </View>
22
+ )
23
+ })
24
+
25
+ _PickerViewColumn.displayName = 'mpx-picker-view-column';
26
+
27
+ export default _PickerViewColumn
28
+
@@ -0,0 +1,104 @@
1
+ import { View } from 'react-native'
2
+ import React, { forwardRef, useState, useRef, useEffect } from 'react'
3
+ import { PickerView } from '@ant-design/react-native'
4
+ import useInnerProps from './getInnerListeners'
5
+ import { getCustomEvent } from './getInnerListeners'
6
+ import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
7
+ /**
8
+ * ✔ value
9
+ * ✔ bindchange
10
+ * ✘ bindpickstart
11
+ * ✘ bindpickend
12
+ * ✘ mask-class
13
+ * ✘ indicator-style
14
+ * ✘ indicator-class
15
+ * ✘ mask-style
16
+ * ✘ immediate-change
17
+ */
18
+
19
+ interface PickerViewProps {
20
+ children: React.ReactNode
21
+ // 初始的defaultValue数组中的数字依次表示 picker-view 内的 picker-view-column 选择的第几项(下标从 0 开始),数字大于 picker-view-column 可选项长度时,选择最后一项。
22
+ value?: Array<number>
23
+ bindchange?: Function
24
+ }
25
+
26
+ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProps>((props: PickerViewProps, ref) => {
27
+ const { children, ...restProps } = props
28
+ const layoutRef = useRef({})
29
+ const { nodeRef } = useNodesRef(props, ref, {})
30
+ const [value, setValue] = useState(props.value)
31
+ useEffect(() => {
32
+ // 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
33
+ setValue(props.value)
34
+ }, [props.value]);
35
+
36
+ const onLayout = () => {
37
+ nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
38
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
39
+ })
40
+ }
41
+ const innerProps = useInnerProps(props, {}, [], { layoutRef })
42
+
43
+
44
+ const onChange = (val: Array<number>): void => {
45
+ const eventData = getCustomEvent('change', {}, { detail: {value: val, source: 'touch' }, layoutRef: layoutRef })
46
+ setValue(val)
47
+ props.bindchange && props.bindchange(eventData)
48
+ }
49
+
50
+ const joinString = (data: string | any[] | React.ReactElement): string => {
51
+ return (Array.isArray(data) ? data : [data]).join('')
52
+ }
53
+
54
+ const getLabelFromChildren = (child: React.ReactElement): string => {
55
+ return child.props && child.props.children ? getLabelFromChildren(child.props.children) : joinString(child)
56
+ }
57
+
58
+ const handleChildren = (children: React.ReactNode[]): any[] => {
59
+ return children.map((child: any, index: number) => {
60
+ return {
61
+ label: getLabelFromChildren(child),
62
+ value: index
63
+ }
64
+ })
65
+ }
66
+
67
+ const getDataFromChildren = (children: React.ReactNode): any[] => {
68
+ return (Array.isArray(children) ? children : [children]).map((child: any) => {
69
+ return handleChildren(child.props && child.props.children ? child.props.children : [child])
70
+ })
71
+ }
72
+
73
+ const columns = Array.isArray(children) ? children.length : 1
74
+ const originData = getDataFromChildren(children)
75
+ // 子节点默认的序号,这里是更新默认值的
76
+ const subChildLength = originData.map((item) => {
77
+ return item.length
78
+ })
79
+ const defaultValue = (props.value || []).map((item, index) => {
80
+ if (item > subChildLength[index]) {
81
+ return subChildLength[index] - 1
82
+ } else {
83
+ return item
84
+ }
85
+ })
86
+
87
+ return (
88
+ <PickerView
89
+ {...restProps}
90
+ cols={columns}
91
+ // 默认选中项
92
+ defaultValue={defaultValue}
93
+ // 内部维护选中项
94
+ value={value}
95
+ // data数据源column
96
+ data={originData}
97
+ onChange={onChange}
98
+ cascade={false}/>
99
+ )
100
+ })
101
+
102
+ _PickerView.displayName = 'mpx-picker-view';
103
+
104
+ export default _PickerView