@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.
- package/lib/platform/style/wx/index.js +314 -254
- package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
- package/lib/platform/template/wx/component-config/checkbox.js +8 -0
- package/lib/platform/template/wx/component-config/cover-image.js +15 -0
- package/lib/platform/template/wx/component-config/cover-view.js +9 -0
- package/lib/platform/template/wx/component-config/form.js +13 -1
- package/lib/platform/template/wx/component-config/icon.js +8 -0
- package/lib/platform/template/wx/component-config/index.js +5 -1
- package/lib/platform/template/wx/component-config/label.js +15 -0
- package/lib/platform/template/wx/component-config/movable-area.js +18 -1
- package/lib/platform/template/wx/component-config/movable-view.js +18 -1
- package/lib/platform/template/wx/component-config/navigator.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view.js +18 -2
- package/lib/platform/template/wx/component-config/picker.js +14 -1
- package/lib/platform/template/wx/component-config/radio-group.js +8 -0
- package/lib/platform/template/wx/component-config/radio.js +8 -0
- package/lib/platform/template/wx/component-config/root-portal.js +15 -0
- package/lib/platform/template/wx/component-config/switch.js +8 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -3
- package/lib/react/processScript.js +2 -0
- package/lib/runtime/components/react/context.ts +38 -0
- package/lib/runtime/components/react/dist/context.js +7 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +22 -11
- package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
- package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
- package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
- package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
- package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
- package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
- package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
- package/lib/runtime/components/react/dist/types/common.js +1 -0
- package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
- package/lib/runtime/components/react/dist/utils.js +82 -14
- package/lib/runtime/components/react/getInnerListeners.ts +25 -13
- package/lib/runtime/components/react/mpx-button.tsx +87 -67
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
- package/lib/runtime/components/react/mpx-form.tsx +89 -0
- package/lib/runtime/components/react/mpx-icon.tsx +103 -0
- package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
- package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
- package/lib/runtime/components/react/mpx-input.tsx +54 -26
- package/lib/runtime/components/react/mpx-label.tsx +115 -0
- package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
- package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
- package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
- package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
- package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
- package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
- package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
- package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
- package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
- package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
- package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-radio.tsx +246 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
- package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
- package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
- package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
- package/lib/runtime/components/react/mpx-switch.tsx +127 -0
- package/lib/runtime/components/react/mpx-text.tsx +52 -68
- package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
- package/lib/runtime/components/react/mpx-view.tsx +373 -140
- package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
- package/lib/runtime/components/react/types/common.ts +12 -0
- package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
- package/lib/runtime/components/react/types/global.d.ts +4 -0
- package/lib/runtime/components/react/useNodesRef.ts +3 -8
- package/lib/runtime/components/react/utils.ts +93 -15
- package/lib/runtime/optionProcessor.js +19 -17
- package/lib/template-compiler/compiler.js +56 -41
- package/lib/template-compiler/gen-node-react.js +7 -7
- 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
|