@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.
Files changed (80) hide show
  1. package/lib/config.js +38 -10
  2. package/lib/index.js +5 -1
  3. package/lib/platform/style/wx/index.js +66 -60
  4. package/lib/platform/template/wx/index.js +12 -8
  5. package/lib/react/processTemplate.js +4 -2
  6. package/lib/react/style-helper.js +2 -5
  7. package/lib/runtime/components/react/context.ts +8 -0
  8. package/lib/runtime/components/react/dist/context.js +1 -0
  9. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -1
  10. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -1
  11. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +3 -2
  12. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -1
  13. package/lib/runtime/components/react/dist/mpx-icon.jsx +3 -2
  14. package/lib/runtime/components/react/dist/mpx-image/index.jsx +2 -1
  15. package/lib/runtime/components/react/dist/mpx-input.jsx +2 -1
  16. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -1
  17. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -2
  18. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -1
  19. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +2 -1
  20. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -1
  21. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -1
  22. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +2 -1
  23. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +2 -1
  24. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +4 -2
  25. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -2
  26. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +2 -1
  27. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -1
  28. package/lib/runtime/components/react/dist/mpx-radio.jsx +3 -2
  29. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -3
  30. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +78 -77
  31. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +2 -1
  32. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -2
  33. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -2
  34. package/lib/runtime/components/react/dist/mpx-text.jsx +2 -1
  35. package/lib/runtime/components/react/dist/mpx-view.jsx +45 -15
  36. package/lib/runtime/components/react/dist/mpx-web-view.jsx +4 -3
  37. package/lib/runtime/components/react/dist/useAnimationHooks.js +215 -0
  38. package/lib/runtime/components/react/dist/useNodesRef.js +1 -5
  39. package/lib/runtime/components/react/dist/utils.jsx +50 -37
  40. package/lib/runtime/components/react/mpx-button.tsx +3 -1
  41. package/lib/runtime/components/react/mpx-checkbox-group.tsx +3 -1
  42. package/lib/runtime/components/react/mpx-checkbox.tsx +4 -1
  43. package/lib/runtime/components/react/mpx-form.tsx +2 -1
  44. package/lib/runtime/components/react/mpx-icon.tsx +3 -2
  45. package/lib/runtime/components/react/mpx-image/index.tsx +2 -1
  46. package/lib/runtime/components/react/mpx-input.tsx +2 -1
  47. package/lib/runtime/components/react/mpx-label.tsx +2 -1
  48. package/lib/runtime/components/react/mpx-movable-area.tsx +3 -2
  49. package/lib/runtime/components/react/mpx-movable-view.tsx +2 -1
  50. package/lib/runtime/components/react/mpx-picker/date.tsx +2 -1
  51. package/lib/runtime/components/react/mpx-picker/index.tsx +2 -1
  52. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +2 -1
  53. package/lib/runtime/components/react/mpx-picker/region.tsx +2 -1
  54. package/lib/runtime/components/react/mpx-picker/selector.tsx +2 -1
  55. package/lib/runtime/components/react/mpx-picker/time.tsx +4 -2
  56. package/lib/runtime/components/react/mpx-picker-view-column.tsx +3 -2
  57. package/lib/runtime/components/react/mpx-picker-view.tsx +2 -1
  58. package/lib/runtime/components/react/mpx-radio-group.tsx +2 -1
  59. package/lib/runtime/components/react/mpx-radio.tsx +3 -2
  60. package/lib/runtime/components/react/mpx-scroll-view.tsx +14 -2
  61. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -75
  62. package/lib/runtime/components/react/mpx-swiper/index.tsx +4 -1
  63. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -1
  64. package/lib/runtime/components/react/mpx-switch.tsx +2 -1
  65. package/lib/runtime/components/react/mpx-text.tsx +2 -1
  66. package/lib/runtime/components/react/mpx-view.tsx +55 -23
  67. package/lib/runtime/components/react/mpx-web-view.tsx +4 -3
  68. package/lib/runtime/components/react/types/common.ts +8 -2
  69. package/lib/runtime/components/react/types/global.d.ts +11 -1
  70. package/lib/runtime/components/react/useAnimationHooks.ts +248 -0
  71. package/lib/runtime/components/react/useNodesRef.ts +1 -6
  72. package/lib/runtime/components/react/utils.tsx +71 -50
  73. package/lib/runtime/components/web/mpx-scroll-view.vue +25 -5
  74. package/lib/style-compiler/index.js +5 -4
  75. package/lib/template-compiler/compiler.js +127 -158
  76. package/lib/utils/const.js +2 -1
  77. package/lib/web/processStyles.js +6 -2
  78. package/lib/web/processTemplate.js +2 -3
  79. package/lib/wxml/loader.js +1 -1
  80. 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 { nodeRef: movableViewRef } = useNodesRef(props, ref);
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 { nodeRef } = useNodesRef(props, ref, {
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 { nodeRef: viewRef } = useNodesRef(props, ref, {});
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 { nodeRef } = useNodesRef(props, ref, {});
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 { nodeRef: viewRef } = useNodesRef(props, ref, {});
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 { nodeRef: viewRef } = useNodesRef(props, ref, {});
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 { nodeRef: viewRef } = useNodesRef(props, ref, {});
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 { nodeRef: viewRef } = useNodesRef(props, ref, {});
129
+ const viewRef = useRef(null);
130
+ useNodesRef(props, ref, viewRef, {});
130
131
  // 存储modal的布局信息
131
132
  const modalLayoutRef = useRef({});
132
- const { nodeRef: modalRef } = useNodesRef(props, ref, {});
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 { nodeRef: scrollViewRef } = useNodesRef(props, ref, {});
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 { nodeRef } = useNodesRef(props, ref, {});
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 { nodeRef } = useNodesRef(props, ref, { defaultStyle });
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 { nodeRef } = useNodesRef(props, ref, {
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 { nodeRef: scrollViewRef } = useNodesRef(props, ref, {
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 { nodeRef: scrollViewRef } = useNodesRef(props, ref, {});
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: defaultX || 0,
80
- y: defaultY || 0
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: dir === 'x' ? defaultX : 0,
94
- y: dir === 'y' ? defaultY : 0
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 initOffsetIndex = initIndex + (props.circular && totalElements > 1 ? 1 : 0);
119
- const defaultX = (defaultWidth * initOffsetIndex) || 0;
120
- const offset = {
121
- x: dir === 'x' ? defaultX : 0,
122
- y: dir === 'y' ? defaultY : 0
123
- };
124
- state.offset = offset;
125
- internalsRef.current.offset = offset;
126
- setState((preState) => {
127
- return {
128
- ...preState,
129
- offset
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(state.children)) {
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
- // 这里安卓好像没有触发onScrollEnd, 调用scrollTo的时候
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
- if (hasSelfPercent) {
314
- const { width, height } = e?.nativeEvent?.layout || {};
315
- setWidth(width || 0);
316
- setHeight(height || 0);
317
- }
318
- if (props.enableOffset) {
319
- scrollViewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
320
- layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
321
- const isWDiff = state.width !== width;
322
- const isHDiff = state.height !== height;
323
- if (isWDiff || isHDiff) {
324
- const changeState = {
325
- width: isWDiff ? width : state.width,
326
- height: isHDiff ? height : state.height
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
- const attr = state.dir === 'x' ? 'width' : 'height';
329
- changeState[attr] = changeState[attr] - previousMargin - nextMargin;
330
- const correctOffset = Object.assign({}, state.offset, {
331
- [state.dir]: initOffsetIndex * (state.dir === 'x' ? changeState.width : changeState.height)
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
- if (previousMargin) {
356
- offsetArray.push(0);
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: false,
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, total, children } = state;
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 (total > 1 && Array.isArray(children)) {
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(total - 1 + '');
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 { nodeRef } = useNodesRef(props, ref, {});
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 { nodeRef } = useNodesRef(props, ref, {});
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 { nodeRef } = useNodesRef(props, ref);
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 { nodeRef } = useNodesRef(props, ref);
21
+ const nodeRef = useRef(null);
22
+ useNodesRef(props, ref, nodeRef);
22
23
  const innerProps = useInnerProps(props, {
23
24
  ref: nodeRef,
24
25
  style: normalStyle,