@mpxjs/webpack-plugin 2.10.4-beta.19-input → 2.10.4-beta.19-input1

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 (34) hide show
  1. package/lib/runtime/components/react/dist/getInnerListeners.js +22 -36
  2. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -7
  3. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +4 -2
  4. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +17 -20
  5. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -7
  6. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -7
  7. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -7
  8. package/lib/runtime/components/react/dist/mpx-image.jsx +20 -33
  9. package/lib/runtime/components/react/dist/mpx-input.jsx +9 -14
  10. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -7
  11. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -8
  12. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +79 -205
  13. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +13 -11
  14. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +7 -8
  15. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +11 -29
  16. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +5 -3
  17. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -9
  18. package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -7
  19. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +2 -10
  20. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +51 -104
  21. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +1 -3
  22. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +9 -11
  23. package/lib/runtime/components/react/dist/mpx-swiper.jsx +141 -203
  24. package/lib/runtime/components/react/dist/mpx-switch.jsx +2 -7
  25. package/lib/runtime/components/react/dist/mpx-text.jsx +2 -7
  26. package/lib/runtime/components/react/dist/mpx-video.jsx +2 -7
  27. package/lib/runtime/components/react/dist/mpx-view.jsx +26 -28
  28. package/lib/runtime/components/react/dist/mpx-web-view.jsx +29 -34
  29. package/lib/runtime/components/react/dist/useAnimationHooks.js +89 -12
  30. package/lib/runtime/components/react/dist/utils.jsx +114 -199
  31. package/package.json +1 -1
  32. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +0 -145
  33. package/lib/runtime/components/react/dist/mpx-progress.jsx +0 -163
  34. package/lib/runtime/components/react/dist/mpx-slider.jsx +0 -321
@@ -1,12 +1,11 @@
1
1
  import { View } from 'react-native';
2
2
  import { GestureDetector, Gesture } from 'react-native-gesture-handler';
3
3
  import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS, useAnimatedReaction, cancelAnimation } from 'react-native-reanimated';
4
- import React, { forwardRef, useRef, useEffect, useMemo, createElement } from 'react';
4
+ import React, { forwardRef, useRef, useEffect, useMemo } from 'react';
5
5
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
6
6
  import useNodesRef from './useNodesRef'; // 引入辅助函数
7
- import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject, flatGesture, useRunOnJSCallback } from './utils';
7
+ import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject, flatGesture } from './utils';
8
8
  import { SwiperContext } from './context';
9
- import Portal from './mpx-portal';
10
9
  /**
11
10
  * 默认的Style类型
12
11
  */
@@ -71,19 +70,16 @@ const easeMap = {
71
70
  easeInOutCubic: Easing.inOut(Easing.cubic)
72
71
  };
