@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ✘ scale-area
|
|
3
3
|
*/
|
|
4
4
|
import { View } from 'react-native';
|
|
5
|
-
import { useState, useEffect, forwardRef } from 'react';
|
|
5
|
+
import { useState, useEffect, forwardRef, useRef } from 'react';
|
|
6
6
|
import useNodesRef from './useNodesRef';
|
|
7
7
|
import useInnerProps from './getInnerListeners';
|
|
8
8
|
import { MovableAreaContext } from './context';
|
|
@@ -16,7 +16,8 @@ const _MovableArea = forwardRef((props, ref) => {
|
|
|
16
16
|
setAreaHeight(height);
|
|
17
17
|
}, [width, height]);
|
|
18
18
|
const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
19
|
-
const
|
|
19
|
+
const movableViewRef = useRef(null);
|
|
20
|
+
useNodesRef(props, ref, movableViewRef);
|
|
20
21
|
const onLayout = (e) => {
|
|
21
22
|
const { width = 10, height = 10 } = e.nativeEvent.layout;
|
|
22
23
|
setAreaWidth(width);
|
|
@@ -41,7 +41,8 @@ const _MovableView = forwardRef((props, ref) => {
|
|
|
41
41
|
x: Number(x),
|
|
42
42
|
y: Number(y)
|
|
43
43
|
});
|
|
44
|
-
const
|
|
44
|
+
const nodeRef = useRef(null);
|
|
45
|
+
useNodesRef(props, ref, nodeRef, {
|
|
45
46
|
defaultStyle: styles.container
|
|
46
47
|
});
|
|
47
48
|
let panResponder = {};
|
|
@@ -27,7 +27,8 @@ const _DatePicker = forwardRef((props, ref) => {
|
|
|
27
27
|
const [datevalue, setDateValue] = useState(value);
|
|
28
28
|
// 存储layout布局信息
|
|
29
29
|
const layoutRef = useRef({});
|
|
30
|
-
const
|
|
30
|
+
const viewRef = useRef(null);
|
|
31
|
+
useNodesRef(props, ref, viewRef, {});
|
|
31
32
|
useEffect(() => {
|
|
32
33
|
value && setDateValue(value);
|
|
33
34
|
}, [value]);
|
|
@@ -30,7 +30,8 @@ import { FormContext } from '../context';
|
|
|
30
30
|
const _Picker = forwardRef((props, ref) => {
|
|
31
31
|
const { mode = 'selector', value, bindcancel, bindchange, children, bindcolumnchange } = props;
|
|
32
32
|
const innerLayout = useRef({});
|
|
33
|
-
const
|
|
33
|
+
const nodeRef = useRef(null);
|
|
34
|
+
useNodesRef(props, ref, nodeRef, {});
|
|
34
35
|
const innerProps = useInnerProps(props, {
|
|
35
36
|
ref: nodeRef
|
|
36
37
|
}, [], { layoutRef: innerLayout });
|
|
@@ -86,7 +86,8 @@ const _MultiSelectorPicker = forwardRef((props, ref) => {
|
|
|
86
86
|
const [data, setData] = useState(formatRange || []);
|
|
87
87
|
// 存储layout布局信息
|
|
88
88
|
const layoutRef = useRef({});
|
|
89
|
-
const
|
|
89
|
+
const viewRef = useRef(null);
|
|
90
|
+
useNodesRef(props, ref, viewRef, {});
|
|
90
91
|
useEffect(() => {
|
|
91
92
|
if (range) {
|
|
92
93
|
const newFormatRange = formatRangeFun(range, props['range-key']);
|
|
@@ -40,7 +40,8 @@ const _RegionPicker = forwardRef((props, ref) => {
|
|
|
40
40
|
const [regionvalue, setRegionValue] = useState(value);
|
|
41
41
|
// 存储layout布局信息
|
|
42
42
|
const layoutRef = useRef({});
|
|
43
|
-
const
|
|
43
|
+
const viewRef = useRef(null);
|
|
44
|
+
useNodesRef(props, ref, viewRef, {});
|
|
44
45
|
const onChange = (value) => {
|
|
45
46
|
// 通过 value 查找 code
|
|
46
47
|
let tmp = regionData;
|
|
@@ -27,7 +27,8 @@ const _SelectorPicker = forwardRef((props, ref) => {
|
|
|
27
27
|
const [data, setData] = useState(formatRange || []);
|
|
28
28
|
// 存储layout布局信息
|
|
29
29
|
const layoutRef = useRef({});
|
|
30
|
-
const
|
|
30
|
+
const viewRef = useRef(null);
|
|
31
|
+
useNodesRef(props, ref, viewRef, {});
|
|
31
32
|
useEffect(() => {
|
|
32
33
|
if (range) {
|
|
33
34
|
const newFormatRange = formatRangeFun(range, props['range-key']);
|
|
@@ -126,10 +126,12 @@ const _TimePicker = forwardRef((props, ref) => {
|
|
|
126
126
|
const [timevalue, setTimeValue] = useState(defaultValue);
|
|
127
127
|
// 存储layout布局信息
|
|
128
128
|
const layoutRef = useRef({});
|
|
129
|
-
const
|
|
129
|
+
const viewRef = useRef(null);
|
|
130
|
+
useNodesRef(props, ref, viewRef, {});
|
|
130
131
|
// 存储modal的布局信息
|
|
131
132
|
const modalLayoutRef = useRef({});
|
|
132
|
-
const
|
|
133
|
+
const modalRef = useRef(null);
|
|
134
|
+
useNodesRef(props, ref, modalRef, {});
|
|
133
135
|
const [visible, setVisible] = useState(false);
|
|
134
136
|
const columnData = generateColumns();
|
|
135
137
|
const [data, setData] = useState(columnData);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { View, Animated, SafeAreaView } from 'react-native';
|
|
2
|
-
import React, { forwardRef, useState, useEffect } from 'react';
|
|
2
|
+
import React, { forwardRef, useRef, useState, useEffect } from 'react';
|
|
3
3
|
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils';
|
|
4
4
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
5
5
|
const defaultItemHeight = 36;
|
|
@@ -13,7 +13,8 @@ const _PickerViewColumn = forwardRef((props, ref) => {
|
|
|
13
13
|
const { textProps } = splitProps(props);
|
|
14
14
|
// const { innerStyle } = splitStyle(normalStyle)
|
|
15
15
|
// scrollView的ref
|
|
16
|
-
const
|
|
16
|
+
const scrollViewRef = useRef(null);
|
|
17
|
+
useNodesRef(props, ref, scrollViewRef, {});
|
|
17
18
|
// 每个元素的高度
|
|
18
19
|
let [itemH, setItemH] = useState(0);
|
|
19
20
|
useEffect(() => {
|
|
@@ -30,7 +30,8 @@ const _PickerView = forwardRef((props, ref) => {
|
|
|
30
30
|
// 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
|
|
31
31
|
const indicatorStyle = parseInlineStyle(props['indicator-style']);
|
|
32
32
|
const { height: indicatorH, width: indicatorW } = indicatorStyle;
|
|
33
|
-
const
|
|
33
|
+
const nodeRef = useRef(null);
|
|
34
|
+
useNodesRef(props, ref, nodeRef, {});
|
|
34
35
|
// picker-view 设置的color等textStyle,在小程序上的表现是可以继承到最内层的text样式, 但是RN内部column是slot无法设置, 需要业务自己在column内的元素上设置
|
|
35
36
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
|
|
36
37
|
const { textStyle } = splitStyle(normalStyle);
|
|
@@ -25,7 +25,8 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
25
25
|
...style
|
|
26
26
|
};
|
|
27
27
|
const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
28
|
-
const
|
|
28
|
+
const nodeRef = useRef(null);
|
|
29
|
+
useNodesRef(props, ref, nodeRef, { defaultStyle });
|
|
29
30
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
30
31
|
const getSelectionValue = () => {
|
|
31
32
|
for (const key in groupValue) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ✔ checked
|
|
5
5
|
* ✔ color
|
|
6
6
|
*/
|
|
7
|
-
import { useState, forwardRef, useEffect, useContext } from 'react';
|
|
7
|
+
import { useRef, useState, forwardRef, useEffect, useContext } from 'react';
|
|
8
8
|
import { View, StyleSheet } from 'react-native';
|
|
9
9
|
import { warn } from '@mpxjs/utils';
|
|
10
10
|
import { LabelContext, RadioGroupContext } from './context';
|
|
@@ -92,7 +92,8 @@ const Radio = forwardRef((radioProps, ref) => {
|
|
|
92
92
|
if (backgroundStyle) {
|
|
93
93
|
warn('Radio does not support background image-related styles!');
|
|
94
94
|
}
|
|
95
|
-
const
|
|
95
|
+
const nodeRef = useRef(null);
|
|
96
|
+
useNodesRef(props, ref, nodeRef, {
|
|
96
97
|
defaultStyle,
|
|
97
98
|
change: onChange
|
|
98
99
|
});
|
|
@@ -33,14 +33,16 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { ScrollView } from 'react-native-gesture-handler';
|
|
35
35
|
import { RefreshControl } from 'react-native';
|
|
36
|
-
import { useRef, useState, useEffect, forwardRef } from 'react';
|
|
36
|
+
import { 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 from './useNodesRef';
|
|
40
41
|
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren } from './utils';
|
|
42
|
+
import { IntersectionObserverContext } from './context';
|
|
41
43
|
const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
42
44
|
const { textProps, innerProps: props = {} } = splitProps(scrollViewProps);
|
|
43
|
-
const { enhanced = false, bounces = true, style = {}, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'paging-enabled': pagingEnabled = false, 'upper-threshold': upperThreshold = 50, 'lower-threshold': lowerThreshold = 50, 'scroll-with-animation': scrollWithAnimation, 'refresher-enabled': refresherEnabled, 'refresher-default-style': refresherDefaultStyle, 'refresher-background': refresherBackground, 'show-scrollbar': showScrollbar = true, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
45
|
+
const { enhanced = false, bounces = true, style = {}, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'enable-trigger-intersection-observer': enableTriggerIntersectionObserver = false, 'paging-enabled': pagingEnabled = false, 'upper-threshold': upperThreshold = 50, 'lower-threshold': lowerThreshold = 50, 'scroll-with-animation': scrollWithAnimation, 'refresher-enabled': refresherEnabled, 'refresher-default-style': refresherDefaultStyle, 'refresher-background': refresherBackground, 'show-scrollbar': showScrollbar = true, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
44
46
|
const [refreshing, setRefreshing] = useState(true);
|
|
45
47
|
const snapScrollTop = useRef(0);
|
|
46
48
|
const snapScrollLeft = useRef(0);
|
|
@@ -55,9 +57,11 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
55
57
|
const hasCallScrollToUpper = useRef(true);
|
|
56
58
|
const hasCallScrollToLower = useRef(false);
|
|
57
59
|
const initialTimeout = useRef(null);
|
|
60
|
+
const intersectionObservers = useContext(IntersectionObserverContext);
|
|
58
61
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
59
62
|
const { textStyle, innerStyle } = splitStyle(normalStyle);
|
|
60
|
-
const
|
|
63
|
+
const scrollViewRef = useAnimatedRef();
|
|
64
|
+
useNodesRef(props, ref, scrollViewRef, {
|
|
61
65
|
scrollOffset: scrollOptions,
|
|
62
66
|
node: {
|
|
63
67
|
scrollEnabled: scrollX || scrollY,
|
|
@@ -171,6 +175,11 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
171
175
|
layoutRef
|
|
172
176
|
}, props));
|
|
173
177
|
updateScrollOptions(e, { scrollLeft, scrollTop });
|
|
178
|
+
if (enableTriggerIntersectionObserver && intersectionObservers) {
|
|
179
|
+
for (const key in intersectionObservers) {
|
|
180
|
+
intersectionObservers[key].throttleMeasure();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
174
183
|
}
|
|
175
184
|
function onScrollEnd(e) {
|
|
176
185
|
const { bindscrollend } = props;
|
|
@@ -277,6 +286,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
277
286
|
'scroll-x',
|
|
278
287
|
'scroll-y',
|
|
279
288
|
'enable-back-to-top',
|
|
289
|
+
'enable-trigger-intersection-observer',
|
|
280
290
|
'paging-enabled',
|
|
281
291
|
'show-scrollbar',
|
|
282
292
|
'upper-threshold',
|
|
@@ -67,31 +67,33 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
67
67
|
const initOffsetIndex = initIndex + (props.circular && totalElements > 1 ? 1 : 0);
|
|
68
68
|
const defaultX = (defaultWidth * initOffsetIndex) || 0;
|
|
69
69
|
const defaultY = (defaultHeight * initOffsetIndex) || 0;
|
|
70
|
+
// 主动scorllTo时是否要出发onScrollEnd
|
|
71
|
+
const needTriggerScrollEnd = useRef(true);
|
|
70
72
|
// 内部存储上一次的offset值
|
|
71
73
|
const autoplayTimerRef = useRef(null);
|
|
72
|
-
const
|
|
74
|
+
const scrollViewRef = useRef(null);
|
|
75
|
+
useNodesRef(props, ref, scrollViewRef, {});
|
|
73
76
|
const {
|
|
74
77
|
// 存储layout布局信息
|
|
75
78
|
layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout: onWrapperLayout });
|
|
76
79
|
// 内部存储上一次的偏移量
|
|
77
80
|
const internalsRef = useRef({
|
|
78
81
|
offset: {
|
|
79
|
-
x:
|
|
80
|
-
y:
|
|
82
|
+
x: 0,
|
|
83
|
+
y: 0
|
|
81
84
|
},
|
|
82
85
|
isScrolling: false
|
|
83
86
|
});
|
|
84
87
|
const isDragRef = useRef(false);
|
|
85
88
|
const [state, setState] = useState({
|
|
86
|
-
children: newChild,
|
|
87
89
|
width: dir === 'x' && typeof defaultWidth === 'number' ? defaultWidth - previousMargin - nextMargin : defaultWidth,
|
|
88
90
|
height: dir === 'y' && typeof defaultHeight === 'number' ? defaultHeight - previousMargin - nextMargin : defaultHeight,
|
|
89
91
|
// 真正的游标索引, 从0开始
|
|
90
92
|
index: initIndex,
|
|
91
93
|
total: totalElements,
|
|
92
94
|
offset: {
|
|
93
|
-
x:
|
|
94
|
-
y:
|
|
95
|
+
x: 0,
|
|
96
|
+
y: 0
|
|
95
97
|
},
|
|
96
98
|
dir
|
|
97
99
|
});
|
|
@@ -112,25 +114,38 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
112
114
|
}, [props.autoplay, props.current, state.index, state.width, state.height]);
|
|
113
115
|
useEffect(() => {
|
|
114
116
|
// 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
|
|
115
|
-
if (!props.autoplay && props.current !== state.index) {
|
|
117
|
+
if (!props.autoplay && props.current !== undefined && props.current !== state.index) {
|
|
116
118
|
const initIndex = props.current || 0;
|
|
117
119
|
// 这里要排除超过元素个数的设置
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
const { nextIndex, nextOffset } = getMultiNextConfig(props.current);
|
|
121
|
+
// 1. 安卓需要主动更新下内部状态, 2. IOS不能触发完wcrollTo之后立即updateState, 会造成滑动两次
|
|
122
|
+
// 2. setTimeout 是fix 当再渲染过程中触发scrollTo失败的问题
|
|
123
|
+
if (Platform.OS === 'ios') {
|
|
124
|
+
needTriggerScrollEnd.current = false;
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
scrollViewRef.current?.scrollTo({
|
|
127
|
+
...nextOffset,
|
|
128
|
+
animated: true
|
|
129
|
+
});
|
|
130
|
+
}, 50);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
updateState(nextIndex, nextOffset);
|
|
134
|
+
}
|
|
132
135
|
}
|
|
133
|
-
}, [props.current]);
|
|
136
|
+
}, [props.current, state.width, state.height]);
|
|
137
|
+
function getMultiNextConfig(target) {
|
|
138
|
+
const step = state.dir === 'x' ? state.width : state.height;
|
|
139
|
+
const targetPos = step * props.current;
|
|
140
|
+
const targetOffset = {
|
|
141
|
+
x: dir === 'x' ? targetPos : 0,
|
|
142
|
+
y: dir === 'y' ? targetPos : 0
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
nextIndex: target,
|
|
146
|
+
nextOffset: targetOffset
|
|
147
|
+
};
|
|
148
|
+
}
|
|
134
149
|
/**
|
|
135
150
|
* @desc: 更新状态: index和offset, 并响应索引变化的事件
|
|
136
151
|
* scrollViewOffset: 移动到的目标位置
|
|
@@ -180,7 +195,6 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
180
195
|
nextIndex = isBack ? nextIndex - 2 : nextIndex;
|
|
181
196
|
}
|
|
182
197
|
if (!props.circular) {
|
|
183
|
-
// nextIndex = isBack ? nextIndex - 2 : nextIndex
|
|
184
198
|
nextOffset = Object.assign({}, currentOffset, { [state.dir]: step * nextIndex });
|
|
185
199
|
}
|
|
186
200
|
else {
|
|
@@ -229,13 +243,12 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
229
243
|
createAutoPlay();
|
|
230
244
|
return;
|
|
231
245
|
}
|
|
232
|
-
if (!Array.isArray(
|
|
246
|
+
if (!Array.isArray(props.children)) {
|
|
233
247
|
return;
|
|
234
248
|
}
|
|
235
249
|
const step = state.dir === 'x' ? state.width : state.height;
|
|
236
250
|
const { nextOffset, autoMoveOffset, isAutoEnd } = getNextConfig(state.offset);
|
|
237
251
|
// 这里可以scroll到下一个元素, 但是把scrollView的偏移量在设置为content,视觉效果就没了吧
|
|
238
|
-
// scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: true })
|
|
239
252
|
if (Platform.OS === 'ios') {
|
|
240
253
|
if (!isAutoEnd) {
|
|
241
254
|
scrollViewRef.current?.scrollTo({ x: nextOffset.x, y: nextOffset.y, animated: true });
|
|
@@ -265,7 +278,6 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
265
278
|
// 安卓无法实现视觉的无缝连接, 只能回到真正的位置, 且安卓调用scrollTo不能触发onMomentumScrollEnd,还未找到为啥
|
|
266
279
|
if (state.dir === 'x') {
|
|
267
280
|
scrollViewRef.current?.scrollTo({ x: step, y: step, animated: true });
|
|
268
|
-
// scrollViewRef.current?.scrollTo({ x: autoMoveOffset.x, y: autoMoveOffset.y, animated: true })
|
|
269
281
|
}
|
|
270
282
|
else {
|
|
271
283
|
scrollViewRef.current?.scrollTo({ x: autoMoveOffset.x, y: step, animated: true });
|
|
@@ -282,9 +294,15 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
282
294
|
}
|
|
283
295
|
/**
|
|
284
296
|
* 当用户开始拖动结束
|
|
297
|
+
* 注意: 当手动调用scrollTo的时候, 安卓不会触发onMomentumScrollEnd, IOS会触发onMomentumScrollEnd
|
|
285
298
|
*/
|
|
286
299
|
function onScrollEnd(event) {
|
|
287
|
-
|
|
300
|
+
if (Platform.OS === 'ios' && !needTriggerScrollEnd.current) {
|
|
301
|
+
const { nextIndex, nextOffset } = getMultiNextConfig(props.current);
|
|
302
|
+
updateState(nextIndex, nextOffset);
|
|
303
|
+
needTriggerScrollEnd.current = true;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
288
306
|
if (totalElements === 1) {
|
|
289
307
|
return;
|
|
290
308
|
}
|
|
@@ -310,58 +328,41 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
310
328
|
* @desc: 水平方向时,获取元素的布局,更新, 其中如果传递100%时需要依赖measure计算元算的宽高
|
|
311
329
|
*/
|
|
312
330
|
function onWrapperLayout(e) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
331
|
+
scrollViewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
|
|
332
|
+
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
|
|
333
|
+
const isWDiff = state.width !== width;
|
|
334
|
+
const isHDiff = state.height !== height;
|
|
335
|
+
if (isWDiff || isHDiff) {
|
|
336
|
+
const changeState = {
|
|
337
|
+
width: isWDiff ? width : state.width,
|
|
338
|
+
height: isHDiff ? height : state.height
|
|
339
|
+
};
|
|
340
|
+
const attr = state.dir === 'x' ? 'width' : 'height';
|
|
341
|
+
changeState[attr] = changeState[attr] - previousMargin - nextMargin;
|
|
342
|
+
const correctOffset = Object.assign({}, state.offset, {
|
|
343
|
+
[state.dir]: initOffsetIndex * (state.dir === 'x' ? changeState.width : changeState.height)
|
|
344
|
+
});
|
|
345
|
+
state.width = changeState.width;
|
|
346
|
+
state.height = changeState.height;
|
|
347
|
+
// 这里setState之后,会再触发重新渲染, renderScrollView会再次触发onScrollEnd,
|
|
348
|
+
setState((preState) => {
|
|
349
|
+
return {
|
|
350
|
+
...preState,
|
|
351
|
+
width: changeState.width,
|
|
352
|
+
height: changeState.height
|
|
327
353
|
};
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
});
|
|
333
|
-
state.offset = correctOffset;
|
|
334
|
-
state.width = changeState.width;
|
|
335
|
-
state.height = changeState.height;
|
|
336
|
-
setState((preState) => {
|
|
337
|
-
return {
|
|
338
|
-
...preState,
|
|
339
|
-
offset: correctOffset,
|
|
340
|
-
width: changeState.width,
|
|
341
|
-
height: changeState.height
|
|
342
|
-
};
|
|
343
|
-
});
|
|
344
|
-
scrollViewRef.current?.scrollTo({ x: correctOffset.x, y: correctOffset.y, animated: false });
|
|
345
|
-
}
|
|
346
|
-
props.getInnerLayout && props.getInnerLayout(layoutRef);
|
|
347
|
-
});
|
|
348
|
-
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
props.getInnerLayout && props.getInnerLayout(layoutRef);
|
|
357
|
+
});
|
|
349
358
|
}
|
|
350
359
|
function getOffset() {
|
|
351
360
|
const step = state.dir === 'x' ? state.width : state.height;
|
|
352
361
|
if (!step || Number.isNaN(+step))
|
|
353
362
|
return [];
|
|
354
363
|
const offsetArray = [];
|
|
355
|
-
|
|
356
|
-
offsetArray.push(
|
|
357
|
-
for (let i = 1; i < totalElements; i++) {
|
|
358
|
-
offsetArray.push(i * step - previousMargin);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
for (let i = 0; i < totalElements; i++) {
|
|
363
|
-
offsetArray.push(i * step);
|
|
364
|
-
}
|
|
364
|
+
for (let i = 0; i < totalElements; i++) {
|
|
365
|
+
offsetArray.push(i * step);
|
|
365
366
|
}
|
|
366
367
|
return offsetArray;
|
|
367
368
|
}
|
|
@@ -370,7 +371,7 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
370
371
|
const scrollElementProps = {
|
|
371
372
|
ref: scrollViewRef,
|
|
372
373
|
horizontal: props.horizontal,
|
|
373
|
-
pagingEnabled:
|
|
374
|
+
pagingEnabled: true,
|
|
374
375
|
snapToOffsets: offsetsArray,
|
|
375
376
|
decelerationRate: 0.99,
|
|
376
377
|
showsHorizontalScrollIndicator: false,
|
|
@@ -422,20 +423,21 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
422
423
|
</View>);
|
|
423
424
|
}
|
|
424
425
|
function renderPages() {
|
|
425
|
-
const { width, height
|
|
426
|
+
const { width, height } = state;
|
|
427
|
+
const { children } = props;
|
|
426
428
|
const { circular } = props;
|
|
427
429
|
const pageStyle = { width: width, height: height };
|
|
428
430
|
// 设置了previousMargin或者nextMargin,
|
|
429
431
|
// 1. 元素的宽度是减去这两个数目之和
|
|
430
432
|
// 2. previousMargin设置marginLeft正值, nextmargin设置marginRight负值
|
|
431
433
|
// 3. 第一个元素设置previousMargin 和 nextMargin, 最后一个元素
|
|
432
|
-
if (
|
|
434
|
+
if (totalElements > 1 && Array.isArray(children)) {
|
|
433
435
|
let arrElements = [];
|
|
434
436
|
// pages = ["2", "0", "1", "2", "0"]
|
|
435
437
|
const pages = Array.isArray(children) ? Object.keys(children) : [];
|
|
436
438
|
/* 无限循环的时候 */
|
|
437
439
|
if (circular) {
|
|
438
|
-
pages.unshift(
|
|
440
|
+
pages.unshift(totalElements - 1 + '');
|
|
439
441
|
pages.push('0');
|
|
440
442
|
}
|
|
441
443
|
arrElements = pages.map((page, i) => {
|
|
@@ -446,7 +448,6 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
446
448
|
else if (i === pages.length - 1 && typeof width === 'number') {
|
|
447
449
|
nextMargin && (extraStyle.marginRight = nextMargin);
|
|
448
450
|
}
|
|
449
|
-
// return (<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>{children[+page]}</View>)
|
|
450
451
|
return (<View style={[pageStyle, styles.slide, extraStyle]} key={'page' + i}>
|
|
451
452
|
{wrapChildren({
|
|
452
453
|
children: children[+page]
|
|
@@ -43,7 +43,8 @@ const _SwiperWrapper = forwardRef((props, ref) => {
|
|
|
43
43
|
bindchange: props.bindchange,
|
|
44
44
|
easingFunction: props['easing-function'] || 'default'
|
|
45
45
|
};
|
|
46
|
-
const
|
|
46
|
+
const nodeRef = useRef(null);
|
|
47
|
+
useNodesRef(props, ref, nodeRef, {});
|
|
47
48
|
const innerProps = useInnerProps(props, {
|
|
48
49
|
ref: nodeRef
|
|
49
50
|
}, [
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { View } from 'react-native';
|
|
2
|
-
import { forwardRef } from 'react';
|
|
2
|
+
import { forwardRef, useRef } from 'react';
|
|
3
3
|
import useInnerProps from './getInnerListeners';
|
|
4
4
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
5
5
|
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils';
|
|
6
6
|
const _SwiperItem = forwardRef((props, ref) => {
|
|
7
7
|
const { 'enable-offset': enableOffset, 'enable-var': enableVar, 'external-var-context': externalVarContext, style } = props;
|
|
8
8
|
const { textProps } = splitProps(props);
|
|
9
|
-
const
|
|
9
|
+
const nodeRef = useRef(null);
|
|
10
|
+
useNodesRef(props, ref, nodeRef, {});
|
|
10
11
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
|
|
11
12
|
const { textStyle, innerStyle } = splitStyle(normalStyle);
|
|
12
13
|
const {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* ✔ color
|
|
6
6
|
*/
|
|
7
7
|
import { Switch } from 'react-native';
|
|
8
|
-
import { useEffect, forwardRef, useState, useContext } from 'react';
|
|
8
|
+
import { useRef, useEffect, forwardRef, useState, useContext } from 'react';
|
|
9
9
|
import { warn } from '@mpxjs/utils';
|
|
10
10
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
11
11
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
@@ -31,7 +31,8 @@ const _Switch = forwardRef((props, ref) => {
|
|
|
31
31
|
useEffect(() => {
|
|
32
32
|
setIsChecked(checked);
|
|
33
33
|
}, [checked]);
|
|
34
|
-
const
|
|
34
|
+
const nodeRef = useRef(null);
|
|
35
|
+
useNodesRef(props, ref, nodeRef);
|
|
35
36
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
36
37
|
const onChange = (evt, { checked } = {}) => {
|
|
37
38
|
if (type === 'switch') {
|
|
@@ -18,7 +18,8 @@ const _Text = forwardRef((props, ref) => {
|
|
|
18
18
|
parentWidth,
|
|
19
19
|
parentHeight
|
|
20
20
|
});
|
|
21
|
-
const
|
|
21
|
+
const nodeRef = useRef(null);
|
|
22
|
+
useNodesRef(props, ref, nodeRef);
|
|
22
23
|
const innerProps = useInnerProps(props, {
|
|
23
24
|
ref: nodeRef,
|
|
24
25
|
style: normalStyle,
|