@mpxjs/webpack-plugin 2.9.67 → 2.9.69-beta.1

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 (150) hide show
  1. package/lib/index.js +30 -9
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +51 -54
  4. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  5. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  6. package/lib/platform/template/wx/component-config/index.js +1 -1
  7. package/lib/platform/template/wx/component-config/input.js +1 -1
  8. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  9. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  10. package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
  11. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  12. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  13. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  14. package/lib/react/processStyles.js +14 -4
  15. package/lib/react/processTemplate.js +3 -0
  16. package/lib/resolver/AddEnvPlugin.js +1 -0
  17. package/lib/resolver/AddModePlugin.js +9 -8
  18. package/lib/runtime/components/react/context.ts +14 -0
  19. package/lib/runtime/components/react/dist/context.js +4 -0
  20. package/lib/runtime/components/react/dist/event.config.js +24 -24
  21. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -175
  22. package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
  23. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  29. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  30. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  31. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  32. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  33. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  34. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  35. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  36. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  37. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  38. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  39. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  40. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +14 -14
  41. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  42. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  43. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  44. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  45. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  46. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  47. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  48. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  49. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +171 -88
  50. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  51. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  52. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  53. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  54. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +62 -0
  55. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  56. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +53 -42
  57. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  58. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +28 -9
  59. package/lib/runtime/components/react/dist/mpx-swiper.jsx +608 -0
  60. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  61. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  62. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  63. package/lib/runtime/components/react/dist/mpx-view.jsx +67 -94
  64. package/lib/runtime/components/react/dist/mpx-web-view.jsx +152 -37
  65. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  66. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  67. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  68. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  69. package/lib/runtime/components/react/dist/useAnimationHooks.js +36 -10
  70. package/lib/runtime/components/react/dist/utils.jsx +129 -24
  71. package/lib/runtime/components/react/event.config.ts +25 -26
  72. package/lib/runtime/components/react/getInnerListeners.ts +238 -202
  73. package/lib/runtime/components/react/mpx-button.tsx +104 -57
  74. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  75. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  76. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  77. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  78. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  79. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  80. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  81. package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
  82. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  83. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  84. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  85. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  86. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  87. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  88. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  89. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  90. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  91. package/lib/runtime/components/react/mpx-movable-view.tsx +22 -26
  92. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  93. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  94. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  95. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  96. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  97. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  98. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  99. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  100. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
  101. package/lib/runtime/components/react/mpx-picker-view-column.tsx +276 -112
  102. package/lib/runtime/components/react/mpx-picker-view.tsx +137 -129
  103. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  104. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  105. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  106. package/lib/runtime/components/react/mpx-rich-text/index.tsx +115 -0
  107. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  108. package/lib/runtime/components/react/mpx-scroll-view.tsx +83 -73
  109. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  110. package/lib/runtime/components/react/mpx-swiper-item.tsx +41 -12
  111. package/lib/runtime/components/react/mpx-swiper.tsx +690 -0
  112. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  113. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  114. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  115. package/lib/runtime/components/react/mpx-view.tsx +93 -117
  116. package/lib/runtime/components/react/mpx-web-view.tsx +162 -56
  117. package/lib/runtime/components/react/pickerFaces.ts +112 -0
  118. package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
  119. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  120. package/lib/runtime/components/react/pickerViewOverlay.tsx +34 -0
  121. package/lib/runtime/components/react/types/common.ts +2 -0
  122. package/lib/runtime/components/react/types/global.d.ts +7 -17
  123. package/lib/runtime/components/react/useAnimationHooks.ts +37 -12
  124. package/lib/runtime/components/react/utils.tsx +169 -29
  125. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  126. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  127. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  128. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  129. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  130. package/lib/runtime/optionProcessor.js +7 -38
  131. package/lib/runtime/utils.js +2 -0
  132. package/lib/style-compiler/index.js +3 -4
  133. package/lib/style-compiler/plugins/scope-id.js +30 -2
  134. package/lib/style-compiler/strip-conditional-loader.js +118 -0
  135. package/lib/template-compiler/bind-this.js +7 -2
  136. package/lib/template-compiler/compiler.js +66 -39
  137. package/lib/template-compiler/gen-node-react.js +3 -3
  138. package/package.json +6 -4
  139. package/LICENSE +0 -433
  140. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  141. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  142. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  143. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  144. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  145. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  146. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  147. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -525
  148. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  149. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
  150. package/lib/runtime/components/web/event.js +0 -105
