@mpxjs/webpack-plugin 2.9.64 → 2.9.66
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 +38 -10
- package/lib/index.js +5 -1
- package/lib/platform/style/wx/index.js +66 -60
- package/lib/platform/template/wx/index.js +12 -8
- package/lib/react/processTemplate.js +4 -2
- package/lib/react/style-helper.js +2 -5
- package/lib/runtime/components/react/context.ts +8 -0
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-form.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-icon.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-label.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +4 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-radio.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -3
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +78 -77
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-text.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +45 -15
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +4 -3
- package/lib/runtime/components/react/dist/useAnimationHooks.js +215 -0
- package/lib/runtime/components/react/dist/useNodesRef.js +1 -5
- package/lib/runtime/components/react/dist/utils.jsx +50 -37
- package/lib/runtime/components/react/mpx-button.tsx +3 -1
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +3 -1
- package/lib/runtime/components/react/mpx-checkbox.tsx +4 -1
- package/lib/runtime/components/react/mpx-form.tsx +2 -1
- package/lib/runtime/components/react/mpx-icon.tsx +3 -2
- package/lib/runtime/components/react/mpx-image/index.tsx +2 -1
- package/lib/runtime/components/react/mpx-input.tsx +2 -1
- package/lib/runtime/components/react/mpx-label.tsx +2 -1
- package/lib/runtime/components/react/mpx-movable-area.tsx +3 -2
- package/lib/runtime/components/react/mpx-movable-view.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker/date.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker/index.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker/region.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker/selector.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker/time.tsx +4 -2
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +3 -2
- package/lib/runtime/components/react/mpx-picker-view.tsx +2 -1
- package/lib/runtime/components/react/mpx-radio-group.tsx +2 -1
- package/lib/runtime/components/react/mpx-radio.tsx +3 -2
- package/lib/runtime/components/react/mpx-scroll-view.tsx +14 -2
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -75
- package/lib/runtime/components/react/mpx-swiper/index.tsx +4 -1
- package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -1
- package/lib/runtime/components/react/mpx-switch.tsx +2 -1
- package/lib/runtime/components/react/mpx-text.tsx +2 -1
- package/lib/runtime/components/react/mpx-view.tsx +55 -23
- package/lib/runtime/components/react/mpx-web-view.tsx +4 -3
- package/lib/runtime/components/react/types/common.ts +8 -2
- package/lib/runtime/components/react/types/global.d.ts +11 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +248 -0
- package/lib/runtime/components/react/useNodesRef.ts +1 -6
- package/lib/runtime/components/react/utils.tsx +71 -50
- package/lib/runtime/components/web/mpx-scroll-view.vue +25 -5
- package/lib/style-compiler/index.js +5 -4
- package/lib/template-compiler/compiler.js +127 -158
- package/lib/utils/const.js +2 -1
- package/lib/web/processStyles.js +6 -2
- package/lib/web/processTemplate.js +2 -3
- package/lib/wxml/loader.js +1 -1
- package/package.json +6 -4
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { View, LayoutChangeEvent } from 'react-native'
|
|
6
|
-
import { JSX, useState, useEffect, forwardRef, ReactNode } from 'react'
|
|
6
|
+
import { JSX, useState, useEffect, forwardRef, ReactNode, useRef } from 'react'
|
|
7
7
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
8
8
|
import useInnerProps from './getInnerListeners'
|
|
9
9
|
import { MovableAreaContext } from './context'
|
|
@@ -41,7 +41,8 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
|
|
|
41
41
|
setHeight
|
|
42
42
|
} = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
|
|
43
43
|
|
|
44
|
-
const
|
|
44
|
+
const movableViewRef = useRef(null)
|
|
45
|
+
useNodesRef(props, ref, movableViewRef)
|
|
45
46
|
|
|
46
47
|
const onLayout = (e: LayoutChangeEvent) => {
|
|
47
48
|
const { width = 10, height = 10 } = e.nativeEvent.layout
|
|
@@ -84,7 +84,8 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
84
84
|
y: Number(y)
|
|
85
85
|
})
|
|
86
86
|
|
|
87
|
-
const
|
|
87
|
+
const nodeRef = useRef<View>(null)
|
|
88
|
+
useNodesRef(props, ref, nodeRef, {
|
|
88
89
|
defaultStyle: styles.container
|
|
89
90
|
})
|
|
90
91
|
|
|
@@ -31,7 +31,8 @@ const _DatePicker = forwardRef<HandlerRef<View, DateProps>, DateProps>((props: D
|
|
|
31
31
|
const [datevalue, setDateValue] = useState(value)
|
|
32
32
|
// 存储layout布局信息
|
|
33
33
|
const layoutRef = useRef({})
|
|
34
|
-
const
|
|
34
|
+
const viewRef = useRef<View>(null)
|
|
35
|
+
useNodesRef<View, DateProps>(props, ref, viewRef, {
|
|
35
36
|
})
|
|
36
37
|
|
|
37
38
|
useEffect(() => {
|
|
@@ -34,7 +34,8 @@ import { FormContext, FormFieldValue } from '../context'
|
|
|
34
34
|
const _Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>((props: PickerProps, ref): React.JSX.Element => {
|
|
35
35
|
const { mode = 'selector', value, bindcancel, bindchange, children, bindcolumnchange } = props
|
|
36
36
|
const innerLayout = useRef({})
|
|
37
|
-
const
|
|
37
|
+
const nodeRef = useRef(null)
|
|
38
|
+
useNodesRef<View, PickerProps>(props, ref, nodeRef, {
|
|
38
39
|
})
|
|
39
40
|
const innerProps = useInnerProps(props, {
|
|
40
41
|
ref: nodeRef
|
|
@@ -89,7 +89,8 @@ const _MultiSelectorPicker = forwardRef<HandlerRef<View, MultiSelectorProps>, Mu
|
|
|
89
89
|
const [data, setData] = useState(formatRange || [])
|
|
90
90
|
// 存储layout布局信息
|
|
91
91
|
const layoutRef = useRef({})
|
|
92
|
-
const
|
|
92
|
+
const viewRef = useRef<View>(null)
|
|
93
|
+
useNodesRef<View, MultiSelectorProps>(props, ref, viewRef, {
|
|
93
94
|
})
|
|
94
95
|
|
|
95
96
|
useEffect(() => {
|
|
@@ -44,7 +44,8 @@ const _RegionPicker = forwardRef<HandlerRef<View, RegionProps>, RegionProps>((pr
|
|
|
44
44
|
const [regionvalue, setRegionValue] = useState(value)
|
|
45
45
|
// 存储layout布局信息
|
|
46
46
|
const layoutRef = useRef({})
|
|
47
|
-
const
|
|
47
|
+
const viewRef = useRef<View>(null)
|
|
48
|
+
useNodesRef<View, RegionProps>(props, ref, viewRef, {
|
|
48
49
|
})
|
|
49
50
|
|
|
50
51
|
const onChange = (value: string[]): void => {
|
|
@@ -31,7 +31,8 @@ const _SelectorPicker = forwardRef<HandlerRef<View, SelectorProps>, SelectorProp
|
|
|
31
31
|
const [data, setData] = useState(formatRange || [])
|
|
32
32
|
// 存储layout布局信息
|
|
33
33
|
const layoutRef = useRef({})
|
|
34
|
-
const
|
|
34
|
+
const viewRef = useRef<View>(null)
|
|
35
|
+
useNodesRef<View, SelectorProps>(props, ref, viewRef, {
|
|
35
36
|
})
|
|
36
37
|
|
|
37
38
|
useEffect(() => {
|
|
@@ -134,10 +134,12 @@ const _TimePicker = forwardRef<HandlerRef<View, TimeProps>, TimeProps>((props: T
|
|
|
134
134
|
const [timevalue, setTimeValue] = useState(defaultValue)
|
|
135
135
|
// 存储layout布局信息
|
|
136
136
|
const layoutRef = useRef({})
|
|
137
|
-
const
|
|
137
|
+
const viewRef = useRef<View>(null)
|
|
138
|
+
useNodesRef<View, TimeProps>(props, ref, viewRef, {})
|
|
138
139
|
// 存储modal的布局信息
|
|
139
140
|
const modalLayoutRef = useRef({})
|
|
140
|
-
const
|
|
141
|
+
const modalRef = useRef<View>(null)
|
|
142
|
+
useNodesRef<View, TimeProps>(props, ref, modalRef, {})
|
|
141
143
|
const [visible, setVisible] = useState(false)
|
|
142
144
|
const columnData = generateColumns()
|
|
143
145
|
const [data, setData] = useState(columnData)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import { View, Animated, SafeAreaView, NativeScrollEvent, NativeSyntheticEvent, LayoutChangeEvent, ScrollView } from 'react-native'
|
|
3
|
-
import React, { forwardRef, useState, useEffect, ReactElement, ReactNode } from 'react'
|
|
3
|
+
import React, { forwardRef, useRef, useState, useEffect, ReactElement, ReactNode } from 'react'
|
|
4
4
|
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils'
|
|
5
5
|
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
|
|
6
6
|
interface ColumnProps {
|
|
@@ -38,7 +38,8 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
38
38
|
const { textProps } = splitProps(props)
|
|
39
39
|
// const { innerStyle } = splitStyle(normalStyle)
|
|
40
40
|
// scrollView的ref
|
|
41
|
-
const
|
|
41
|
+
const scrollViewRef = useRef<ScrollView>(null)
|
|
42
|
+
useNodesRef(props, ref, scrollViewRef, {})
|
|
42
43
|
// 每个元素的高度
|
|
43
44
|
let [itemH, setItemH] = useState(0)
|
|
44
45
|
|
|
@@ -66,7 +66,8 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
66
66
|
// 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
|
|
67
67
|
const indicatorStyle = parseInlineStyle(props['indicator-style'])
|
|
68
68
|
const { height: indicatorH, width: indicatorW } = indicatorStyle
|
|
69
|
-
const
|
|
69
|
+
const nodeRef = useRef(null)
|
|
70
|
+
useNodesRef<View, PickerViewProps>(props, ref, nodeRef, {})
|
|
70
71
|
// picker-view 设置的color等textStyle,在小程序上的表现是可以继承到最内层的text样式, 但是RN内部column是slot无法设置, 需要业务自己在column内的元素上设置
|
|
71
72
|
const {
|
|
72
73
|
normalStyle,
|
|
@@ -65,7 +65,8 @@ const radioGroup = forwardRef<
|
|
|
65
65
|
setHeight
|
|
66
66
|
} = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
|
|
67
67
|
|
|
68
|
-
const
|
|
68
|
+
const nodeRef = useRef(null)
|
|
69
|
+
useNodesRef(props, ref, nodeRef, { defaultStyle })
|
|
69
70
|
|
|
70
71
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
|
|
71
72
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ✔ checked
|
|
5
5
|
* ✔ color
|
|
6
6
|
*/
|
|
7
|
-
import { JSX, useState, forwardRef, useEffect, ReactNode, useContext, Dispatch, SetStateAction } from 'react'
|
|
7
|
+
import { JSX, useRef, useState, forwardRef, useEffect, ReactNode, useContext, Dispatch, SetStateAction } from 'react'
|
|
8
8
|
import { View, StyleSheet, ViewStyle, NativeSyntheticEvent } from 'react-native'
|
|
9
9
|
import { warn } from '@mpxjs/utils'
|
|
10
10
|
import { LabelContext, RadioGroupContext } from './context'
|
|
@@ -141,7 +141,8 @@ const Radio = forwardRef<HandlerRef<View, RadioProps>, RadioProps>(
|
|
|
141
141
|
warn('Radio does not support background image-related styles!')
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
const
|
|
144
|
+
const nodeRef = useRef(null)
|
|
145
|
+
useNodesRef(props, ref, nodeRef, {
|
|
145
146
|
defaultStyle,
|
|
146
147
|
change: onChange
|
|
147
148
|
})
|
|
@@ -33,11 +33,13 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { ScrollView } from 'react-native-gesture-handler'
|
|
35
35
|
import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
|
|
36
|
-
import { JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef } from 'react'
|
|
36
|
+
import { JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef, useContext } from 'react'
|
|
37
|
+
import { useAnimatedRef } from 'react-native-reanimated'
|
|
37
38
|
import { warn } from '@mpxjs/utils'
|
|
38
39
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
39
40
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
40
41
|
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren } from './utils'
|
|
42
|
+
import { IntersectionObserverContext } from './context'
|
|
41
43
|
|
|
42
44
|
interface ScrollViewProps {
|
|
43
45
|
children?: ReactNode;
|
|
@@ -59,6 +61,7 @@ interface ScrollViewProps {
|
|
|
59
61
|
'scroll-top'?: number;
|
|
60
62
|
'scroll-left'?: number;
|
|
61
63
|
'enable-offset'?: boolean;
|
|
64
|
+
'enable-trigger-intersection-observer'?: boolean;
|
|
62
65
|
'enable-var'?: boolean;
|
|
63
66
|
'external-var-context'?: Record<string, any>;
|
|
64
67
|
'parent-font-size'?: number;
|
|
@@ -106,6 +109,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
106
109
|
'scroll-x': scrollX = false,
|
|
107
110
|
'scroll-y': scrollY = false,
|
|
108
111
|
'enable-back-to-top': enableBackToTop = false,
|
|
112
|
+
'enable-trigger-intersection-observer': enableTriggerIntersectionObserver = false,
|
|
109
113
|
'paging-enabled': pagingEnabled = false,
|
|
110
114
|
'upper-threshold': upperThreshold = 50,
|
|
111
115
|
'lower-threshold': lowerThreshold = 50,
|
|
@@ -138,6 +142,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
138
142
|
const hasCallScrollToUpper = useRef(true)
|
|
139
143
|
const hasCallScrollToLower = useRef(false)
|
|
140
144
|
const initialTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
145
|
+
const intersectionObservers = useContext(IntersectionObserverContext)
|
|
141
146
|
|
|
142
147
|
const {
|
|
143
148
|
normalStyle,
|
|
@@ -150,7 +155,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
150
155
|
|
|
151
156
|
const { textStyle, innerStyle } = splitStyle(normalStyle)
|
|
152
157
|
|
|
153
|
-
const
|
|
158
|
+
const scrollViewRef = useAnimatedRef<ScrollView>()
|
|
159
|
+
useNodesRef(props, ref, scrollViewRef, {
|
|
154
160
|
scrollOffset: scrollOptions,
|
|
155
161
|
node: {
|
|
156
162
|
scrollEnabled: scrollX || scrollY,
|
|
@@ -283,6 +289,11 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
283
289
|
}, props)
|
|
284
290
|
)
|
|
285
291
|
updateScrollOptions(e, { scrollLeft, scrollTop })
|
|
292
|
+
if (enableTriggerIntersectionObserver && intersectionObservers) {
|
|
293
|
+
for (const key in intersectionObservers) {
|
|
294
|
+
intersectionObservers[key].throttleMeasure()
|
|
295
|
+
}
|
|
296
|
+
}
|
|
286
297
|
}
|
|
287
298
|
|
|
288
299
|
function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
|
|
@@ -405,6 +416,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
405
416
|
'scroll-x',
|
|
406
417
|
'scroll-y',
|
|
407
418
|
'enable-back-to-top',
|
|
419
|
+
'enable-trigger-intersection-observer',
|
|
408
420
|
'paging-enabled',
|
|
409
421
|
'show-scrollbar',
|
|
410
422
|
'upper-threshold',
|
|
@@ -87,9 +87,12 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
87
87
|
const initOffsetIndex = initIndex + (props.circular && totalElements > 1 ? 1 : 0)
|
|
88
88
|
const defaultX = (defaultWidth * initOffsetIndex) || 0
|
|
89
89
|
const defaultY = (defaultHeight * initOffsetIndex) || 0
|
|
90
|
+
// 主动scorllTo时是否要出发onScrollEnd
|
|
91
|
+
const needTriggerScrollEnd = useRef(true)
|
|
90
92
|
// 内部存储上一次的offset值
|
|
91
93
|
const autoplayTimerRef = useRef<ReturnType <typeof setTimeout> | null>(null)
|
|
92
|
-
const
|
|
94
|
+
const scrollViewRef = useRef<ScrollView & View>(null)
|
|
95
|
+
useNodesRef<ScrollView & View, CarouseProps>(props, ref, scrollViewRef, {})
|
|
93
96
|
const {
|
|
94
97
|
// 存储layout布局信息
|
|
95
98
|
layoutRef,
|
|
@@ -99,22 +102,21 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
99
102
|
// 内部存储上一次的偏移量
|
|
100
103
|
const internalsRef = useRef({
|
|
101
104
|
offset: {
|
|
102
|
-
x:
|
|
103
|
-
y:
|
|
105
|
+
x: 0,
|
|
106
|
+
y: 0
|
|
104
107
|
},
|
|
105
108
|
isScrolling: false
|
|
106
109
|
})
|
|
107
110
|
const isDragRef = useRef(false)
|
|
108
111
|
const [state, setState] = useState({
|
|
109
|
-
children: newChild,
|
|
110
112
|
width: dir === 'x' && typeof defaultWidth === 'number' ? defaultWidth - previousMargin - nextMargin : defaultWidth,
|
|
111
113
|
height: dir === 'y' && typeof defaultHeight === 'number' ? defaultHeight - previousMargin - nextMargin : defaultHeight,
|
|
112
114
|
// 真正的游标索引, 从0开始
|
|
113
115
|
index: initIndex,
|
|
114
116
|
total: totalElements,
|
|
115
117
|
offset: {
|
|
116
|
-
x:
|
|
117
|
-
y:
|
|
118
|
+
x: 0,
|
|
119
|
+
y: 0
|
|
118
120
|
},
|
|
119
121
|
dir
|
|
120
122
|
} as CarouseState)
|
|
@@ -137,25 +139,38 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
137
139
|
|
|
138
140
|
useEffect(() => {
|
|
139
141
|
// 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
|
|
140
|
-
if (!props.autoplay && props.current !== state.index) {
|
|
142
|
+
if (!props.autoplay && props.current !== undefined && props.current !== state.index) {
|
|
141
143
|
const initIndex = props.current || 0
|
|
142
144
|
// 这里要排除超过元素个数的设置
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
const { nextIndex, nextOffset } = getMultiNextConfig(props.current)
|
|
146
|
+
// 1. 安卓需要主动更新下内部状态, 2. IOS不能触发完wcrollTo之后立即updateState, 会造成滑动两次
|
|
147
|
+
// 2. setTimeout 是fix 当再渲染过程中触发scrollTo失败的问题
|
|
148
|
+
if (Platform.OS === 'ios') {
|
|
149
|
+
needTriggerScrollEnd.current = false
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
scrollViewRef.current?.scrollTo({
|
|
152
|
+
...nextOffset,
|
|
153
|
+
animated: true
|
|
154
|
+
})
|
|
155
|
+
}, 50)
|
|
156
|
+
} else {
|
|
157
|
+
updateState(nextIndex, nextOffset)
|
|
148
158
|
}
|
|
149
|
-
state.offset = offset
|
|
150
|
-
internalsRef.current.offset = offset
|
|
151
|
-
setState((preState) => {
|
|
152
|
-
return {
|
|
153
|
-
...preState,
|
|
154
|
-
offset
|
|
155
|
-
}
|
|
156
|
-
})
|
|
157
159
|
}
|
|
158
|
-
}, [props.current])
|
|
160
|
+
}, [props.current, state.width, state.height])
|
|
161
|
+
|
|
162
|
+
function getMultiNextConfig (target: number) {
|
|
163
|
+
const step = state.dir === 'x' ? state.width : state.height
|
|
164
|
+
const targetPos = step * props.current
|
|
165
|
+
const targetOffset = {
|
|
166
|
+
x: dir === 'x' ? targetPos : 0,
|
|
167
|
+
y: dir === 'y' ? targetPos : 0
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
nextIndex: target,
|
|
171
|
+
nextOffset: targetOffset
|
|
172
|
+
}
|
|
173
|
+
}
|
|
159
174
|
/**
|
|
160
175
|
* @desc: 更新状态: index和offset, 并响应索引变化的事件
|
|
161
176
|
* scrollViewOffset: 移动到的目标位置
|
|
@@ -207,7 +222,6 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
207
222
|
nextIndex = isBack ? nextIndex - 2 : nextIndex
|
|
208
223
|
}
|
|
209
224
|
if (!props.circular) {
|
|
210
|
-
// nextIndex = isBack ? nextIndex - 2 : nextIndex
|
|
211
225
|
nextOffset = Object.assign({}, currentOffset, { [state.dir]: step * nextIndex })
|
|
212
226
|
} else {
|
|
213
227
|
if (isBack) {
|
|
@@ -253,13 +267,12 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
253
267
|
createAutoPlay()
|
|
254
268
|
return
|
|
255
269
|
}
|
|
256
|
-
if (!Array.isArray(
|
|
270
|
+
if (!Array.isArray(props.children)) {
|
|
257
271
|
return
|
|
258
272
|
}
|
|
259
273
|
const step = state.dir === 'x' ? state.width : state.height
|
|
260
274
|
const { nextOffset, autoMoveOffset, isAutoEnd } = getNextConfig(state.offset)
|
|
261
275
|
// 这里可以scroll到下一个元素, 但是把scrollView的偏移量在设置为content,视觉效果就没了吧
|
|
262
|
-
// scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: true })
|
|
263
276
|
if (Platform.OS === 'ios') {
|
|
264
277
|
if (!isAutoEnd) {
|
|
265
278
|
scrollViewRef.current?.scrollTo({ x: nextOffset.x, y: nextOffset.y, animated: true })
|
|
@@ -285,7 +298,6 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
285
298
|
// 安卓无法实现视觉的无缝连接, 只能回到真正的位置, 且安卓调用scrollTo不能触发onMomentumScrollEnd,还未找到为啥
|
|
286
299
|
if (state.dir === 'x') {
|
|
287
300
|
scrollViewRef.current?.scrollTo({ x: step, y: step, animated: true })
|
|
288
|
-
// scrollViewRef.current?.scrollTo({ x: autoMoveOffset.x, y: autoMoveOffset.y, animated: true })
|
|
289
301
|
} else {
|
|
290
302
|
scrollViewRef.current?.scrollTo({ x: autoMoveOffset.x, y: step, animated: true })
|
|
291
303
|
}
|
|
@@ -303,9 +315,15 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
303
315
|
|
|
304
316
|
/**
|
|
305
317
|
* 当用户开始拖动结束
|
|
318
|
+
* 注意: 当手动调用scrollTo的时候, 安卓不会触发onMomentumScrollEnd, IOS会触发onMomentumScrollEnd
|
|
306
319
|
*/
|
|
307
320
|
function onScrollEnd (event: NativeSyntheticEvent<NativeScrollEvent>) {
|
|
308
|
-
|
|
321
|
+
if (Platform.OS === 'ios' && !needTriggerScrollEnd.current) {
|
|
322
|
+
const { nextIndex, nextOffset } = getMultiNextConfig(props.current)
|
|
323
|
+
updateState(nextIndex, nextOffset)
|
|
324
|
+
needTriggerScrollEnd.current = true
|
|
325
|
+
return
|
|
326
|
+
}
|
|
309
327
|
if (totalElements === 1) {
|
|
310
328
|
return
|
|
311
329
|
}
|
|
@@ -333,57 +351,41 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
333
351
|
* @desc: 水平方向时,获取元素的布局,更新, 其中如果传递100%时需要依赖measure计算元算的宽高
|
|
334
352
|
*/
|
|
335
353
|
function onWrapperLayout (e: LayoutChangeEvent) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const isWDiff = state.width !== width
|
|
345
|
-
const isHDiff = state.height !== height
|
|
346
|
-
if (isWDiff || isHDiff) {
|
|
347
|
-
const changeState = {
|
|
348
|
-
width: isWDiff ? width : state.width,
|
|
349
|
-
height: isHDiff ? height : state.height
|
|
350
|
-
}
|
|
351
|
-
const attr = state.dir === 'x' ? 'width' : 'height'
|
|
352
|
-
changeState[attr] = changeState[attr] - previousMargin - nextMargin
|
|
353
|
-
const correctOffset = Object.assign({}, state.offset, {
|
|
354
|
-
[state.dir]: initOffsetIndex * (state.dir === 'x' ? changeState.width : changeState.height)
|
|
355
|
-
})
|
|
356
|
-
state.offset = correctOffset
|
|
357
|
-
state.width = changeState.width
|
|
358
|
-
state.height = changeState.height
|
|
359
|
-
setState((preState) => {
|
|
360
|
-
return {
|
|
361
|
-
...preState,
|
|
362
|
-
offset: correctOffset,
|
|
363
|
-
width: changeState.width,
|
|
364
|
-
height: changeState.height
|
|
365
|
-
}
|
|
366
|
-
})
|
|
367
|
-
scrollViewRef.current?.scrollTo({ x: correctOffset.x, y: correctOffset.y, animated: false })
|
|
354
|
+
scrollViewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
|
|
355
|
+
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
|
|
356
|
+
const isWDiff = state.width !== width
|
|
357
|
+
const isHDiff = state.height !== height
|
|
358
|
+
if (isWDiff || isHDiff) {
|
|
359
|
+
const changeState = {
|
|
360
|
+
width: isWDiff ? width : state.width,
|
|
361
|
+
height: isHDiff ? height : state.height
|
|
368
362
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
363
|
+
const attr = state.dir === 'x' ? 'width' : 'height'
|
|
364
|
+
changeState[attr] = changeState[attr] - previousMargin - nextMargin
|
|
365
|
+
const correctOffset = Object.assign({}, state.offset, {
|
|
366
|
+
[state.dir]: initOffsetIndex * (state.dir === 'x' ? changeState.width : changeState.height)
|
|
367
|
+
})
|
|
368
|
+
state.width = changeState.width
|
|
369
|
+
state.height = changeState.height
|
|
370
|
+
// 这里setState之后,会再触发重新渲染, renderScrollView会再次触发onScrollEnd,
|
|
371
|
+
setState((preState) => {
|
|
372
|
+
return {
|
|
373
|
+
...preState,
|
|
374
|
+
width: changeState.width,
|
|
375
|
+
height: changeState.height
|
|
376
|
+
}
|
|
377
|
+
})
|
|
378
|
+
}
|
|
379
|
+
props.getInnerLayout && props.getInnerLayout(layoutRef)
|
|
380
|
+
})
|
|
372
381
|
}
|
|
373
382
|
|
|
374
383
|
function getOffset (): Array<number> {
|
|
375
384
|
const step = state.dir === 'x' ? state.width : state.height
|
|
376
385
|
if (!step || Number.isNaN(+step)) return []
|
|
377
386
|
const offsetArray = []
|
|
378
|
-
|
|
379
|
-
offsetArray.push(
|
|
380
|
-
for (let i = 1; i < totalElements; i++) {
|
|
381
|
-
offsetArray.push(i * step - previousMargin)
|
|
382
|
-
}
|
|
383
|
-
} else {
|
|
384
|
-
for (let i = 0; i < totalElements; i++) {
|
|
385
|
-
offsetArray.push(i * step)
|
|
386
|
-
}
|
|
387
|
+
for (let i = 0; i < totalElements; i++) {
|
|
388
|
+
offsetArray.push(i * step)
|
|
387
389
|
}
|
|
388
390
|
return offsetArray
|
|
389
391
|
}
|
|
@@ -393,7 +395,7 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
393
395
|
const scrollElementProps = {
|
|
394
396
|
ref: scrollViewRef,
|
|
395
397
|
horizontal: props.horizontal,
|
|
396
|
-
pagingEnabled:
|
|
398
|
+
pagingEnabled: true,
|
|
397
399
|
snapToOffsets: offsetsArray,
|
|
398
400
|
decelerationRate: 0.99, // 'fast'
|
|
399
401
|
showsHorizontalScrollIndicator: false,
|
|
@@ -460,20 +462,21 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
460
462
|
}
|
|
461
463
|
|
|
462
464
|
function renderPages () {
|
|
463
|
-
const { width, height
|
|
465
|
+
const { width, height } = state
|
|
466
|
+
const { children } = props
|
|
464
467
|
const { circular } = props
|
|
465
468
|
const pageStyle = { width: width, height: height }
|
|
466
469
|
// 设置了previousMargin或者nextMargin,
|
|
467
470
|
// 1. 元素的宽度是减去这两个数目之和
|
|
468
471
|
// 2. previousMargin设置marginLeft正值, nextmargin设置marginRight负值
|
|
469
472
|
// 3. 第一个元素设置previousMargin 和 nextMargin, 最后一个元素
|
|
470
|
-
if (
|
|
473
|
+
if (totalElements > 1 && Array.isArray(children)) {
|
|
471
474
|
let arrElements: (Array<ReactNode>) = []
|
|
472
475
|
// pages = ["2", "0", "1", "2", "0"]
|
|
473
476
|
const pages = Array.isArray(children) ? Object.keys(children) : []
|
|
474
477
|
/* 无限循环的时候 */
|
|
475
478
|
if (circular) {
|
|
476
|
-
pages.unshift(
|
|
479
|
+
pages.unshift(totalElements - 1 + '')
|
|
477
480
|
pages.push('0')
|
|
478
481
|
}
|
|
479
482
|
arrElements = pages.map((page, i) => {
|
|
@@ -485,7 +488,6 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
|
|
|
485
488
|
} else if (i === pages.length - 1 && typeof width === 'number') {
|
|
486
489
|
nextMargin && (extraStyle.marginRight = nextMargin)
|
|
487
490
|
}
|
|
488
|
-
// return (<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>{children[+page]}</View>)
|
|
489
491
|
return (<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>
|
|
490
492
|
{wrapChildren(
|
|
491
493
|
{
|
|
@@ -45,7 +45,10 @@ const _SwiperWrapper = forwardRef<HandlerRef<ScrollView, SwiperProps>, SwiperPro
|
|
|
45
45
|
bindchange: props.bindchange,
|
|
46
46
|
easingFunction: props['easing-function'] || 'default'
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
|
|
49
|
+
const nodeRef = useRef(null)
|
|
50
|
+
useNodesRef<ScrollView, SwiperProps>(props, ref, nodeRef, {})
|
|
51
|
+
|
|
49
52
|
const innerProps = useInnerProps(props, {
|
|
50
53
|
ref: nodeRef
|
|
51
54
|
}, [
|
|
@@ -25,7 +25,8 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
|
|
|
25
25
|
} = props
|
|
26
26
|
|
|
27
27
|
const { textProps } = splitProps(props)
|
|
28
|
-
const
|
|
28
|
+
const nodeRef = useRef(null)
|
|
29
|
+
useNodesRef(props, ref, nodeRef, {})
|
|
29
30
|
|
|
30
31
|
const {
|
|
31
32
|
normalStyle,
|
|
@@ -76,7 +76,8 @@ const _Switch = forwardRef<HandlerRef<Switch, _SwitchProps>, _SwitchProps>((prop
|
|
|
76
76
|
setIsChecked(checked)
|
|
77
77
|
}, [checked])
|
|
78
78
|
|
|
79
|
-
const
|
|
79
|
+
const nodeRef = useRef(null)
|
|
80
|
+
useNodesRef<Switch, _SwitchProps>(props, ref, nodeRef)
|
|
80
81
|
|
|
81
82
|
const {
|
|
82
83
|
layoutRef,
|
|
@@ -48,7 +48,8 @@ const _Text = forwardRef<HandlerRef<Text, _TextProps>, _TextProps>((props, ref):
|
|
|
48
48
|
parentHeight
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const nodeRef = useRef(null)
|
|
52
|
+
useNodesRef<Text, _TextProps>(props, ref, nodeRef)
|
|
52
53
|
|
|
53
54
|
const innerProps = useInnerProps(props, {
|
|
54
55
|
ref: nodeRef,
|