@mpxjs/webpack-plugin 2.9.69-beta.1 → 2.9.69-beta.10
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/config.js +3 -1
- package/lib/platform/template/wx/index.js +3 -1
- package/lib/react/processScript.js +6 -4
- package/lib/runtime/components/react/context.ts +17 -0
- package/lib/runtime/components/react/dist/context.js +2 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +2 -2
- package/lib/runtime/components/react/dist/locale-provider.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
- package/lib/runtime/components/react/dist/mpx-image.jsx +13 -9
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +65 -61
- package/lib/runtime/components/react/dist/mpx-portal/portal-consumer.jsx +23 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +93 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +40 -0
- package/lib/runtime/components/react/dist/mpx-portal.jsx +13 -0
- package/lib/runtime/components/react/dist/mpx-provider.jsx +31 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +9 -5
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +13 -7
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +384 -321
- package/lib/runtime/components/react/dist/mpx-view.jsx +16 -20
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +129 -53
- package/lib/runtime/components/react/dist/pickerFaces.js +2 -7
- package/lib/runtime/components/react/dist/useAnimationHooks.js +30 -13
- package/lib/runtime/components/react/dist/utils.jsx +60 -2
- package/lib/runtime/components/react/getInnerListeners.ts +2 -2
- package/lib/runtime/components/react/locale-provider.tsx +83 -0
- package/lib/runtime/components/react/mpx-button.tsx +20 -57
- package/lib/runtime/components/react/mpx-image.tsx +41 -25
- package/lib/runtime/components/react/mpx-picker/time.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +3 -3
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +70 -69
- package/lib/runtime/components/react/mpx-portal/portal-consumer.tsx +32 -0
- package/lib/runtime/components/react/mpx-portal/portal-host.tsx +127 -0
- package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +64 -0
- package/lib/runtime/components/react/mpx-portal.tsx +30 -0
- package/lib/runtime/components/react/mpx-provider.tsx +51 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
- package/lib/runtime/components/react/mpx-scroll-view.tsx +10 -8
- package/lib/runtime/components/react/mpx-swiper-item.tsx +13 -7
- package/lib/runtime/components/react/mpx-swiper.tsx +378 -325
- package/lib/runtime/components/react/mpx-view.tsx +19 -22
- package/lib/runtime/components/react/mpx-web-view.tsx +170 -62
- package/lib/runtime/components/react/pickerFaces.ts +2 -7
- package/lib/runtime/components/react/types/global.d.ts +7 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +34 -14
- package/lib/runtime/components/react/utils.tsx +67 -2
- package/lib/template-compiler/compiler.js +1 -1
- package/lib/wxss/loader.js +15 -2
- package/package.json +1 -1
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* ✘ bindagreeprivacyauthorization
|
|
35
35
|
* ✔ bindtap
|
|
36
36
|
*/
|
|
37
|
-
import { createElement, useEffect, useRef,
|
|
37
|
+
import { createElement, useEffect, useRef, ReactNode, forwardRef, useContext, JSX } from 'react'
|
|
38
38
|
import {
|
|
39
39
|
View,
|
|
40
40
|
StyleSheet,
|
|
@@ -45,10 +45,12 @@ import {
|
|
|
45
45
|
NativeSyntheticEvent
|
|
46
46
|
} from 'react-native'
|
|
47
47
|
import { warn } from '@mpxjs/utils'
|
|
48
|
-
import {
|
|
48
|
+
import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
|
|
49
|
+
import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover } from './utils'
|
|
49
50
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
50
51
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
51
52
|
import { RouteContext, FormContext } from './context'
|
|
53
|
+
import type { ExtendedViewStyle } from './types/common'
|
|
52
54
|
|
|
53
55
|
export type Type = 'default' | 'primary' | 'warn'
|
|
54
56
|
|
|
@@ -68,7 +70,7 @@ export interface ButtonProps {
|
|
|
68
70
|
disabled?: boolean
|
|
69
71
|
loading?: boolean
|
|
70
72
|
'hover-class'?: string
|
|
71
|
-
'hover-style'?:
|
|
73
|
+
'hover-style'?: ExtendedViewStyle
|
|
72
74
|
'hover-start-time'?: number
|
|
73
75
|
'hover-stay-time'?: number
|
|
74
76
|
'open-type'?: OpenType
|
|
@@ -83,8 +85,6 @@ export interface ButtonProps {
|
|
|
83
85
|
children: ReactNode
|
|
84
86
|
bindgetuserinfo?: (userInfo: any) => void
|
|
85
87
|
bindtap?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
86
|
-
bindtouchstart?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
87
|
-
bindtouchend?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
const LOADING_IMAGE_URI =
|
|
@@ -216,15 +216,16 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
216
216
|
style = {},
|
|
217
217
|
children,
|
|
218
218
|
bindgetuserinfo,
|
|
219
|
-
bindtap
|
|
220
|
-
bindtouchstart,
|
|
221
|
-
bindtouchend
|
|
219
|
+
bindtap
|
|
222
220
|
} = props
|
|
223
221
|
|
|
224
222
|
const pageId = useContext(RouteContext)
|
|
225
223
|
|
|
226
224
|
const formContext = useContext(FormContext)
|
|
227
225
|
|
|
226
|
+
const enableHover = hoverClass !== 'none'
|
|
227
|
+
const { isHover, gesture } = useHover({ enableHover, hoverStartTime, hoverStayTime, disabled })
|
|
228
|
+
|
|
228
229
|
let submitFn: () => void | undefined
|
|
229
230
|
let resetFn: () => void | undefined
|
|
230
231
|
|
|
@@ -233,27 +234,15 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
233
234
|
resetFn = formContext.reset
|
|
234
235
|
}
|
|
235
236
|
|
|
236
|
-
const refs = useRef<{
|
|
237
|
-
hoverStartTimer: ReturnType<typeof setTimeout> | undefined
|
|
238
|
-
hoverStayTimer: ReturnType<typeof setTimeout> | undefined
|
|
239
|
-
}>({
|
|
240
|
-
hoverStartTimer: undefined,
|
|
241
|
-
hoverStayTimer: undefined
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
const [isHover, setIsHover] = useState(false)
|
|
245
|
-
|
|
246
237
|
const isMiniSize = size === 'mini'
|
|
247
238
|
|
|
248
|
-
const applyHoverEffect = isHover && hoverClass !== 'none'
|
|
249
|
-
|
|
250
239
|
const [color, hoverColor, plainColor, disabledColor] = TypeColorMap[type]
|
|
251
240
|
|
|
252
|
-
const normalBackgroundColor = disabled ? disabledColor :
|
|
241
|
+
const normalBackgroundColor = disabled ? disabledColor : isHover || loading ? hoverColor : color
|
|
253
242
|
|
|
254
243
|
const plainBorderColor = disabled
|
|
255
244
|
? 'rgba(0, 0, 0, .2)'
|
|
256
|
-
:
|
|
245
|
+
: isHover
|
|
257
246
|
? `rgba(${plainColor},.6)`
|
|
258
247
|
: `rgb(${plainColor})`
|
|
259
248
|
|
|
@@ -261,14 +250,14 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
261
250
|
|
|
262
251
|
const plainTextColor = disabled
|
|
263
252
|
? 'rgba(0, 0, 0, .2)'
|
|
264
|
-
:
|
|
253
|
+
: isHover
|
|
265
254
|
? `rgba(${plainColor}, .6)`
|
|
266
255
|
: `rgb(${plainColor})`
|
|
267
256
|
|
|
268
257
|
const normalTextColor =
|
|
269
258
|
type === 'default'
|
|
270
|
-
? `rgba(0, 0, 0, ${disabled ? 0.3 :
|
|
271
|
-
: `rgba(255 ,255 ,255 , ${disabled ||
|
|
259
|
+
? `rgba(0, 0, 0, ${disabled ? 0.3 : isHover || loading ? 0.6 : 1})`
|
|
260
|
+
: `rgba(255 ,255 ,255 , ${disabled || isHover || loading ? 0.6 : 1})`
|
|
272
261
|
|
|
273
262
|
const viewStyle = {
|
|
274
263
|
borderWidth: 1,
|
|
@@ -297,7 +286,7 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
297
286
|
{},
|
|
298
287
|
defaultStyle,
|
|
299
288
|
style,
|
|
300
|
-
|
|
289
|
+
isHover ? hoverStyle : {}
|
|
301
290
|
)
|
|
302
291
|
|
|
303
292
|
const {
|
|
@@ -366,34 +355,6 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
366
355
|
}
|
|
367
356
|
}
|
|
368
357
|
|
|
369
|
-
const setStayTimer = () => {
|
|
370
|
-
clearTimeout(refs.current.hoverStayTimer)
|
|
371
|
-
refs.current.hoverStayTimer = setTimeout(() => {
|
|
372
|
-
setIsHover(false)
|
|
373
|
-
clearTimeout(refs.current.hoverStayTimer)
|
|
374
|
-
}, hoverStayTime)
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const setStartTimer = () => {
|
|
378
|
-
clearTimeout(refs.current.hoverStartTimer)
|
|
379
|
-
refs.current.hoverStartTimer = setTimeout(() => {
|
|
380
|
-
setIsHover(true)
|
|
381
|
-
clearTimeout(refs.current.hoverStartTimer)
|
|
382
|
-
}, hoverStartTime)
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const onTouchStart = (evt: NativeSyntheticEvent<TouchEvent>) => {
|
|
386
|
-
bindtouchstart && bindtouchstart(evt)
|
|
387
|
-
if (disabled) return
|
|
388
|
-
setStartTimer()
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const onTouchEnd = (evt: NativeSyntheticEvent<TouchEvent>) => {
|
|
392
|
-
bindtouchend && bindtouchend(evt)
|
|
393
|
-
if (disabled) return
|
|
394
|
-
setStayTimer()
|
|
395
|
-
}
|
|
396
|
-
|
|
397
358
|
const handleFormTypeFn = () => {
|
|
398
359
|
if (formType === 'submit') {
|
|
399
360
|
submitFn && submitFn()
|
|
@@ -418,8 +379,6 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
418
379
|
},
|
|
419
380
|
layoutProps,
|
|
420
381
|
{
|
|
421
|
-
bindtouchstart: (bindtouchstart || !disabled) && onTouchStart,
|
|
422
|
-
bindtouchend: (bindtouchend || !disabled) && onTouchEnd,
|
|
423
382
|
bindtap: !disabled && onTap
|
|
424
383
|
}
|
|
425
384
|
),
|
|
@@ -442,7 +401,7 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
442
401
|
}
|
|
443
402
|
)
|
|
444
403
|
|
|
445
|
-
|
|
404
|
+
const baseButton = createElement(View, innerProps, loading && createElement(Loading, { alone: !children }),
|
|
446
405
|
wrapChildren(
|
|
447
406
|
props,
|
|
448
407
|
{
|
|
@@ -453,6 +412,10 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
|
|
|
453
412
|
}
|
|
454
413
|
)
|
|
455
414
|
)
|
|
415
|
+
|
|
416
|
+
return enableHover
|
|
417
|
+
? createElement(GestureDetector, { gesture: gesture as PanGesture }, baseButton)
|
|
418
|
+
: baseButton
|
|
456
419
|
})
|
|
457
420
|
|
|
458
421
|
Button.displayName = 'MpxButton'
|
|
@@ -403,32 +403,48 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
|
|
|
403
403
|
}
|
|
404
404
|
)
|
|
405
405
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
406
|
+
const createBaseImage = (innerProps = {}) => {
|
|
407
|
+
return renderImage(
|
|
408
|
+
extendObject(
|
|
409
|
+
{
|
|
410
|
+
source: { uri: src },
|
|
411
|
+
resizeMode: resizeMode,
|
|
412
|
+
onLoad: bindload && onImageLoad,
|
|
413
|
+
onError: binderror && onImageError,
|
|
414
|
+
style: extendObject(
|
|
415
|
+
{
|
|
416
|
+
transformOrigin: 'top left',
|
|
417
|
+
width: isCropMode ? imageWidth : '100%',
|
|
418
|
+
height: isCropMode ? imageHeight : '100%'
|
|
419
|
+
},
|
|
420
|
+
isCropMode ? modeStyle : {}
|
|
421
|
+
)
|
|
422
|
+
},
|
|
423
|
+
innerProps
|
|
424
|
+
),
|
|
425
|
+
enableFastImage
|
|
426
|
+
)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const SvgImage = createElement(
|
|
430
|
+
View,
|
|
431
|
+
innerProps,
|
|
432
|
+
createElement(SvgCssUri, {
|
|
433
|
+
uri: src,
|
|
434
|
+
onLayout: onSvgLoad,
|
|
435
|
+
onError: binderror && onSvgError,
|
|
436
|
+
style: extendObject(
|
|
437
|
+
{ transformOrigin: 'top left' },
|
|
438
|
+
modeStyle
|
|
439
|
+
)
|
|
440
|
+
})
|
|
431
441
|
)
|
|
442
|
+
|
|
443
|
+
const BaseImage = createBaseImage(innerProps)
|
|
444
|
+
|
|
445
|
+
const LayoutImage = createElement(View, innerProps, loaded && createBaseImage())
|
|
446
|
+
|
|
447
|
+
return isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage
|
|
432
448
|
})
|
|
433
449
|
|
|
434
450
|
Image.displayName = 'mpx-image'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { View, Text, Modal, TouchableWithoutFeedback } from 'react-native'
|
|
2
|
-
import
|
|
2
|
+
import Portal from '../mpx-portal'
|
|
3
|
+
import { PickerView } from '@ant-design/react-native'
|
|
3
4
|
import React, { forwardRef, useState, useRef, useEffect } from 'react'
|
|
4
5
|
import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
|
|
5
6
|
import { TimeProps } from './type'
|
|
@@ -9,7 +9,7 @@ interface PickerColumnItemProps {
|
|
|
9
9
|
item: React.ReactElement
|
|
10
10
|
index: number
|
|
11
11
|
itemHeight: number
|
|
12
|
-
itemWidth
|
|
12
|
+
itemWidth?: number | '100%'
|
|
13
13
|
textStyleFromParent: Record<string, any>
|
|
14
14
|
textStyle: Record<string, any>
|
|
15
15
|
hasVarDec: boolean
|
|
@@ -23,7 +23,7 @@ const _PickerViewColumnItem: React.FC<PickerColumnItemProps> = ({
|
|
|
23
23
|
item,
|
|
24
24
|
index,
|
|
25
25
|
itemHeight,
|
|
26
|
-
itemWidth,
|
|
26
|
+
itemWidth = '100%',
|
|
27
27
|
textStyleFromParent,
|
|
28
28
|
textStyle,
|
|
29
29
|
hasVarDec,
|
|
@@ -44,8 +44,8 @@ const _PickerViewColumnItem: React.FC<PickerColumnItemProps> = ({
|
|
|
44
44
|
return {
|
|
45
45
|
opacity: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.opacity), Extrapolation.CLAMP),
|
|
46
46
|
transform: [
|
|
47
|
-
{ rotateX: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.deg), Extrapolation.CLAMP) + 'deg' },
|
|
48
47
|
{ translateY: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.offsetY), Extrapolation.EXTEND) },
|
|
48
|
+
{ rotateX: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.deg), Extrapolation.CLAMP) + 'deg' },
|
|
49
49
|
{ scale: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.scale), Extrapolation.EXTEND) }
|
|
50
50
|
]
|
|
51
51
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react'
|
|
2
2
|
import { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, SafeAreaView, ScrollView, StyleSheet, View } from 'react-native'
|
|
3
3
|
import Reanimated, { AnimatedRef, useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'
|
|
4
|
-
import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid } from './utils'
|
|
4
|
+
import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS, useDebounceCallback, useStableCallback } from './utils'
|
|
5
5
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
6
6
|
import PickerOverlay from './pickerViewOverlay'
|
|
7
7
|
import PickerMask from './pickerViewMask'
|
|
@@ -64,14 +64,12 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
const { height: pickerH, itemHeight } = wrapperStyle
|
|
67
|
-
const [scrollViewWidth, setScrollViewWidth] = useState<number | '100%'>('100%')
|
|
68
|
-
const [itemRawW, setItemRawW] = useState<number | '100%'>('100%')
|
|
69
67
|
const [itemRawH, setItemRawH] = useState(itemHeight)
|
|
70
68
|
const maxIndex = useMemo(() => columnData.length - 1, [columnData])
|
|
71
|
-
const maxScrollViewWidth = useRef(-1)
|
|
72
69
|
const prevScrollingInfo = useRef({ index: initialIndex, y: 0 })
|
|
73
70
|
const touching = useRef(false)
|
|
74
71
|
const scrolling = useRef(false)
|
|
72
|
+
const timerScrollTo = useRef<NodeJS.Timeout | null>(null)
|
|
75
73
|
const activeIndex = useRef(initialIndex)
|
|
76
74
|
const prevIndex = usePrevious(initialIndex)
|
|
77
75
|
const prevMaxIndex = usePrevious(maxIndex)
|
|
@@ -88,11 +86,6 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
88
86
|
|
|
89
87
|
// console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
|
|
90
88
|
|
|
91
|
-
// const initialOffset = useMemo(() => ({
|
|
92
|
-
// x: 0,
|
|
93
|
-
// y: itemRawH * initialIndex
|
|
94
|
-
// }), [itemRawH])
|
|
95
|
-
|
|
96
89
|
const paddingHeight = useMemo(
|
|
97
90
|
() => Math.round((pickerH - itemHeight) / 2),
|
|
98
91
|
[pickerH, itemHeight]
|
|
@@ -112,8 +105,41 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
112
105
|
return Math.max(0, Math.min(calc, maxIndex))
|
|
113
106
|
}, [itemRawH, maxIndex])
|
|
114
107
|
|
|
108
|
+
const getYofIndex = useCallback((index: number) => {
|
|
109
|
+
return index * itemRawH
|
|
110
|
+
}, [itemRawH])
|
|
111
|
+
|
|
112
|
+
const stableResetScrollPosition = useStableCallback((y: number) => {
|
|
113
|
+
// console.log('[mpx-picker-view-column], reset --->', 'columnIndex=', columnIndex, 'y=', y, touching.current, scrolling.current, itemRawH, 'snapToOffsets=', snapToOffsets)
|
|
114
|
+
if (touching.current || scrolling.current) {
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
// needReset.current = true
|
|
118
|
+
if (y % itemRawH !== 0) {
|
|
119
|
+
scrolling.current = true
|
|
120
|
+
const targetIndex = getIndex(y)
|
|
121
|
+
const targetY = getYofIndex(targetIndex)
|
|
122
|
+
scrollViewRef.current?.scrollTo({ x: 0, y: targetY, animated: false })
|
|
123
|
+
} else {
|
|
124
|
+
onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } })
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
const debounceResetScrollPosition = useDebounceCallback(stableResetScrollPosition, 10)
|
|
128
|
+
|
|
129
|
+
const clearTimerScrollTo = () => {
|
|
130
|
+
if (timerScrollTo.current) {
|
|
131
|
+
clearTimeout(timerScrollTo.current)
|
|
132
|
+
timerScrollTo.current = null
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
return () => {
|
|
138
|
+
clearTimerScrollTo()
|
|
139
|
+
}
|
|
140
|
+
}, [])
|
|
141
|
+
|
|
115
142
|
useEffect(() => {
|
|
116
|
-
// console.log('[mpx-picker-view-column], useEffect000 --->', 'columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'prevIndex=', prevIndex, 'activeIndex=', activeIndex.current, 'maxIndex=', maxIndex, 'prevMaxIndex=', prevMaxIndex)
|
|
117
143
|
if (
|
|
118
144
|
!scrollViewRef.current ||
|
|
119
145
|
!itemRawH ||
|
|
@@ -126,11 +152,11 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
126
152
|
) {
|
|
127
153
|
return
|
|
128
154
|
}
|
|
129
|
-
|
|
130
|
-
setTimeout(() => {
|
|
155
|
+
clearTimerScrollTo()
|
|
156
|
+
timerScrollTo.current = setTimeout(() => {
|
|
131
157
|
scrollViewRef.current?.scrollTo({
|
|
132
158
|
x: 0,
|
|
133
|
-
y:
|
|
159
|
+
y: getYofIndex(initialIndex),
|
|
134
160
|
animated: false
|
|
135
161
|
})
|
|
136
162
|
}, isAndroid ? 200 : 0)
|
|
@@ -138,86 +164,64 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
138
164
|
}, [itemRawH, initialIndex])
|
|
139
165
|
|
|
140
166
|
const onContentSizeChange = (_w: number, h: number) => {
|
|
141
|
-
const y =
|
|
142
|
-
// console.log('[mpx-picker-view-column], onContentSizeChange --->', 'columnIndex=', columnIndex, '_w=', _w, 'h=', h, 'y=', y, 'itemRawH=', itemRawH)
|
|
167
|
+
const y = getYofIndex(initialIndex)
|
|
143
168
|
if (y <= h) {
|
|
144
|
-
|
|
169
|
+
clearTimerScrollTo()
|
|
170
|
+
timerScrollTo.current = setTimeout(() => {
|
|
145
171
|
scrollViewRef.current?.scrollTo({ x: 0, y, animated: false })
|
|
146
172
|
}, 0)
|
|
147
173
|
}
|
|
148
174
|
}
|
|
149
175
|
|
|
150
|
-
const onScrollViewLayout = (e: LayoutChangeEvent) => {
|
|
151
|
-
if (isAndroid) {
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
|
-
// RN iOS bug: https://github.com/facebook/react-native/issues/36135
|
|
155
|
-
const { width } = e.nativeEvent.layout
|
|
156
|
-
const widthInt = Math.ceil(width)
|
|
157
|
-
// console.log('[mpx-picker-view-column], onScrollViewLayout --->', 'columnIndex=', columnIndex, 'width=', width, 'widthInt=', widthInt, 'scrollViewWidth=', scrollViewWidth)
|
|
158
|
-
if (widthInt !== scrollViewWidth) {
|
|
159
|
-
const maxW = maxScrollViewWidth.current
|
|
160
|
-
if (maxW !== -1 && widthInt > maxW) {
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
if (maxW === -1) {
|
|
164
|
-
maxScrollViewWidth.current = Math.ceil(widthInt * 1.5)
|
|
165
|
-
}
|
|
166
|
-
setScrollViewWidth(widthInt)
|
|
167
|
-
}
|
|
168
|
-
if (itemRawW === '100%') {
|
|
169
|
-
setItemRawW(widthInt)
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
176
|
const onItemLayout = (e: LayoutChangeEvent) => {
|
|
174
177
|
const { height: rawH } = e.nativeEvent.layout
|
|
175
|
-
|
|
176
|
-
if (
|
|
177
|
-
setItemRawH(
|
|
178
|
+
const roundedH = Math.round(rawH)
|
|
179
|
+
if (roundedH && roundedH !== itemRawH) {
|
|
180
|
+
setItemRawH(roundedH)
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
|
|
181
|
-
const
|
|
184
|
+
const onScrollBeginDrag = () => {
|
|
185
|
+
isIOS && debounceResetScrollPosition.clear()
|
|
182
186
|
touching.current = true
|
|
183
187
|
prevScrollingInfo.current = {
|
|
184
188
|
index: activeIndex.current,
|
|
185
|
-
y: activeIndex.current
|
|
189
|
+
y: getYofIndex(activeIndex.current)
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
192
|
|
|
189
|
-
const
|
|
190
|
-
touching.current = false
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const onTouchCancel = () => {
|
|
193
|
+
const onScrollEndDrag = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
194
194
|
touching.current = false
|
|
195
|
+
const { y } = e.nativeEvent.contentOffset
|
|
196
|
+
if (isIOS) {
|
|
197
|
+
if (y >= 0 && y <= snapToOffsets[maxIndex]) {
|
|
198
|
+
debounceResetScrollPosition(y)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
const onMomentumScrollBegin = () => {
|
|
204
|
+
isIOS && debounceResetScrollPosition.clear()
|
|
198
205
|
scrolling.current = true
|
|
199
206
|
}
|
|
200
207
|
|
|
201
|
-
const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
208
|
+
const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent> | { nativeEvent: { contentOffset: { y: number } } }) => {
|
|
202
209
|
scrolling.current = false
|
|
203
|
-
if (!itemRawH) {
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
210
|
const { y: scrollY } = e.nativeEvent.contentOffset
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
+
// console.log('[mpx-picker-view-column], onMomentumScrollEnd --->', 'columnIndex=', columnIndex, scrollY, itemRawH)
|
|
212
|
+
if (isIOS && scrollY % itemRawH !== 0) {
|
|
213
|
+
return debounceResetScrollPosition(scrollY)
|
|
214
|
+
}
|
|
215
|
+
const calcIndex = getIndex(scrollY)
|
|
216
|
+
if (calcIndex !== activeIndex.current) {
|
|
217
|
+
activeIndex.current = calcIndex
|
|
211
218
|
onSelectChange(calcIndex)
|
|
212
219
|
}
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
// 全局注册的震动触感 hook
|
|
220
|
-
const pickerVibrate = global.__mpx.config.rnConfig.pickerVibrate
|
|
223
|
+
// 全局注册的振动触感 hook
|
|
224
|
+
const pickerVibrate = global.__mpx?.config?.rnConfig?.pickerVibrate
|
|
221
225
|
if (typeof pickerVibrate !== 'function') {
|
|
222
226
|
return
|
|
223
227
|
}
|
|
@@ -229,7 +233,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
229
233
|
if (currentId !== prevIndex) {
|
|
230
234
|
prevScrollingInfo.current = {
|
|
231
235
|
index: currentId,
|
|
232
|
-
y: currentId
|
|
236
|
+
y: getYofIndex(currentId)
|
|
233
237
|
}
|
|
234
238
|
// vibrateShort({ type: 'selection' })
|
|
235
239
|
pickerVibrate()
|
|
@@ -246,7 +250,6 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
246
250
|
item={item}
|
|
247
251
|
index={index}
|
|
248
252
|
itemHeight={itemHeight}
|
|
249
|
-
itemWidth={itemRawW}
|
|
250
253
|
textStyleFromParent={textStyleFromParent}
|
|
251
254
|
textStyle={textStyle}
|
|
252
255
|
hasVarDec={hasVarDec}
|
|
@@ -271,14 +274,12 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
271
274
|
showsHorizontalScrollIndicator={false}
|
|
272
275
|
scrollEventThrottle={16}
|
|
273
276
|
{...layoutProps}
|
|
274
|
-
style={[{ width:
|
|
277
|
+
style={[{ width: '100%' }]}
|
|
275
278
|
decelerationRate="fast"
|
|
276
279
|
snapToOffsets={snapToOffsets}
|
|
277
280
|
onScroll={onScroll}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
onTouchEnd={onTouchEnd}
|
|
281
|
-
onTouchCancel={onTouchCancel}
|
|
281
|
+
onScrollBeginDrag={onScrollBeginDrag}
|
|
282
|
+
onScrollEndDrag={onScrollEndDrag}
|
|
282
283
|
onMomentumScrollBegin={onMomentumScrollBegin}
|
|
283
284
|
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
284
285
|
onContentSizeChange={onContentSizeChange}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useRef, ReactNode } from 'react'
|
|
2
|
+
import { PortalContextValue } from '../context'
|
|
3
|
+
import { getFocusedNavigation } from '@mpxjs/utils'
|
|
4
|
+
|
|
5
|
+
export type PortalConsumerProps = {
|
|
6
|
+
manager: PortalContextValue
|
|
7
|
+
children?: ReactNode
|
|
8
|
+
}
|
|
9
|
+
const PortalConsumer = ({ manager, children } :PortalConsumerProps): JSX.Element | null => {
|
|
10
|
+
const keyRef = useRef<any>(null)
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const navigation = getFocusedNavigation()
|
|
13
|
+
const curPageId = navigation?.pageId
|
|
14
|
+
manager.update(keyRef.current, children, curPageId)
|
|
15
|
+
}, [children])
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!manager) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
'Looks like you forgot to wrap your root component with `Provider` component from `@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal`.\n\n'
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
const navigation = getFocusedNavigation()
|
|
23
|
+
const curPageId = navigation?.pageId
|
|
24
|
+
keyRef.current = manager.mount(children, undefined, curPageId)
|
|
25
|
+
return () => {
|
|
26
|
+
manager.unmount(keyRef.current)
|
|
27
|
+
}
|
|
28
|
+
}, [])
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default PortalConsumer
|