@@ -0,0 +1,88 @@
1
+ import React, { useEffect } from 'react'
2
+ import { LayoutChangeEvent } from 'react-native'
3
+ import Reanimated, { Extrapolation, interpolate, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'
4
+ import { wrapChildren, extendObject } from './utils'
5
+ import { createFaces } from './pickerFaces'
6
+ import { usePickerViewColumnAnimationContext } from './pickerVIewContext'
7
+
8
+ interface PickerColumnItemProps {
9
+ item: React.ReactElement
10
+ index: number
11
+ itemHeight: number
12
+ itemWidth: number | '100%'
13
+ textStyleFromParent: Record<string, any>
14
+ textStyle: Record<string, any>
15
+ hasVarDec: boolean
16
+ varContext: Record<string, any>
17
+ visibleCount: number
18
+ textProps?: any
19
+ onItemLayout?: (e: LayoutChangeEvent) => void
20
+ }
21
+
22
+ const _PickerViewColumnItem: React.FC<PickerColumnItemProps> = ({
23
+ item,
24
+ index,
25
+ itemHeight,
26
+ itemWidth,
27
+ textStyleFromParent,
28
+ textStyle,
29
+ hasVarDec,
30
+ varContext,
31
+ textProps,
32
+ visibleCount,
33
+ onItemLayout
34
+ }) => {
35
+ const offsetYShared = usePickerViewColumnAnimationContext()
36
+ const facesShared = useSharedValue(createFaces(itemHeight, visibleCount))
37
+
38
+ useEffect(() => {
39
+ facesShared.value = createFaces(itemHeight, visibleCount)
40
+ }, [itemHeight])
41
+
42
+ const animatedStyles = useAnimatedStyle(() => {
43
+ const inputRange = facesShared.value.map((f) => itemHeight * (index + f.index))
44
+ return {
45
+ opacity: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.opacity), Extrapolation.CLAMP),
46
+ transform: [
47
+ { rotateX: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.deg), Extrapolation.CLAMP) + 'deg' },
48
+ { translateY: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.offsetY), Extrapolation.EXTEND) },
49
+ { scale: interpolate(offsetYShared.value, inputRange, facesShared.value.map((x) => x.scale), Extrapolation.EXTEND) }
50
+ ]
51
+ }
52
+ })
53
+
54
+ const strKey = `picker-column-item-${index}`
55
+ const restProps = index === 0 ? { onLayout: onItemLayout } : {}
56
+ const itemProps = extendObject(
57
+ {
58
+ style: extendObject(
59
+ { height: itemHeight, width: '100%' },
60
+ textStyleFromParent,
61
+ textStyle,
62
+ item.props.style
63
+ )
64
+ },
65
+ restProps
66
+ )
67
+ const realItem = React.cloneElement(item, itemProps)
68
+
69
+ return (
70
+ <Reanimated.View
71
+ key={strKey}
72
+ style={[{ height: itemHeight, width: itemWidth }, animatedStyles]}
73
+ >
74
+ {wrapChildren(
75
+ { children: realItem },
76
+ {
77
+ hasVarDec,
78
+ varContext,
79
+ textStyle,
80
+ textProps
81
+ }
82
+ )}
83
+ </Reanimated.View>
84
+ )
85
+ }
86
+
87
+ _PickerViewColumnItem.displayName = 'MpxPickerViewColumnItem'
88
+ export default _PickerViewColumnItem
@@ -1,31 +1,50 @@
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 } from './utils'
5
+ import useNodesRef, { HandlerRef } from './useNodesRef'
6
+ import PickerOverlay from './pickerViewOverlay'
7
+ import PickerMask from './pickerViewMask'
8
+ import MpxPickerVIewColumnItem from './mpx-picker-view-column-item'
9
+ import { PickerViewColumnAnimationContext } from './pickerVIewContext'
1
10
 