73
72
  const SwiperWrapper = forwardRef((props, ref) => {
74
- const { 'indicator-dots': showPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, autoplay = false, circular = false, disableGesture = false, current: propCurrent = 0, bindchange } = props;
73
+ const { 'indicator-dots': showsPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, autoplay = false, circular = false, disableGesture = false } = props;
75
74
  const easeingFunc = props['easing-function'] || 'default';
76
75
  const easeDuration = props.duration || 500;
77
76
  const horizontal = props.vertical !== undefined ? !props.vertical : true;
78
77
  const nodeRef = useRef(null);
79
78
  // 手势协同gesture 1.0
80
79
  const swiperGestureRef = useRef();
81
- useNodesRef(props, ref, nodeRef, {
82
- // scrollView内部会过滤是否绑定了gestureRef,withRef(swiperGestureRef)给gesture对象设置一个ref(2.0版本)
83
- gestureRef: swiperGestureRef
84
- });
80
+ useNodesRef(props, ref, nodeRef, {});
85
81
  // 计算transfrom之类的
86
- const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, hasPositionFixed, setWidth, setHeight } = useTransformStyle(style, {
82
+ const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, {
87
83
  enableVar,
88
84
  externalVarContext,
89
85
  parentFontSize,
@@ -112,18 +108,23 @@ const SwiperWrapper = forwardRef((props, ref) => {
112
108
  // 每个元素的宽度 or 高度,有固定值直接初始化无则0
113
109
  const step = useSharedValue(initStep);
114
110
  // 记录选中元素的索引值
115
- const currentIndex = useSharedValue(propCurrent);
111
+ const currentIndex = useSharedValue(props.current || 0);
116
112
  // const initOffset = getOffset(props.current || 0, initStep)
117
113
  // 记录元素的偏移量
118
- const offset = useSharedValue(getOffset(propCurrent, initStep));
114
+ const offset = useSharedValue(getOffset(props.current || 0, initStep));
119
115
  const strAbso = 'absolute' + dir.toUpperCase();
120
- const strVelocity = 'velocity' + dir.toUpperCase();
121
116
  // 标识手指触摸和抬起, 起点在onBegin
122
117
  const touchfinish = useSharedValue(true);
123
118
  // 记录上一帧的绝对定位坐标
124
119
  const preAbsolutePos = useSharedValue(0);
125
120
  // 记录从onBegin 到 onTouchesUp 时移动的距离
126
121
  const moveTranstion = useSharedValue(0);
122
+ // 记录从onBegin 到 onTouchesUp 的时间
123
+ const moveTime = useSharedValue(0);
124
+ // 记录从onBegin 到 onTouchesCancelled 另外一个方向移动的距离
125
+ const anotherDirectionMove = useSharedValue(0);
126
+ // 另一个方向的
127
+ const anotherAbso = 'absolute' + (dir === 'x' ? 'y' : 'x').toUpperCase();
127
128
  const timerId = useRef(0);
128
129
  const intervalTimer = props.interval || 500;
129
130
  const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
@@ -170,7 +171,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
170
171
  const iStep = dir === 'x' ? realWidth : realHeight;
171
172
  if (iStep !== step.value) {
172
173
  step.value = iStep;
173
- updateCurrent(propCurrent, iStep);
174
+ updateCurrent(props.current || 0, iStep);
174
175
  updateAutoplay();
175
176
  }
176
177
  }
@@ -186,6 +187,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
186
187
  }
187
188
  });
188
189
  function renderPagination() {
190
+ if (children.length <= 1)
191
+ return null;
189
192
  const activeColor = activeDotColor || '#007aff';
190
193
  const unActionColor = dotColor || 'rgba(0,0,0,.2)';
191
194
  // 正常渲染所有dots
@@ -272,7 +275,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
272
275
  easing: easeMap[easeingFunc]
273
276
  }, () => {
274
277
  currentIndex.value = nextIndex;
275
- runOnJS(runOnJSCallback)('loop');
278
+ runOnJS(loop)();
276
279
  });
277
280
  }
278
281
  else {
@@ -288,7 +291,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
288
291
  // 将开始位置设置为真正的位置
289
292
  offset.value = initOffset;
290
293
  currentIndex.value = nextIndex;
291
- runOnJS(runOnJSCallback)('loop');
294
+ runOnJS(loop)();
292
295
  });
293
296
  }
294
297
  else {
@@ -300,7 +303,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
300
303
  easing: easeMap[easeingFunc]
301
304
  }, () => {
302
305
  currentIndex.value = nextIndex;
303
- runOnJS(runOnJSCallback)('loop');
306
+ runOnJS(loop)();
304
307
  });
305
308
  }
306
309
  }
@@ -325,19 +328,12 @@ const SwiperWrapper = forwardRef((props, ref) => {
325
328
  resumeLoop
326
329
  };
327
330
  }, []);
328
- function handleSwiperChange(current, pCurrent) {
329
- if (pCurrent !== currentIndex.value) {
331
+ function handleSwiperChange(current) {
332
+ if (props.current !== currentIndex.value) {
330
333
  const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef });
331
- bindchange && bindchange(eventData);
334
+ props.bindchange && props.bindchange(eventData);
332
335
  }
333
336
  }
