@mpxjs/webpack-plugin 2.9.69-beta.0 → 2.9.69-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +17 -1
- package/lib/platform/style/wx/index.js +18 -18
- package/lib/platform/template/wx/component-config/movable-view.js +8 -1
- package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
- package/lib/resolver/AddEnvPlugin.js +1 -0
- package/lib/resolver/AddModePlugin.js +1 -0
- package/lib/runtime/components/react/context.ts +8 -0
- package/lib/runtime/components/react/dist/context.js +2 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +3 -4
- package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +54 -52
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +21 -6
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +25 -8
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +150 -148
- package/lib/runtime/components/react/dist/mpx-view.jsx +9 -40
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +50 -12
- package/lib/runtime/components/react/dist/pickerFaces.js +1 -1
- package/lib/runtime/components/react/dist/useAnimationHooks.js +1 -1
- package/lib/runtime/components/react/dist/utils.jsx +63 -4
- package/lib/runtime/components/react/getInnerListeners.ts +3 -5
- package/lib/runtime/components/react/mpx-input.tsx +1 -1
- package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +177 -159
- package/lib/runtime/components/react/mpx-picker-view.tsx +35 -37
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
- package/lib/runtime/components/react/mpx-scroll-view.tsx +30 -13
- package/lib/runtime/components/react/mpx-swiper-item.tsx +38 -10
- package/lib/runtime/components/react/mpx-swiper.tsx +690 -0
- package/lib/runtime/components/react/mpx-view.tsx +11 -51
- package/lib/runtime/components/react/mpx-web-view.tsx +57 -13
- package/lib/runtime/components/react/pickerFaces.ts +15 -7
- package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
- package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
- package/lib/runtime/components/react/{pickerOverlay.tsx → pickerViewOverlay.tsx} +5 -3
- package/lib/runtime/components/react/types/global.d.ts +3 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +1 -1
- package/lib/runtime/components/react/utils.tsx +75 -5
- package/lib/style-compiler/index.js +3 -4
- package/lib/style-compiler/strip-conditional-loader.js +118 -0
- package/lib/template-compiler/compiler.js +9 -14
- package/lib/utils/pre-process-json.js +5 -9
- package/package.json +1 -1
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
- package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
- package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { useTransformStyle, splitStyle, splitProps,
|
|
1
|
+
import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react'
|
|
2
|
+
import { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, SafeAreaView, ScrollView, StyleSheet, View } from 'react-native'
|
|
3
|
+
import Reanimated, { AnimatedRef, useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'
|
|
4
|
+
import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, useDebounceCallback, useStableCallback, isIOS } from './utils'
|
|
5
5
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import PickerOverlay from './pickerViewOverlay'
|
|
7
|
+
import PickerMask from './pickerViewMask'
|
|
8
|
+
import MpxPickerVIewColumnItem from './mpx-picker-view-column-item'
|
|
9
|
+
import { PickerViewColumnAnimationContext } from './pickerVIewContext'
|
|
8
10
|
|
|
9
11
|
interface ColumnProps {
|
|
10
12
|
children?: React.ReactNode
|
|
11
13
|
columnData: React.ReactNode[]
|
|
14
|
+
columnStyle: Record<string, any>
|
|
12
15
|
initialIndex: number
|
|
13
|
-
onColumnItemRawHChange: Function
|
|
14
|
-
getInnerLayout: Function
|
|
15
16
|
onSelectChange: Function
|
|
16
17
|
style: {
|
|
17
18
|
[key: string]: any
|
|
@@ -22,25 +23,23 @@ interface ColumnProps {
|
|
|
22
23
|
height: number
|
|
23
24
|
itemHeight: number
|
|
24
25
|
}
|
|
26
|
+
pickerMaskStyle: Record<string, any>
|
|
25
27
|
pickerOverlayStyle: Record<string, any>
|
|
26
28
|
columnIndex: number
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
// 默认的单个选项高度
|
|
30
|
-
const DefaultPickerItemH = 36
|
|
31
|
-
// 默认一屏可见选项个数
|
|
32
31
|
const visibleCount = 5
|
|
33
32
|
|
|
34
33
|
const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>, ColumnProps>((props: ColumnProps, ref) => {
|
|
35
34
|
const {
|
|
36
35
|
columnData,
|
|
37
36
|
columnIndex,
|
|
37
|
+
columnStyle,
|
|
38
38
|
initialIndex,
|
|
39
39
|
onSelectChange,
|
|
40
|
-
onColumnItemRawHChange,
|
|
41
|
-
getInnerLayout,
|
|
42
40
|
style,
|
|
43
41
|
wrapperStyle,
|
|
42
|
+
pickerMaskStyle,
|
|
44
43
|
pickerOverlayStyle,
|
|
45
44
|
'enable-var': enableVar,
|
|
46
45
|
'external-var-context': externalVarContext
|
|
@@ -54,27 +53,42 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
54
53
|
setWidth,
|
|
55
54
|
setHeight
|
|
56
55
|
} = useTransformStyle(style, { enableVar, externalVarContext })
|
|
57
|
-
const { textStyle } = splitStyle(
|
|
56
|
+
const { textStyle: textStyleFromParent = {} } = splitStyle(columnStyle)
|
|
57
|
+
const { textStyle = {} } = splitStyle(normalStyle)
|
|
58
58
|
const { textProps } = splitProps(props)
|
|
59
|
-
const scrollViewRef =
|
|
59
|
+
const scrollViewRef = useAnimatedRef<Reanimated.ScrollView>()
|
|
60
|
+
const offsetYShared = useScrollViewOffset(scrollViewRef as AnimatedRef<Reanimated.ScrollView>)
|
|
60
61
|
|
|
61
|
-
useNodesRef(props, ref, scrollViewRef
|
|
62
|
+
useNodesRef(props, ref, scrollViewRef as AnimatedRef<ScrollView>, {
|
|
62
63
|
style: normalStyle
|
|
63
64
|
})
|
|
64
65
|
|
|
65
|
-
const { height: pickerH, itemHeight
|
|
66
|
-
const [itemRawH, setItemRawH] = useState(
|
|
66
|
+
const { height: pickerH, itemHeight } = wrapperStyle
|
|
67
|
+
const [itemRawH, setItemRawH] = useState(itemHeight)
|
|
67
68
|
const maxIndex = useMemo(() => columnData.length - 1, [columnData])
|
|
69
|
+
const prevScrollingInfo = useRef({ index: initialIndex, y: 0 })
|
|
68
70
|
const touching = useRef(false)
|
|
69
71
|
const scrolling = useRef(false)
|
|
70
72
|
const activeIndex = useRef(initialIndex)
|
|
71
73
|
const prevIndex = usePrevious(initialIndex)
|
|
72
74
|
const prevMaxIndex = usePrevious(maxIndex)
|
|
73
75
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
const {
|
|
77
|
+
layoutProps
|
|
78
|
+
} = useLayout({
|
|
79
|
+
props,
|
|
80
|
+
hasSelfPercent,
|
|
81
|
+
setWidth,
|
|
82
|
+
setHeight,
|
|
83
|
+
nodeRef: scrollViewRef
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
|
|
87
|
+
|
|
88
|
+
const paddingHeight = useMemo(
|
|
89
|
+
() => Math.round((pickerH - itemHeight) / 2),
|
|
90
|
+
[pickerH, itemHeight]
|
|
91
|
+
)
|
|
78
92
|
|
|
79
93
|
const snapToOffsets = useMemo(
|
|
80
94
|
() => columnData.map((_, i) => i * itemRawH),
|
|
@@ -82,12 +96,34 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
82
96
|
)
|
|
83
97
|
|
|
84
98
|
const contentContainerStyle = useMemo(() => {
|
|
85
|
-
return [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
return [{ paddingVertical: paddingHeight }]
|
|
100
|
+
}, [paddingHeight])
|
|
101
|
+
|
|
102
|
+
const getIndex = useCallback((y: number) => {
|
|
103
|
+
const calc = Math.round(y / itemRawH)
|
|
104
|
+
return Math.max(0, Math.min(calc, maxIndex))
|
|
105
|
+
}, [itemRawH, maxIndex])
|
|
106
|
+
|
|
107
|
+
const getYofIndex = useCallback((index: number) => {
|
|
108
|
+
return index * itemRawH
|
|
109
|
+
}, [itemRawH])
|
|
110
|
+
|
|
111
|
+
const stableResetScrollPosition = useStableCallback((y: number) => {
|
|
112
|
+
console.log('[mpx-picker-view-column], reset --->', 'columnIndex=', columnIndex, 'y=', y, touching.current, scrolling.current)
|
|
113
|
+
if (touching.current || scrolling.current) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
// needReset.current = true
|
|
117
|
+
if (y % itemRawH !== 0) {
|
|
118
|
+
scrolling.current = true
|
|
119
|
+
const targetIndex = getIndex(y)
|
|
120
|
+
const targetY = getYofIndex(targetIndex)
|
|
121
|
+
scrollViewRef.current?.scrollTo({ x: 0, y: targetY, animated: false })
|
|
122
|
+
} else {
|
|
123
|
+
onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } })
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
const debounceResetScrollPosition = useDebounceCallback(stableResetScrollPosition, 10)
|
|
91
127
|
|
|
92
128
|
useEffect(() => {
|
|
93
129
|
if (
|
|
@@ -102,188 +138,170 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
102
138
|
) {
|
|
103
139
|
return
|
|
104
140
|
}
|
|
105
|
-
|
|
141
|
+
setTimeout(() => {
|
|
142
|
+
scrollViewRef.current?.scrollTo({
|
|
143
|
+
x: 0,
|
|
144
|
+
y: getYofIndex(initialIndex),
|
|
145
|
+
animated: false
|
|
146
|
+
})
|
|
147
|
+
}, isAndroid ? 200 : 0)
|
|
106
148
|
activeIndex.current = initialIndex
|
|
107
|
-
scrollViewRef.current.scrollTo({
|
|
108
|
-
x: 0,
|
|
109
|
-
y: itemRawH * initialIndex,
|
|
110
|
-
animated: false
|
|
111
|
-
})
|
|
112
149
|
}, [itemRawH, initialIndex])
|
|
113
150
|
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
} = useLayout({
|
|
122
|
-
props,
|
|
123
|
-
hasSelfPercent,
|
|
124
|
-
setWidth,
|
|
125
|
-
setHeight,
|
|
126
|
-
nodeRef: scrollViewRef,
|
|
127
|
-
onLayout: onScrollViewLayout
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
const onContentSizeChange = (w: number, h: number) => {
|
|
131
|
-
scrollViewRef.current?.scrollTo({
|
|
132
|
-
x: 0,
|
|
133
|
-
y: itemRawH * initialIndex,
|
|
134
|
-
animated: false
|
|
135
|
-
})
|
|
151
|
+
const onContentSizeChange = (_w: number, h: number) => {
|
|
152
|
+
const y = getYofIndex(initialIndex)
|
|
153
|
+
if (y <= h) {
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
scrollViewRef.current?.scrollTo({ x: 0, y, animated: false })
|
|
156
|
+
}, 0)
|
|
157
|
+
}
|
|
136
158
|
}
|
|
137
159
|
|
|
138
160
|
const onItemLayout = (e: LayoutChangeEvent) => {
|
|
139
161
|
const { height: rawH } = e.nativeEvent.layout
|
|
140
162
|
if (rawH && itemRawH !== rawH) {
|
|
141
163
|
setItemRawH(rawH)
|
|
142
|
-
onColumnItemRawHChange(rawH)
|
|
143
164
|
}
|
|
144
165
|
}
|
|
145
166
|
|
|
146
|
-
const
|
|
167
|
+
const onScrollBeginDrag = () => {
|
|
168
|
+
isIOS && debounceResetScrollPosition.clear()
|
|
147
169
|
touching.current = true
|
|
170
|
+
prevScrollingInfo.current = {
|
|
171
|
+
index: activeIndex.current,
|
|
172
|
+
y: getYofIndex(activeIndex.current)
|
|
173
|
+
}
|
|
148
174
|
}
|
|
149
175
|
|
|
150
|
-
const
|
|
151
|
-
touching.current = false
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const onTouchCancel = () => {
|
|
176
|
+
const onScrollEndDrag = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
155
177
|
touching.current = false
|
|
178
|
+
const { y } = e.nativeEvent.contentOffset
|
|
179
|
+
if (isIOS) {
|
|
180
|
+
if (y > 0 && y < snapToOffsets[maxIndex]) {
|
|
181
|
+
debounceResetScrollPosition(y)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
156
184
|
}
|
|
157
185
|
|
|
158
186
|
const onMomentumScrollBegin = () => {
|
|
187
|
+
isIOS && debounceResetScrollPosition.clear()
|
|
159
188
|
scrolling.current = true
|
|
160
189
|
}
|
|
161
190
|
|
|
162
|
-
const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
191
|
+
const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent> | { nativeEvent: { contentOffset: { y: number } } }) => {
|
|
163
192
|
scrolling.current = false
|
|
164
|
-
if (!itemRawH) {
|
|
165
|
-
return
|
|
166
|
-
}
|
|
167
193
|
const { y: scrollY } = e.nativeEvent.contentOffset
|
|
168
|
-
|
|
194
|
+
if (isIOS && scrollY % itemRawH !== 0) {
|
|
195
|
+
return debounceResetScrollPosition(scrollY)
|
|
196
|
+
}
|
|
197
|
+
const calcIndex = getIndex(scrollY)
|
|
169
198
|
activeIndex.current = calcIndex
|
|
170
199
|
if (calcIndex !== initialIndex) {
|
|
171
|
-
calcIndex = Math.max(0, Math.min(calcIndex, maxIndex)) || 0
|
|
172
200
|
onSelectChange(calcIndex)
|
|
173
201
|
}
|
|
174
202
|
}
|
|
175
203
|
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
inputRange: inputRange,
|
|
199
|
-
outputRange: faces.map((x) => `${x.deg}deg`),
|
|
200
|
-
extrapolate: 'extend'
|
|
201
|
-
}),
|
|
202
|
-
translateY: offsetY.interpolate({
|
|
203
|
-
inputRange: inputRange,
|
|
204
|
-
outputRange: faces.map((x) => x.offsetY),
|
|
205
|
-
extrapolate: 'extend'
|
|
206
|
-
})
|
|
204
|
+
const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
205
|
+
const { y } = e.nativeEvent.contentOffset
|
|
206
|
+
if (isAndroid) {
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
// 全局注册的震动触感 hook
|
|
210
|
+
const pickerVibrate = global.__mpx.config.rnConfig.pickerVibrate
|
|
211
|
+
if (typeof pickerVibrate !== 'function') {
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
const { index: prevIndex, y: _y } = prevScrollingInfo.current
|
|
215
|
+
if (touching.current || scrolling.current) {
|
|
216
|
+
if (Math.abs(y - _y) >= itemRawH) {
|
|
217
|
+
const currentId = getIndex(y)
|
|
218
|
+
if (currentId !== prevIndex) {
|
|
219
|
+
prevScrollingInfo.current = {
|
|
220
|
+
index: currentId,
|
|
221
|
+
y: getYofIndex(currentId)
|
|
222
|
+
}
|
|
223
|
+
// vibrateShort({ type: 'selection' })
|
|
224
|
+
pickerVibrate()
|
|
225
|
+
}
|
|
207
226
|
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
211
229
|
|
|
212
230
|
const renderInnerchild = () =>
|
|
213
|
-
columnData.map((item: React.
|
|
214
|
-
const InnerProps = index === 0 ? { onLayout: onItemLayout } : {}
|
|
215
|
-
const strKey = `picker-column-${columnIndex}-${index}`
|
|
216
|
-
const { opacity, rotateX, translateY } = getTransform(index)
|
|
231
|
+
columnData.map((item: React.ReactElement, index: number) => {
|
|
217
232
|
return (
|
|
218
|
-
<
|
|
219
|
-
key={
|
|
220
|
-
{
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
]}
|
|
233
|
-
>
|
|
234
|
-
{wrapChildren(
|
|
235
|
-
{ children: item },
|
|
236
|
-
{
|
|
237
|
-
hasVarDec,
|
|
238
|
-
varContext: varContextRef.current,
|
|
239
|
-
textStyle,
|
|
240
|
-
textProps
|
|
241
|
-
}
|
|
242
|
-
)}
|
|
243
|
-
</Animated.View>
|
|
233
|
+
<MpxPickerVIewColumnItem
|
|
234
|
+
key={index}
|
|
235
|
+
item={item}
|
|
236
|
+
index={index}
|
|
237
|
+
itemHeight={itemHeight}
|
|
238
|
+
textStyleFromParent={textStyleFromParent}
|
|
239
|
+
textStyle={textStyle}
|
|
240
|
+
hasVarDec={hasVarDec}
|
|
241
|
+
varContext={varContextRef.current}
|
|
242
|
+
textProps={textProps}
|
|
243
|
+
visibleCount={visibleCount}
|
|
244
|
+
onItemLayout={onItemLayout}
|
|
245
|
+
/>
|
|
244
246
|
)
|
|
245
247
|
})
|
|
246
248
|
|
|
247
249
|
const renderScollView = () => {
|
|
248
250
|
return (
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
251
|
+
<PickerViewColumnAnimationContext.Provider value={offsetYShared}>
|
|
252
|
+
<Reanimated.ScrollView
|
|
253
|
+
ref={scrollViewRef}
|
|
254
|
+
bounces={true}
|
|
255
|
+
horizontal={false}
|
|
256
|
+
nestedScrollEnabled={true}
|
|
257
|
+
removeClippedSubviews={false}
|
|
258
|
+
showsVerticalScrollIndicator={false}
|
|
259
|
+
showsHorizontalScrollIndicator={false}
|
|
260
|
+
scrollEventThrottle={16}
|
|
261
|
+
{...layoutProps}
|
|
262
|
+
style={[{ width: '100%' }]}
|
|
263
|
+
decelerationRate="fast"
|
|
264
|
+
snapToOffsets={snapToOffsets}
|
|
265
|
+
onScroll={onScroll}
|
|
266
|
+
onScrollBeginDrag={onScrollBeginDrag}
|
|
267
|
+
onScrollEndDrag={onScrollEndDrag}
|
|
268
|
+
onMomentumScrollBegin={onMomentumScrollBegin}
|
|
269
|
+
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
270
|
+
onContentSizeChange={onContentSizeChange}
|
|
271
|
+
contentContainerStyle={contentContainerStyle}
|
|
272
|
+
>
|
|
273
|
+
{renderInnerchild()}
|
|
274
|
+
</Reanimated.ScrollView>
|
|
275
|
+
</PickerViewColumnAnimationContext.Provider>
|
|
273
276
|
)
|
|
274
277
|
}
|
|
275
278
|
|
|
276
279
|
const renderOverlay = () => (
|
|
277
|
-
<PickerOverlay
|
|
280
|
+
<PickerOverlay
|
|
281
|
+
itemHeight={itemHeight}
|
|
282
|
+
overlayItemStyle={pickerOverlayStyle}
|
|
283
|
+
/>
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
const renderMask = () => (
|
|
287
|
+
<PickerMask
|
|
288
|
+
itemHeight={itemHeight}
|
|
289
|
+
maskContainerStyle={pickerMaskStyle}
|
|
290
|
+
/>
|
|
278
291
|
)
|
|
279
292
|
|
|
280
293
|
return (
|
|
281
|
-
<SafeAreaView style={[
|
|
294
|
+
<SafeAreaView style={[styles.wrapper, normalStyle]}>
|
|
282
295
|
{renderScollView()}
|
|
296
|
+
{renderMask()}
|
|
283
297
|
{renderOverlay()}
|
|
284
298
|
</SafeAreaView>
|
|
285
299
|
)
|
|
286
300
|
})
|
|
287
301
|
|
|
302
|
+
const styles = StyleSheet.create({
|
|
303
|
+
wrapper: { display: 'flex', flex: 1 }
|
|
304
|
+
})
|
|
305
|
+
|
|
288
306
|
_PickerViewColumn.displayName = 'MpxPickerViewColumn'
|
|
289
307
|
export default _PickerViewColumn
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { View } from 'react-native'
|
|
2
|
-
import React, { forwardRef,
|
|
2
|
+
import React, { forwardRef, useRef } from 'react'
|
|
3
3
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
4
4
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
5
5
|
import {
|
|
@@ -9,8 +9,6 @@ import {
|
|
|
9
9
|
wrapChildren,
|
|
10
10
|
parseInlineStyle,
|
|
11
11
|
useTransformStyle,
|
|
12
|
-
useDebounceCallback,
|
|
13
|
-
useStableCallback,
|
|
14
12
|
extendObject
|
|
15
13
|
} from './utils'
|
|
16
14
|
import type { AnyFunc } from './types/common'
|
|
@@ -21,21 +19,21 @@ import type { AnyFunc } from './types/common'
|
|
|
21
19
|
* ✘ bindpickend
|
|
22
20
|
* ✘ mask-class
|
|
23
21
|
* ✔ indicator-style: 优先级indicator-style.height > pick-view-column中的子元素设置的height
|
|
22
|
+
* WebView Only:
|
|
24
23
|
* ✘ indicator-class
|
|
25
|
-
*
|
|
24
|
+
* ✔ mask-style
|
|
26
25
|
* ✘ immediate-change
|
|
27
26
|
*/
|
|
28
27
|
|
|
29
28
|
interface PickerViewProps {
|
|
30
29
|
children: React.ReactNode
|
|
31
|
-
// 初始的defaultValue数组中的数字依次表示 picker-view 内的 picker-view-column 选择的第几项(下标从 0 开始),
|
|
32
|
-
// 数字大于 picker-view-column 可选项长度时,选择最后一项。
|
|
33
30
|
value?: Array<number>
|
|
34
31
|
bindchange?: AnyFunc
|
|
35
32
|
style: {
|
|
36
33
|
[key: string]: any
|
|
37
34
|
}
|
|
38
35
|
'indicator-style'?: string
|
|
36
|
+
'mask-style'?: string
|
|
39
37
|
'enable-var': boolean
|
|
40
38
|
'external-var-context'?: Record<string, any>,
|
|
41
39
|
'enable-offset': boolean
|
|
@@ -62,6 +60,8 @@ const styles: { [key: string]: Object } = {
|
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
63
|
+
const DefaultPickerItemH = 36
|
|
64
|
+
|
|
65
65
|
const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProps>((props: PickerViewProps, ref) => {
|
|
66
66
|
const {
|
|
67
67
|
children,
|
|
@@ -71,16 +71,16 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
71
71
|
'enable-var': enableVar,
|
|
72
72
|
'external-var-context': externalVarContext
|
|
73
73
|
} = props
|
|
74
|
-
|
|
75
|
-
// indicatorStyle 需要转换为rn的style
|
|
76
|
-
// 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
|
|
77
74
|
const indicatorStyle = parseInlineStyle(props['indicator-style'])
|
|
75
|
+
const pickerMaskStyle = parseInlineStyle(props['mask-style'])
|
|
78
76
|
const { height: indicatorH, ...pickerOverlayStyle } = indicatorStyle
|
|
79
|
-
const [pickMaxH, setPickMaxH] = useState(0)
|
|
80
77
|
const nodeRef = useRef(null)
|
|
81
78
|
const cloneRef = useRef(null)
|
|
82
79
|
const activeValueRef = useRef(value)
|
|
83
80
|
activeValueRef.current = value.slice()
|
|
81
|
+
const snapActiveValueRef = useRef<number[] | null>(null)
|
|
82
|
+
|
|
83
|
+
console.log('[mpx-picker-view] value=', value, Date.now())
|
|
84
84
|
|
|
85
85
|
const {
|
|
86
86
|
normalStyle,
|
|
@@ -96,7 +96,6 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
96
96
|
})
|
|
97
97
|
|
|
98
98
|
const {
|
|
99
|
-
// 存储layout布局信息
|
|
100
99
|
layoutRef,
|
|
101
100
|
layoutProps,
|
|
102
101
|
layoutStyle
|
|
@@ -104,33 +103,34 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
104
103
|
const { textProps } = splitProps(props)
|
|
105
104
|
const { textStyle } = splitStyle(normalStyle)
|
|
106
105
|
|
|
107
|
-
const onColumnItemRawHChange = (height: number) => {
|
|
108
|
-
if (height > pickMaxH) {
|
|
109
|
-
setPickMaxH(height)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const bindchangeDebounce = useDebounceCallback(useStableCallback(bindchange), 300)
|
|
114
|
-
|
|
115
106
|
const onSelectChange = (columnIndex: number, selectedIndex: number) => {
|
|
116
|
-
bindchangeDebounce.clear()
|
|
117
107
|
const activeValue = activeValueRef.current
|
|
118
108
|
activeValue[columnIndex] = selectedIndex
|
|
109
|
+
console.log('[mpx-picker-view], onSelectChange ---> columnIndex=', columnIndex, 'selectedIndex=', selectedIndex, 'activeValue=', activeValue)
|
|
119
110
|
const eventData = getCustomEvent(
|
|
120
111
|
'change',
|
|
121
112
|
{},
|
|
122
113
|
{ detail: { value: activeValue, source: 'change' }, layoutRef }
|
|
123
114
|
)
|
|
124
|
-
|
|
115
|
+
bindchange?.(eventData)
|
|
116
|
+
snapActiveValueRef.current = activeValueRef.current
|
|
125
117
|
}
|
|
126
118
|
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
)
|
|
133
|
-
|
|
119
|
+
const hasDiff = (a: number[] = [], b: number[]) => {
|
|
120
|
+
return a.some((v, i) => v !== b[i])
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const onInitialChange = (isInvalid: boolean, value: number[]) => {
|
|
124
|
+
if (isInvalid || !snapActiveValueRef.current || hasDiff(snapActiveValueRef.current, value)) {
|
|
125
|
+
console.log('[mpx-picker-view], onInitialChange ===> value=', value)
|
|
126
|
+
const eventData = getCustomEvent(
|
|
127
|
+
'change',
|
|
128
|
+
{},
|
|
129
|
+
{ detail: { value, source: 'change' }, layoutRef }
|
|
130
|
+
)
|
|
131
|
+
bindchange?.(eventData)
|
|
132
|
+
snapActiveValueRef.current = value.slice()
|
|
133
|
+
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
const innerProps = useInnerProps(
|
|
@@ -153,7 +153,6 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
153
153
|
)
|
|
154
154
|
|
|
155
155
|
const renderColumn = (child: React.ReactElement, index: number, columnData: React.ReactNode[], initialIndex: number) => {
|
|
156
|
-
const extraProps = {}
|
|
157
156
|
const childProps = child?.props || {}
|
|
158
157
|
const wrappedProps = extendObject(
|
|
159
158
|
{},
|
|
@@ -164,15 +163,15 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
164
163
|
columnIndex: index,
|
|
165
164
|
key: `pick-view-${index}`,
|
|
166
165
|
wrapperStyle: {
|
|
167
|
-
height: normalStyle?.height ||
|
|
168
|
-
itemHeight: indicatorH ||
|
|
166
|
+
height: normalStyle?.height || DefaultPickerItemH,
|
|
167
|
+
itemHeight: indicatorH || DefaultPickerItemH
|
|
169
168
|
},
|
|
170
|
-
|
|
169
|
+
columnStyle: normalStyle,
|
|
171
170
|
onSelectChange: onSelectChange.bind(null, index),
|
|
172
171
|
initialIndex,
|
|
173
|
-
pickerOverlayStyle
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
pickerOverlayStyle,
|
|
173
|
+
pickerMaskStyle
|
|
174
|
+
}
|
|
176
175
|
)
|
|
177
176
|
const realElement = React.cloneElement(child, wrappedProps)
|
|
178
177
|
return wrapChildren(
|
|
@@ -215,7 +214,7 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
215
214
|
validValue.push(validIndex)
|
|
216
215
|
renderColumns.push(renderColumn(item, index, columnData, validIndex))
|
|
217
216
|
})
|
|
218
|
-
isInvalid
|
|
217
|
+
onInitialChange(isInvalid, validValue)
|
|
219
218
|
return renderColumns
|
|
220
219
|
}
|
|
221
220
|
|
|
@@ -227,5 +226,4 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
227
226
|
})
|
|
228
227
|
|
|
229
228
|
_PickerView.displayName = 'MpxPickerView'
|
|
230
|
-
|
|
231
229
|
export default _PickerView
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* ✔ nodes
|
|
4
4
|
*/
|
|
5
5
|
import { View, ViewProps, ViewStyle } from 'react-native'
|
|
6
|
-
import { useRef, forwardRef, JSX, useState } from 'react'
|
|
6
|
+
import { useRef, forwardRef, JSX, useState, createElement } from 'react'
|
|
7
7
|
import useInnerProps from '../getInnerListeners'
|
|
8
8
|
import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
|
|
9
|
-
import { useTransformStyle, useLayout } from '../utils'
|
|
9
|
+
import { useTransformStyle, useLayout, extendObject } from '../utils'
|
|
10
10
|
import { WebView, WebViewMessageEvent } from 'react-native-webview'
|
|
11
11
|
import { generateHTML } from './html'
|
|
12
12
|
|
|
@@ -91,28 +91,22 @@ const _RichText = forwardRef<HandlerRef<View, _RichTextProps>, _RichTextProps>((
|
|
|
91
91
|
layoutRef
|
|
92
92
|
})
|
|
93
93
|
|
|
94
|
-
const innerProps = useInnerProps(props, {
|
|
94
|
+
const innerProps = useInnerProps(props, extendObject({
|
|
95
95
|
ref: nodeRef,
|
|
96
|
-
style:
|
|
97
|
-
|
|
98
|
-
}, [], {
|
|
96
|
+
style: extendObject(normalStyle, layoutStyle)
|
|
97
|
+
}, layoutProps), [], {
|
|
99
98
|
layoutRef
|
|
100
99
|
})
|
|
101
100
|
|
|
102
101
|
const html: string = typeof nodes === 'string' ? nodes : jsonToHtmlStr(nodes)
|
|
103
102
|
|
|
104
|
-
return (
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
setWebViewHeight(+event.nativeEvent.data)
|
|
112
|
-
}}
|
|
113
|
-
>
|
|
114
|
-
</WebView>
|
|
115
|
-
</View>
|
|
103
|
+
return createElement(View, innerProps,
|
|
104
|
+
createElement(WebView, {
|
|
105
|
+
source: { html: generateHTML(html) },
|
|
106
|
+
onMessage: (event: WebViewMessageEvent) => {
|
|
107
|
+
setWebViewHeight(+event.nativeEvent.data)
|
|
108
|
+
}
|
|
109
|
+
})
|
|
116
110
|
)
|
|
117
111
|
})
|
|
118
112
|
|