2
- import { View, Animated, SafeAreaView, NativeScrollEvent, NativeSyntheticEvent, LayoutChangeEvent, ScrollView } from 'react-native'
3
- import React, { forwardRef, useRef, useState, useEffect, ReactElement, ReactNode } from 'react'
4
- import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils'
5
- import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
6
11
  interface ColumnProps {
7
- children: React.ReactNode,
8
- selectedIndex: number,
9
- onColumnLayoutChange: Function,
10
- getInnerLayout: Function,
11
- onSelectChange: Function,
12
+ children?: React.ReactNode
13
+ columnData: React.ReactNode[]
14
+ columnStyle: Record<string, any>
15
+ initialIndex: number
16
+ onSelectChange: Function
12
17
  style: {
13
18
  [key: string]: any
14
- },
19
+ }
15
20
  'enable-var': boolean
16
21
  'external-var-context'?: Record<string, any>
17
22
  wrapperStyle: {
18
- height?: number,
19
- itemHeight: string
20
- },
21
- prefix: number
23
+ height: number
24
+ itemHeight: number
25
+ }
26
+ pickerMaskStyle: Record<string, any>
27
+ pickerOverlayStyle: Record<string, any>
28
+ columnIndex: number
22
29
  }
23
- const defaultItemHeight = 36
24
- // 每个Column 都有个外层的高度, 内部的元素高度
25
- // 默认的高度
30
+
31
+ const visibleCount = 5
32
+
26
33
  const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>, ColumnProps>((props: ColumnProps, ref) => {
27
- const { children, selectedIndex, onColumnLayoutChange, onSelectChange, getInnerLayout, style, wrapperStyle, 'enable-var': enableVar, 'external-var-context': externalVarContext } = props
28
- // PickerViewColumn
34
+ const {
35
+ columnData,
36
+ columnIndex,
37
+ columnStyle,
38
+ initialIndex,
39
+ onSelectChange,
40
+ style,
41
+ wrapperStyle,
42
+ pickerMaskStyle,
43
+ pickerOverlayStyle,
44
+ 'enable-var': enableVar,
45
+ 'external-var-context': externalVarContext
46
+ } = props
47
+
29
48
  const {
30
49
  normalStyle,
31
50
  hasVarDec,
@@ -34,124 +53,269 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
34
53
  setWidth,
35
54
  setHeight
36
55
  } = useTransformStyle(style, { enableVar, externalVarContext })
37
- const { textStyle } = splitStyle(normalStyle)
56
+ const { textStyle: textStyleFromParent = {} } = splitStyle(columnStyle)
57
+ const { textStyle = {} } = splitStyle(normalStyle)
38
58
  const { textProps } = splitProps(props)
39
- // const { innerStyle } = splitStyle(normalStyle)
40
- // scrollView的ref
41
- const scrollViewRef = useRef<ScrollView>(null)
42
- useNodesRef(props, ref, scrollViewRef, {})
43
- // 每个元素的高度
44
- let [itemH, setItemH] = useState(0)
59
+ const scrollViewRef = useAnimatedRef<Reanimated.ScrollView>()
60
+ const offsetYShared = useScrollViewOffset(scrollViewRef as AnimatedRef<Reanimated.ScrollView>)
61
+
62
+ useNodesRef(props, ref, scrollViewRef as AnimatedRef<ScrollView>, {
63
+ style: normalStyle
64
+ })
65
+
66
+ const { height: pickerH, itemHeight } = wrapperStyle
67
+ const [scrollViewWidth, setScrollViewWidth] = useState<number | '100%'>('100%')
68
+ const [itemRawW, setItemRawW] = useState<number | '100%'>('100%')
69
+ const [itemRawH, setItemRawH] = useState(itemHeight)
70
+ const maxIndex = useMemo(() => columnData.length - 1, [columnData])
71
+ const maxScrollViewWidth = useRef(-1)
72
+ const prevScrollingInfo = useRef({ index: initialIndex, y: 0 })
73
+ const touching = useRef(false)
74
+ const scrolling = useRef(false)
75
+ const activeIndex = useRef(initialIndex)
76
+ const prevIndex = usePrevious(initialIndex)
77
+ const prevMaxIndex = usePrevious(maxIndex)
78
+
79
+ const {
80
+ layoutProps
81
+ } = useLayout({
82
+ props,
83
+ hasSelfPercent,
84
+ setWidth,
85
+ setHeight,
86
+ nodeRef: scrollViewRef
87
+ })
88
+
89
+ // console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
90
+
91
+ // const initialOffset = useMemo(() => ({
92
+ // x: 0,
93
+ // y: itemRawH * initialIndex
94
+ // }), [itemRawH])
95
+
96
+ const paddingHeight = useMemo(
97
+ () => Math.round((pickerH - itemHeight) / 2),
98
+ [pickerH, itemHeight]
99
+ )
100
+
101
+ const snapToOffsets = useMemo(
102
+ () => columnData.map((_, i) => i * itemRawH),
103
+ [columnData, itemRawH]
104
+ )
105
+
106
+ const contentContainerStyle = useMemo(() => {
107
+ return [{ paddingVertical: paddingHeight }]
108
+ }, [paddingHeight])
109
+
110
+ const getIndex = useCallback((y: number) => {
111
+ const calc = Math.round(y / itemRawH)
112
+ return Math.max(0, Math.min(calc, maxIndex))
113
+ }, [itemRawH, maxIndex])
45
114
 
46
115
  useEffect(() => {
47
- if (selectedIndex && itemH) {
48
- const offsetY = selectedIndex * itemH
49
- scrollViewRef.current?.scrollTo({ x: 0, y: offsetY, animated: true })
116
+ // console.log('[mpx-picker-view-column], useEffect000 --->', 'columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'prevIndex=', prevIndex, 'activeIndex=', activeIndex.current, 'maxIndex=', maxIndex, 'prevMaxIndex=', prevMaxIndex)
117
+ if (
118
+ !scrollViewRef.current ||
119
+ !itemRawH ||
120
+ touching.current ||
121
+ scrolling.current ||
122
+ prevIndex == null ||
123
+ initialIndex === prevIndex ||
124
+ initialIndex === activeIndex.current ||
125
+ maxIndex !== prevMaxIndex
126
+ ) {
127
+ return
50
128
  }
51
- }, [selectedIndex, itemH])
129
+ // console.log('[mpx-picker-view-column], useEffect ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'y=', itemRawH * initialIndex, `${scrollViewRef.current?.scrollTo}`)
130
+ setTimeout(() => {
131
+ scrollViewRef.current?.scrollTo({
132
+ x: 0,
133
+ y: itemRawH * initialIndex,
134
+ animated: false
135
+ })
136
+ }, isAndroid ? 200 : 0)
137
+ activeIndex.current = initialIndex
138
+ }, [itemRawH, initialIndex])
52
139
 
53
- const onScrollViewLayout = () => {
54
- getInnerLayout && getInnerLayout(layoutRef)
140
+ const onContentSizeChange = (_w: number, h: number) => {
141
+ const y = itemRawH * initialIndex
142
+ // console.log('[mpx-picker-view-column], onContentSizeChange --->', 'columnIndex=', columnIndex, '_w=', _w, 'h=', h, 'y=', y, 'itemRawH=', itemRawH)
143
+ if (y <= h) {
144
+ setTimeout(() => {
145
+ scrollViewRef.current?.scrollTo({ x: 0, y, animated: false })
146
+ }, 0)
147
+ }
55
148
  }
56
149
 
57
- const {
58
- // 存储layout布局信息
59
- layoutRef,
60
- layoutProps
61
- } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout: onScrollViewLayout })
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
+ }
62
172
 