334
- const runOnJSCallbackRef = useRef({
335
- loop,
336
- pauseLoop,
337
- resumeLoop,
338
- handleSwiperChange
339
- });
340
- const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
341
337
  function getOffset(index, stepValue) {
342
338
  if (!stepValue)
343
339
  return 0;
@@ -355,12 +351,12 @@ const SwiperWrapper = forwardRef((props, ref) => {
355
351
  const targetOffset = getOffset(index || 0, stepValue);
356
352
  if (targetOffset !== offset.value) {
357
353
  // 内部基于props.current!==currentIndex.value决定是否使用动画及更新currentIndex.value
358
- if (propCurrent !== undefined && propCurrent !== currentIndex.value) {
354
+ if (props.current !== undefined && props.current !== currentIndex.value) {
359
355
  offset.value = withTiming(targetOffset, {
360
356
  duration: easeDuration,
361
357
  easing: easeMap[easeingFunc]
362
358
  }, () => {
363
- currentIndex.value = propCurrent;
359
+ currentIndex.value = props.current || 0;
364
360
  });
365
361
  }
366
362
  else {
@@ -379,8 +375,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
379
375
  // 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
380
376
  useAnimatedReaction(() => currentIndex.value, (newIndex, preIndex) => {
381
377
  // 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
382
- if (newIndex !== preIndex && bindchange) {
383
- runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent);
378
+ if (newIndex !== preIndex && props.bindchange) {
379
+ runOnJS(handleSwiperChange)(newIndex);
384
380
  }
385
381
  });
386
382
  useEffect(() => {
@@ -412,11 +408,11 @@ const SwiperWrapper = forwardRef((props, ref) => {
412
408
  }, [children.length]);
413
409
  useEffect(() => {
414
410
  // 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
415
- // 2. 手指滑动过程中更新索引,外部会把current再传入进来,导致offset直接更新,增加判断不同才更新
416
- if (propCurrent !== currentIndex.value) {
417
- updateCurrent(propCurrent, step.value);
411
+ // 2. 手指滑动过程中更新索引,外部会把current再穿进来,导致offset直接更新了
412
+ if (props.current !== currentIndex.value) {
413
+ updateCurrent(props.current || 0, step.value);
418
414
  }
419
- }, [propCurrent]);
415
+ }, [props.current]);
420
416
  useEffect(() => {
421
417
  autoplayShared.value = autoplay;
422
418
  updateAutoplay();
@@ -437,7 +433,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
437
433
  function getTargetPosition(eventData) {
438
434
  'worklet';
439
435
  // 移动的距离
440
- const { transdir } = eventData;
436
+ const { translation } = eventData;
441
437
  let resetOffsetPos = 0;
442
438
  let selectedIndex = currentIndex.value;
443
439
  // 是否临界点
@@ -445,9 +441,9 @@ const SwiperWrapper = forwardRef((props, ref) => {
445
441
  // 真实滚动到的偏移量坐标
446
442
  let moveToTargetPos = 0;
447
443
  const tmp = !circularShared.value ? 0 : preMarginShared.value;
448
- const currentOffset = transdir < 0 ? offset.value - tmp : offset.value + tmp;
444
+ const currentOffset = translation < 0 ? offset.value - tmp : offset.value + tmp;
449
445
  const computedIndex = Math.abs(currentOffset) / step.value;
450
- const moveToIndex = transdir < 0 ? Math.ceil(computedIndex) : Math.floor(computedIndex);
446
+ const moveToIndex = translation < 0 ? Math.ceil(computedIndex) : Math.floor(computedIndex);
451
447
  // 实际应该定位的索引值
452
448
  if (!circularShared.value) {
453
449
  selectedIndex = moveToIndex;
@@ -478,24 +474,26 @@ const SwiperWrapper = forwardRef((props, ref) => {
478
474
  targetOffset: -moveToTargetPos
479
475
  };
480
476
  }
481
- function canMove(eventData) {
477
+ function checkUnCircular(eventData) {
482
478
  'worklet';
483
- // 旧版:如果在快速多次滑动时,只根据当前的offset判断,会出现offset没超出,加上translation后越界的场景(如在倒数第二个元素快速滑动)
484
- // 新版:会加上translation
485
- const { translation, transdir } = eventData;
486
- const gestureMovePos = offset.value + translation;
487
- if (!circularShared.value) {
488
- // 如果只判断区间,中间非滑动状态(handleResistanceMove)向左滑动,突然改为向右滑动,但是还在非滑动态,本应该可滑动判断为了不可滑动
489
- const posEnd = -step.value * (childrenLength.value - 1);
490
- if (transdir < 0) {
491
- return gestureMovePos > posEnd;
492
- }
493
- else {
494
- return gestureMovePos < 0;
495
- }
479
+ const { translation } = eventData;
480
+ const currentOffset = Math.abs(offset.value);
481
+ // 向右滑动swiper
482
+ if (translation < 0) {
483
+ const boundaryOffset = step.value * (childrenLength.value - 1);
484
+ const gestureMovePos = Math.abs(translation) + currentOffset;
485
+ return {
486
+ // 防止快速连续向右滑动时,手势移动的距离 当前的offset超出边界
487
+ targetOffset: gestureMovePos > boundaryOffset ? -boundaryOffset : offset.value + translation,
488
+ canMove: currentOffset < boundaryOffset
489
+ };
496
490
  }
497
491
  else {
498
- return true;
492
+ const gestureMovePos = currentOffset - translation;
493
+ return {
494
+ targetOffset: gestureMovePos < 0 ? 0 : offset.value + translation,
495
+ canMove: currentOffset > 0
496
+ };
499
497
  }
500
498
  }
501
499
  function handleEnd(eventData) {
@@ -509,7 +507,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
509
507
  if (touchfinish.value !== false) {
510
508
  currentIndex.value = selectedIndex;
511
509
  offset.value = resetOffset;
512
- runOnJS(runOnJSCallback)('resumeLoop');
510
+ runOnJS(resumeLoop)();
513
511
  }
514
512
  });
515
513
  }
@@ -520,21 +518,21 @@ const SwiperWrapper = forwardRef((props, ref) => {
520
518
  }, () => {
521
519
  if (touchfinish.value !== false) {
522
520
  currentIndex.value = selectedIndex;
523
- runOnJS(runOnJSCallback)('resumeLoop');
521
+ runOnJS(resumeLoop)();
524
522
  }
525
523
  });
526
524
  }
527
525
  }
528
526
  function handleBack(eventData) {
529
527
  'worklet';
530
- const { transdir } = eventData;
528
+ const { translation } = eventData;
531
529
  // 向右滑动的back:trans < 0, 向左滑动的back: trans < 0
532
530
  let currentOffset = Math.abs(offset.value);
533
531
  if (circularShared.value) {
534
- currentOffset += transdir < 0 ? preMarginShared.value : -preMarginShared.value;
532
+ currentOffset += translation < 0 ? preMarginShared.value : -preMarginShared.value;
535
533
  }
536
534
  const curIndex = currentOffset / step.value;
537
- const moveToIndex = (transdir < 0 ? Math.floor(curIndex) : Math.ceil(curIndex)) - patchElmNumShared.value;
535
+ const moveToIndex = (translation < 0 ? Math.floor(curIndex) : Math.ceil(curIndex)) - patchElmNumShared.value;
538
536
  const targetOffset = -(moveToIndex + patchElmNumShared.value) * step.value + (circularShared.value ? preMarginShared.value : 0);
539
537
  offset.value = withTiming(targetOffset, {
540
538
  duration: easeDuration,
@@ -542,106 +540,77 @@ const SwiperWrapper = forwardRef((props, ref) => {
542
540
  }, () => {
543
541
  if (touchfinish.value !== false) {
544
542
  currentIndex.value = moveToIndex;
545
- runOnJS(runOnJSCallback)('resumeLoop');
543
+ runOnJS(resumeLoop)();
546
544
  }
547
545
  });
548
546
  }
549
- // 当前的offset和index多对应的offset进行对比,判断是否超过一半
550
- function computeHalf(eventData) {
547
+ function computeHalf() {
551
548
  'worklet';
552
- const { transdir } = eventData;
553
549
  const currentOffset = Math.abs(offset.value);
554
550
  let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value;
555
551
  if (circularShared.value) {
556
552
  preOffset -= preMarginShared.value;
557
553
  }
558
- // 正常事件中拿到的translation值(正向滑动<0,倒着滑>0)
554
+ // 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
559
555
  const diffOffset = preOffset - currentOffset;
560
556
  const half = Math.abs(diffOffset) > step.value / 2;
561
- const isTriggerUpdateHalf = (transdir < 0 && currentOffset < preOffset) || (transdir > 0 && currentOffset > preOffset);
562
557
  return {
563
558
  diffOffset,
564
- half,
565
- isTriggerUpdateHalf
559
+ half
566
560
  };
567
561
  }
568
- function handleLongPress(eventData) {
562
+ function handleLongPress() {
569
563
  'worklet';
570
- const { diffOffset, half, isTriggerUpdateHalf } = computeHalf(eventData);
564
+ const { diffOffset, half } = computeHalf();
571
565
  if (+diffOffset === 0) {
572
- runOnJS(runOnJSCallback)('resumeLoop');
573
- }
574
- else if (isTriggerUpdateHalf) {
575
- // 如果触发了onUpdate时的索引变更
576
- handleEnd(eventData);
566
+ runOnJS(resumeLoop)();
577
567
  }
578
568
  else if (half) {
579
- handleEnd(eventData);
569
+ handleEnd({ translation: diffOffset });
580
570
  }
581
571
  else {
582
- handleBack(eventData);
572
+ handleBack({ translation: diffOffset });
583
573
  }
584
574
  }
585
575
  function reachBoundary(eventData) {
586
576
  'worklet';
587
- // 1. 基于当前的offset和translation判断是否超过当前边界值
577
+ // 移动的距离
588
578
  const { translation } = eventData;
589
- const boundaryStart = -patchElmNumShared.value * step.value;
590
- const boundaryEnd = -(childrenLength.value + patchElmNumShared.value) * step.value;
591
- const moveToOffset = offset.value + translation;
579
+ const elementsLength = step.value * childrenLength.value;
592
580
  let isBoundary = false;
593
581
  let resetOffset = 0;
594
- if (moveToOffset < boundaryEnd) {
595
- isBoundary = true;
596
- // 超过边界的距离
597
- const exceedLength = Math.abs(moveToOffset) - Math.abs(boundaryEnd);
598
- // 计算对标正常元素所在的offset
599
- resetOffset = patchElmNumShared.value * step.value + exceedLength;
582
+ // Y轴向下滚动, transDistance > 0, 向上滚动 < 0 X轴向左滚动, transDistance > 0
583
+ const currentOffset = offset.value;
584
+ const moveStep = Math.ceil(translation / elementsLength);
585
+ if (translation < 0) {
586
+ const posEnd = (childrenLength.value + patchElmNumShared.value + 1) * step.value;
587
+ const posReverseEnd = (patchElmNumShared.value - 1) * step.value;
588
+ if (currentOffset < -posEnd + step.value) {
589
+ isBoundary = true;
590
+ resetOffset = Math.abs(moveStep) === 0 ? patchElmNumShared.value * step.value + translation : moveStep * elementsLength;
591
+ }
592
+ if (currentOffset > -posReverseEnd) {
593
+ isBoundary = true;
594
+ resetOffset = moveStep * elementsLength;
595
+ }
600
596
  }
601
- if (moveToOffset > boundaryStart) {
602
- isBoundary = true;
603
- // 超过边界的距离
604
- const exceedLength = Math.abs(boundaryStart) - Math.abs(moveToOffset);
605
- // 计算对标正常元素所在的offset
606
- resetOffset = (patchElmNumShared.value + childrenLength.value - 1) * step.value + (step.value - exceedLength);
597
+ else if (translation > 0) {
598
+ const posEnd = (patchElmNumShared.value - 1) * step.value;
599
+ const posReverseEnd = (patchElmNumShared.value + childrenLength.value) * step.value;
600
+ if (currentOffset > -posEnd) {
601
+ isBoundary = true;
602
+ resetOffset = moveStep * elementsLength + step.value + (moveStep === 1 ? translation : 0);
603
+ }
604
+ if (currentOffset < -posReverseEnd) {
605
+ isBoundary = true;
606
+ resetOffset = moveStep * elementsLength + patchElmNumShared.value * step.value;
607
+ }
607
608
  }
608
609
  return {
609
610
  isBoundary,
610
611
  resetOffset: -resetOffset
611
612
  };
612
613
  }
613
- // 非循环超出边界,应用阻力; 开始滑动少阻力小,滑动越长阻力越大
614
- function handleResistanceMove(eventData) {
615
- 'worklet';
616
- const { translation, transdir } = eventData;
617
- const moveToOffset = offset.value + translation;
618
- const maxOverDrag = Math.floor(step.value / 2);
619
- const maxOffset = translation < 0 ? -(childrenLength.value - 1) * step.value : 0;
620
- let resistance = 0.1;
621
- let overDrag = 0;
622
- let finalOffset = 0;
623
- // 向右向下小于0, 向左向上大于0;
624
- if (transdir < 0) {
625
- overDrag = Math.abs(moveToOffset - maxOffset);
626
- }
627
- else {
628
- overDrag = Math.abs(moveToOffset);
629
- }
630
- // 滑动越多resistance越小
631
- resistance = 1 - overDrag / maxOverDrag;
632
- // 确保阻力在合理范围内
633
- resistance = Math.min(0.5, resistance);
634
- // 限制在最大拖拽范围内
635
- if (transdir < 0) {
636
- const adjustOffset = offset.value + translation * resistance;
637
- finalOffset = Math.max(adjustOffset, maxOffset - maxOverDrag);
638
- }
639
- else {
640
- const adjustOffset = offset.value + translation * resistance;
641
- finalOffset = Math.min(adjustOffset, maxOverDrag);
642
- }
643
- return finalOffset;
644
- }
645
614
  const gesturePan = Gesture.Pan()
646
615
  .onBegin((e) => {
647
616
  'worklet';
@@ -649,47 +618,37 @@ const SwiperWrapper = forwardRef((props, ref) => {
649
618
  return;
650
619
  touchfinish.value = false;
651
620
  cancelAnimation(offset);
652
- runOnJS(runOnJSCallback)('pauseLoop');
621
+ runOnJS(pauseLoop)();
653
622
  preAbsolutePos.value = e[strAbso];
654
623
  moveTranstion.value = e[strAbso];
624
+ anotherDirectionMove.value = e[anotherAbso];
625
+ moveTime.value = new Date().getTime();
655
626
  })
656
627
  .onUpdate((e) => {
657
628
  'worklet';
658
- const moveDistance = e[strAbso] - preAbsolutePos.value;
659
- if (touchfinish.value || moveDistance === 0)
629
+ if (touchfinish.value)
660
630
  return;
631
+ const moveDistance = e[strAbso] - preAbsolutePos.value;
661
632
  const eventData = {
662
- translation: moveDistance,
663
- transdir: moveDistance
633
+ translation: moveDistance
664
634
  };
665
- // 1. 支持滑动中超出一半更新索引的能力:只更新索引并不会影响onFinalize依据当前offset计算的索引
666
- const { half } = computeHalf(eventData);
667
- if (childrenLength.value > 1 && half) {
635
+ // 1. 在Move过程中,如果手指一直没抬起来,超过一半的话也会更新索引
636
+ const { half } = computeHalf();
637
+ if (half) {
668
638
  const { selectedIndex } = getTargetPosition(eventData);
669
639
  currentIndex.value = selectedIndex;
670
640
  }
671
- // 2. 非循环: 处理用户一直拖拽到临界点的场景,如果放到onFinalize无法阻止offset.value更新为越界的值
641
+ // 2. 处理用户一直拖拽到临界点的场景, 不会执行onEnd
642
+ const { canMove, targetOffset } = checkUnCircular(eventData);
672
643
  if (!circularShared.value) {
673
- if (canMove(eventData)) {
674
- offset.value = moveDistance + offset.value;
644
+ if (canMove) {
645
+ offset.value = targetOffset;
646
+ preAbsolutePos.value = e[strAbso];
675
647
  }
676
- else {
677
- const finalOffset = handleResistanceMove(eventData);
678
- offset.value = finalOffset;
679
- }
680
- preAbsolutePos.value = e[strAbso];
681
- return;
682
- }
683
- // 3. 循环更新: 只有一个元素时可滑动,加入阻力
684
- if (circularShared.value && childrenLength.value === 1) {
685
- const finalOffset = handleResistanceMove(eventData);
686
- offset.value = finalOffset;
687
- preAbsolutePos.value = e[strAbso];
688
648
  return;
689
649
  }
690
- // 4. 循环更新:正常
691
650
  const { isBoundary, resetOffset } = reachBoundary(eventData);
692
- if (childrenLength.value > 1 && isBoundary && circularShared.value) {
651
+ if (isBoundary && circularShared.value) {
693
652
  offset.value = resetOffset;
694
653
  }
695
654
  else {
@@ -701,49 +660,26 @@ const SwiperWrapper = forwardRef((props, ref) => {
701
660
  'worklet';
702
661
  if (touchfinish.value)
703
662
  return;
663
+ const moveDistance = e[strAbso] - moveTranstion.value;
704
664
  touchfinish.value = true;
705
- // 触发过onUpdate正常情况下e[strAbso] - preAbsolutePos.value=0; 未触发过onUpdate的情况下e[strAbso] - preAbsolutePos.value 不为0
706
- const moveDistance = e[strAbso] - preAbsolutePos.value;
707
665
  const eventData = {
708
- translation: moveDistance,
709
- transdir: moveDistance !== 0 ? moveDistance : e[strAbso] - moveTranstion.value
666
+ translation: moveDistance
710
667
  };
711
- // 1. 只有一个元素:循环 非循环状态,都走回弹效果
712
- if (childrenLength.value === 1) {
713
- offset.value = withTiming(0, {
714
- duration: easeDuration,
715
- easing: easeMap[easeingFunc]
716
- });
717
- return;
718
- }
719
- // 2.非循环状态不可移动态:最后一个元素 和 第一个元素
720
- // 非循环支持最后元素可滑动能力后,向左快速移动未超过最大可移动范围一半,因为offset为正值,向左滑动handleBack,默认向上取整
721
- // 但是在offset大于0时,取0。[-100, 0](back取0), [0, 100](back取1), 所以handleLongPress里的处理逻辑需要兼容支持,因此这里直接单独处理,不耦合下方公共的判断逻辑。
722
- if (!circularShared.value && !canMove(eventData)) {
723
- if (eventData.transdir < 0) {
724
- handleBack(eventData);
725
- }
726
- else {
727
- handleEnd(eventData);
728
- }
729
- return;
730
- }
731
- // 3. 非循环状态可移动态、循环状态, 正常逻辑处理
732
- const velocity = e[strVelocity];
733
- if (Math.abs(velocity) < longPressRatio) {
734
- handleLongPress(eventData);
668
+ const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000;
669
+ if (Math.abs(strVelocity) < longPressRatio) {
670
+ handleLongPress();
735
671
  }
736
672
  else {
673
+ // 如果触发了onTouchesCancelled,不会触发onUpdate不会更新offset值, 索引不会变更
737
674
  handleEnd(eventData);
738
675
  }
739
- })
740
- .withRef(swiperGestureRef);
676
+ }).withRef(swiperGestureRef);
741
677
  // swiper横向,当y轴滑动5像素手势失效;swiper纵向只响应swiper的滑动事件
742
678
  if (dir === 'x') {
743
- gesturePan.activeOffsetX([-2, 2]).failOffsetY([-5, 5]);
679
+ gesturePan.activeOffsetX([-5, 5]).failOffsetY([-5, 5]);
744
680
  }
745
681
  else {
746
- gesturePan.activeOffsetY([-2, 2]).failOffsetX([-5, 5]);
682
+ gesturePan.activeOffsetY([-5, 5]).failOffsetX([-5, 5]);
747
683
  }
748
684
  // 手势协同2.0
749
685
  if (simultaneousHandlers && simultaneousHandlers.length) {
@@ -764,32 +700,34 @@ const SwiperWrapper = forwardRef((props, ref) => {
764
700
  return { transform: [{ translateY: offset.value }], opacity: step.value > 0 ? 1 : 0 };
765
701
  }
766
702
  });
767
- let finalComponent;
768
- const arrPages = renderItems();
769
- const mergeProps = Object.assign({
770
- style: [normalStyle, layoutStyle, styles.swiper]
771
- }, layoutProps, innerProps);
772
- const animateComponent = createElement(Animated.View, {
773
- style: [{ flexDirection: dir === 'x' ? 'row' : 'column', width: '100%', height: '100%' }, animatedStyles]
774
- }, wrapChildren({
775
- children: arrPages
776
- }, {
777
- hasVarDec,
778
- varContext: varContextRef.current,
779
- textStyle,
780
- textProps
781
- }));
782
- const renderChildrens = showPagination ? [animateComponent, renderPagination()] : animateComponent;
783
- finalComponent = createElement(View, mergeProps, renderChildrens);
784
- if (!disableGesture) {
785
- finalComponent = createElement(GestureDetector, {
786
- gesture: gestureHandler
787
- }, finalComponent);
703
+ function renderSwiper() {
704
+ const arrPages = renderItems();
705
+ return (<View style={[normalStyle, layoutStyle, styles.swiper]} {...layoutProps} {...innerProps}>
706
+ <Animated.View style={[{
707
+ flexDirection: dir === 'x' ? 'row' : 'column',
708
+ width: '100%',
709
+ height: '100%'
710
+ }, animatedStyles]}>
711
+ {wrapChildren({
712
+ children: arrPages
713
+ }, {
714
+ hasVarDec,
715
+ varContext: varContextRef.current,
716
+ textStyle,
717
+ textProps
718
+ })}
719
+ </Animated.View>
720
+ {showsPagination && renderPagination()}
721
+ </View>);
722
+ }
723
+ if (children.length === 1 || disableGesture) {
724
+ return renderSwiper();
788
725
  }
789
- if (hasPositionFixed) {
790
- finalComponent = createElement(Portal, null, finalComponent);
726
+ else {
727
+ return (<GestureDetector gesture={gestureHandler}>
728
+ {renderSwiper()}
729
+ </GestureDetector>);
791
730
  }
792
- return finalComponent;
793
731
  });
794
732
  SwiperWrapper.displayName = 'MpxSwiperWrapper';
795
733
  export default SwiperWrapper;
@@ -10,7 +10,6 @@ import { warn } from '@mpxjs/utils';
10
10
  import useNodesRef from './useNodesRef'; // 引入辅助函数
11
11
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
12
12
  import CheckBox from './mpx-checkbox';
13
- import Portal from './mpx-portal';
14
13
  import { FormContext } from './context';
15
14
  import { useTransformStyle, useLayout, extendObject } from './utils';
16
15
  const _Switch = forwardRef((props, ref) => {
@@ -22,7 +21,7 @@ const _Switch = forwardRef((props, ref) => {
22
21
  if (formContext) {
23
22
  formValuesMap = formContext.formValuesMap;
24
23
  }
25
- const { normalStyle, hasSelfPercent, setWidth, setHeight, hasPositionFixed } = useTransformStyle(style, {
24
+ const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, {
26
25
  enableVar,
27
26
  externalVarContext,
28
27
  parentFontSize,
@@ -84,17 +83,13 @@ const _Switch = forwardRef((props, ref) => {
84
83
  checked: isChecked
85
84
  }));
86
85
  }
87
- let finalComponent = createElement(Switch, extendObject({}, innerProps, {
86
+ return createElement(Switch, extendObject({}, innerProps, {
88
87
  style: normalStyle,
89
88
  value: isChecked,
90
89
  trackColor: { false: '#FFF', true: color },
91
90
  thumbColor: isChecked ? '#FFF' : '#f4f3f4',
92
91
  ios_backgroundColor: '#FFF'
93
92
  }));
94
- if (hasPositionFixed) {
95
- finalComponent = createElement(Portal, null, finalComponent);
96
- }
97
- return finalComponent;
98
93
  });
99
94
  _Switch.displayName = 'MpxSwitch';
100
95
  export default _Switch;
@@ -5,13 +5,12 @@
5
5
  */
6
6
  import { Text } from 'react-native';
7
7
  import { useRef, forwardRef, createElement } from 'react';
8
- import Portal from './mpx-portal';
9
8
  import useInnerProps from './getInnerListeners';
10
9
  import useNodesRef from './useNodesRef'; // 引入辅助函数
11
10
  import { useTransformStyle, wrapChildren, extendObject } from './utils';
12
11
  const _Text = forwardRef((props, ref) => {
13
12
  const { style = {}, allowFontScaling = false, selectable, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'user-select': userSelect, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
14
- const { normalStyle, hasVarDec, varContextRef, hasPositionFixed } = useTransformStyle(style, {
13
+ const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, {
15
14
  enableVar,
16
15
  externalVarContext,
17
16
  parentFontSize,
@@ -30,14 +29,10 @@ const _Text = forwardRef((props, ref) => {
30
29
  }), [
31
30
  'user-select'
32
31
  ]);
33
- let finalComponent = createElement(Text, innerProps, wrapChildren(props, {
32
+ return createElement(Text, innerProps, wrapChildren(props, {
34
33
  hasVarDec,
35
34
  varContext: varContextRef.current
36
35
  }));
37
- if (hasPositionFixed) {
38
- finalComponent = createElement(Portal, null, finalComponent);
39
- }
40
- return finalComponent;
41
36
  });
42
37
  _Text.displayName = 'MpxText';
43
38
  export default _Text;