63
173
  const onItemLayout = (e: LayoutChangeEvent) => {
64
- const layout = e.nativeEvent.layout
65
- if (layout.height && itemH !== layout.height) {
66
- itemH = layout.height
67
- setItemH(layout.height)
68
- onColumnLayoutChange && onColumnLayoutChange({ height: layout.height * 5 })
174
+ const { height: rawH } = e.nativeEvent.layout
175
+ // console.log('[mpx-picker-view-column], onItemLayout --->', 'columnIndex=', columnIndex, 'width=', width)
176
+ if (rawH && itemRawH !== rawH) {
177
+ setItemRawH(rawH)
178
+ }
179
+ }
180
+
181
+ const onTouchStart = () => {
182
+ touching.current = true
183
+ prevScrollingInfo.current = {
184
+ index: activeIndex.current,
185
+ y: activeIndex.current * itemRawH
69
186
  }
70
187
  }
71
188
 
189
+ const onTouchEnd = () => {
190
+ touching.current = false
191
+ }
192
+
193
+ const onTouchCancel = () => {
194
+ touching.current = false
195
+ }
196
+
197
+ const onMomentumScrollBegin = () => {
198
+ scrolling.current = true
199
+ }
200
+
72
201
  const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
73
- if (scrollViewRef && itemH) {
74
- const { y: scrollY } = e.nativeEvent.contentOffset
75
- const selIndex = Math.floor(scrollY / itemH)
76
- onSelectChange(selIndex)
202
+ scrolling.current = false
203
+ if (!itemRawH) {
204
+ return
205
+ }
206
+ const { y: scrollY } = e.nativeEvent.contentOffset
207
+ let calcIndex = Math.round(scrollY / itemRawH)
208
+ activeIndex.current = calcIndex
209
+ if (calcIndex !== initialIndex) {
210
+ calcIndex = Math.max(0, Math.min(calcIndex, maxIndex)) || 0
211
+ onSelectChange(calcIndex)
77
212
  }
78
213
  }
79
214
 
80
- const renderInnerchild = () => {
81
- // Fragment 节点
82
- let realElement: Array<ReactNode> = []
83
- const getRealChilds = () => {
84
- if (Array.isArray(children)) {
85
- realElement = children
86
- } else {
87
- const tempChild = children as ReactElement
88
- if (tempChild.props.children && tempChild.props.children) {
89
- realElement = tempChild.props.children
90
- } else {
91
- realElement = [children]
215
+ const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
216
+ if (isAndroid) {
217
+ return
218
+ }
219
+ // 全局注册的震动触感 hook
220
+ const pickerVibrate = global.__mpx.config.rnConfig.pickerVibrate
221
+ if (typeof pickerVibrate !== 'function') {
222
+ return
223
+ }
224
+ const { y } = e.nativeEvent.contentOffset
225
+ const { index: prevIndex, y: _y } = prevScrollingInfo.current
226
+ if (touching.current || scrolling.current) {
227
+ if (Math.abs(y - _y) >= itemRawH) {
228
+ const currentId = getIndex(y)
229
+ if (currentId !== prevIndex) {
230
+ prevScrollingInfo.current = {
231
+ index: currentId,
232
+ y: currentId * itemRawH
233
+ }
234
+ // vibrateShort({ type: 'selection' })
235
+ pickerVibrate()
92
236
  }
93
237
  }
94
- return realElement
95
238
  }
239
+ }
96
240
 
97
- const realChilds = getRealChilds()
98
- const arrChild = realChilds.map((item: React.ReactNode, index: number) => {
99
- const InnerProps = index === 0 ? { onLayout: onItemLayout } : {}
100
- const strKey = 'picker' + props.prefix + '-column' + index
101
- const arrHeight = (wrapperStyle.itemHeight + '').match(/\d+/g) || []
102
- const iHeight = (arrHeight[0] || defaultItemHeight) as number
103
- return <View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>
104
- {wrapChildren(
105
- {
106
- children: item
107
- },
108
- {
109
- hasVarDec,
110
- varContext: varContextRef.current,
111
- textStyle,
112
- textProps
113
- }
114
- )}
115
- </View>
241
+ const renderInnerchild = () =>
242
+ columnData.map((item: React.ReactElement, index: number) => {
243
+ return (
244
+ <MpxPickerVIewColumnItem
245
+ key={index}
246
+ item={item}
247
+ index={index}
248
+ itemHeight={itemHeight}
249
+ itemWidth={itemRawW}
250
+ textStyleFromParent={textStyleFromParent}
251
+ textStyle={textStyle}
252
+ hasVarDec={hasVarDec}
253
+ varContext={varContextRef.current}
254
+ textProps={textProps}
255
+ visibleCount={visibleCount}
256
+ onItemLayout={onItemLayout}
257
+ />
258
+ )
116
259
  })
117
- const totalHeight = itemH * 5
118
- if (wrapperStyle.height && totalHeight !== wrapperStyle.height) {
119
- const fix = Math.ceil((totalHeight - wrapperStyle.height) / 2)
120
- arrChild.unshift(<View key="picker-column-0" style={[{ height: itemH - fix }]}></View>)
121
- arrChild.unshift(<View key="picker-column-1" style={[{ height: itemH }]}></View>)
122
- arrChild.push(<View key="picker-column-2" style={[{ height: itemH }]}></View>)
123
- arrChild.push(<View key="picker-column-3" style={[{ height: itemH - fix }]}></View>)
124
- } else {
125
- arrChild.unshift(<View key="picker-column-0" style={[{ height: itemH }]}></View>)
126
- arrChild.unshift(<View key="picker-column-1" style={[{ height: itemH }]}></View>)
127
- arrChild.push(<View key="picker-column-2" style={[{ height: itemH }]}></View>)
128
- arrChild.push(<View key="picker-column-3" style={[{ height: itemH }]}></View>)
129
- }
130
- return arrChild
131
- }
132
260
 
133
261
  const renderScollView = () => {
134
- return (<Animated.ScrollView
135
- horizontal={false}
136
- ref={scrollViewRef}
137
- bounces={false}
138
- scrollsToTop={false}
139
- removeClippedSubviews={true}
140
- showsHorizontalScrollIndicator={false}
141
- showsVerticalScrollIndicator={false}
142
- pagingEnabled={false}
143
- snapToInterval={itemH}
144
- automaticallyAdjustContentInsets={false}
145
- {...layoutProps}
146
- onMomentumScrollEnd={onMomentumScrollEnd}>
147
- {renderInnerchild()}
148
- </Animated.ScrollView>)
262
+ return (
263
+ <PickerViewColumnAnimationContext.Provider value={offsetYShared}>
264
+ <Reanimated.ScrollView
265
+ ref={scrollViewRef}
266
+ bounces={true}
267
+ horizontal={false}
268
+ nestedScrollEnabled={true}
269
+ removeClippedSubviews={false}
270
+ showsVerticalScrollIndicator={false}
271
+ showsHorizontalScrollIndicator={false}
272
+ scrollEventThrottle={16}
273
+ {...layoutProps}
274
+ style={[{ width: scrollViewWidth }]}
275
+ decelerationRate="fast"
276
+ snapToOffsets={snapToOffsets}
277
+ onScroll={onScroll}
278
+ onLayout={onScrollViewLayout}
279
+ onTouchStart={onTouchStart}
280
+ onTouchEnd={onTouchEnd}
281
+ onTouchCancel={onTouchCancel}
282
+ onMomentumScrollBegin={onMomentumScrollBegin}
283
+ onMomentumScrollEnd={onMomentumScrollEnd}
284
+ onContentSizeChange={onContentSizeChange}
285
+ contentContainerStyle={contentContainerStyle}
286
+ >
287
+ {renderInnerchild()}
288
+ </Reanimated.ScrollView>
289
+ </PickerViewColumnAnimationContext.Provider>
290
+ )
149
291
  }
150
292
 
151
- return (<SafeAreaView style={[{ display: 'flex', flex: 1 }]}>
152
- { renderScollView() }
153
- </SafeAreaView>)
293
+ const renderOverlay = () => (
294
+ <PickerOverlay
295
+ itemHeight={itemHeight}
296
+ overlayItemStyle={pickerOverlayStyle}
297
+ />
298
+ )
299
+
300
+ const renderMask = () => (
301
+ <PickerMask
302
+ itemHeight={itemHeight}
303
+ maskContainerStyle={pickerMaskStyle}
304
+ />
305
+ )
306
+
307
+ return (
308
+ <SafeAreaView style={[styles.wrapper, normalStyle]}>
309
+ {renderScollView()}
310
+ {renderMask()}
311
+ {renderOverlay()}
312
+ </SafeAreaView>
313
+ )
314
+ })
315
+
316
+ const styles = StyleSheet.create({
317
+ wrapper: { display: 'flex', flex: 1 }
154
318
  })
155
319
 
156
- _PickerViewColumn.displayName = 'mpx-picker-view-column'
320
+ _PickerViewColumn.displayName = 'MpxPickerViewColumn'
157
321
  export default _PickerViewColumn