@mpxjs/webpack-plugin 2.10.7-beta.9 → 2.10.7

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 (40) hide show
  1. package/LICENSE +433 -0
  2. package/lib/dependencies/RecordPageConfigsMapDependency.js +1 -1
  3. package/lib/index.js +5 -6
  4. package/lib/platform/style/wx/index.js +0 -7
  5. package/lib/platform/template/wx/component-config/index.js +1 -5
  6. package/lib/platform/template/wx/component-config/movable-view.js +10 -1
  7. package/lib/platform/template/wx/index.js +2 -1
  8. package/lib/runtime/components/react/context.ts +4 -23
  9. package/lib/runtime/components/react/dist/context.js +2 -5
  10. package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
  11. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -2
  12. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +9 -63
  13. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +63 -308
  14. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +15 -31
  15. package/lib/runtime/components/react/dist/mpx-swiper.jsx +27 -53
  16. package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
  17. package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
  18. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  19. package/lib/runtime/components/react/mpx-button.tsx +2 -3
  20. package/lib/runtime/components/react/mpx-movable-area.tsx +11 -98
  21. package/lib/runtime/components/react/mpx-movable-view.tsx +64 -358
  22. package/lib/runtime/components/react/mpx-scroll-view.tsx +59 -84
  23. package/lib/runtime/components/react/mpx-swiper.tsx +25 -53
  24. package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
  25. package/lib/runtime/components/react/types/global.d.ts +15 -0
  26. package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
  27. package/lib/runtime/components/web/mpx-scroll-view.vue +4 -18
  28. package/lib/template-compiler/bind-this.js +1 -2
  29. package/lib/template-compiler/compiler.js +2 -2
  30. package/package.json +4 -4
  31. package/lib/platform/template/wx/component-config/sticky-header.js +0 -23
  32. package/lib/platform/template/wx/component-config/sticky-section.js +0 -23
  33. package/lib/runtime/components/react/AsyncContainer.tsx +0 -189
  34. package/lib/runtime/components/react/dist/AsyncContainer.jsx +0 -141
  35. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +0 -117
  36. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +0 -45
  37. package/lib/runtime/components/react/mpx-sticky-header.tsx +0 -181
  38. package/lib/runtime/components/react/mpx-sticky-section.tsx +0 -96
  39. package/lib/runtime/components/web/mpx-sticky-header.vue +0 -99
  40. package/lib/runtime/components/web/mpx-sticky-section.vue +0 -15
@@ -32,7 +32,7 @@
32
32
  * ✔ bindscroll
33
33
  */
34
34
  import { ScrollView, RefreshControl, Gesture, GestureDetector } from 'react-native-gesture-handler'
35
- import { View, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle, Animated as RNAnimated } from 'react-native'
35
+ import { View, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
36
36
  import { isValidElement, Children, JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef, useContext, useMemo, createElement } from 'react'
37
37
  import Animated, { useAnimatedRef, useSharedValue, withTiming, useAnimatedStyle, runOnJS } from 'react-native-reanimated'
38
38
  import { warn, hasOwn } from '@mpxjs/utils'
@@ -43,49 +43,48 @@ import { IntersectionObserverContext, ScrollViewContext } from './context'
43
43
  import Portal from './mpx-portal'
44
44
 
45
45
  interface ScrollViewProps {
46
- children?: ReactNode;
47
- enhanced?: boolean;
48
- bounces?: boolean;
49
- style?: ViewStyle;
50
- 'scroll-x'?: boolean;
51
- 'scroll-y'?: boolean;
52
- 'enable-back-to-top'?: boolean;
53
- 'show-scrollbar'?: boolean;
54
- 'paging-enabled'?: boolean;
55
- 'upper-threshold'?: number;
56
- 'lower-threshold'?: number;
57
- 'scroll-with-animation'?: boolean;
58
- 'refresher-triggered'?: boolean;
59
- 'refresher-enabled'?: boolean;
60
- 'refresher-default-style'?: 'black' | 'white' | 'none';
61
- 'refresher-background'?: string;
62
- 'refresher-threshold'?: number;
63
- 'scroll-top'?: number;
64
- 'scroll-left'?: number;
65
- 'enable-offset'?: boolean;
66
- 'scroll-into-view'?: string;
67
- 'enable-trigger-intersection-observer'?: boolean;
68
- 'enable-var'?: boolean;
69
- 'external-var-context'?: Record<string, any>;
70
- 'parent-font-size'?: number;
71
- 'parent-width'?: number;
72
- 'parent-height'?: number;
73
- 'enable-sticky'?: boolean;
74
- 'wait-for'?: Array<GestureHandler>;
75
- 'simultaneous-handlers'?: Array<GestureHandler>;
76
- 'scroll-event-throttle'?:number;
77
- 'scroll-into-view-offset'?: number;
78
- bindscrolltoupper?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
79
- bindscrolltolower?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
80
- bindscroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
81
- bindrefresherrefresh?: (event: NativeSyntheticEvent<unknown>) => void;
82
- binddragstart?: (event: NativeSyntheticEvent<DragEvent>) => void;
83
- binddragging?: (event: NativeSyntheticEvent<DragEvent>) => void;
84
- binddragend?: (event: NativeSyntheticEvent<DragEvent>) => void;
85
- bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent>) => void;
86
- bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
87
- bindtouchend?: (event: NativeSyntheticEvent<TouchEvent>) => void;
88
- bindscrollend?: (event: NativeSyntheticEvent<TouchEvent>) => void;
46
+ children?: ReactNode
47
+ enhanced?: boolean
48
+ bounces?: boolean
49
+ style?: ViewStyle
50
+ scrollEventThrottle?: number
51
+ 'scroll-x'?: boolean
52
+ 'scroll-y'?: boolean
53
+ 'enable-back-to-top'?: boolean
54
+ 'show-scrollbar'?: boolean
55
+ 'paging-enabled'?: boolean
56
+ 'upper-threshold'?: number
57
+ 'lower-threshold'?: number
58
+ 'scroll-with-animation'?: boolean
59
+ 'refresher-triggered'?: boolean
60
+ 'refresher-enabled'?: boolean
61
+ 'refresher-default-style'?: 'black' | 'white' | 'none'
62
+ 'refresher-background'?: string
63
+ 'refresher-threshold'?: number
64
+ 'scroll-top'?: number
65
+ 'scroll-left'?: number
66
+ 'enable-offset'?: boolean
67
+ 'scroll-into-view'?: string
68
+ 'enable-trigger-intersection-observer'?: boolean
69
+ 'enable-var'?: boolean
70
+ 'external-var-context'?: Record<string, any>
71
+ 'parent-font-size'?: number
72
+ 'parent-width'?: number
73
+ 'parent-height'?: number
74
+ 'wait-for'?: Array<GestureHandler>
75
+ 'simultaneous-handlers'?: Array<GestureHandler>
76
+ 'scroll-event-throttle'?: number
77
+ bindscrolltoupper?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
78
+ bindscrolltolower?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
79
+ bindscroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
80
+ bindrefresherrefresh?: (event: NativeSyntheticEvent<unknown>) => void
81
+ binddragstart?: (event: NativeSyntheticEvent<DragEvent>) => void
82
+ binddragging?: (event: NativeSyntheticEvent<DragEvent>) => void
83
+ binddragend?: (event: NativeSyntheticEvent<DragEvent>) => void
84
+ bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent>) => void
85
+ bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void
86
+ bindtouchend?: (event: NativeSyntheticEvent<TouchEvent>) => void
87
+ bindscrollend?: (event: NativeSyntheticEvent<TouchEvent>) => void
89
88
  __selectRef?: (selector: string, nodeType: 'node' | 'component', all?: boolean) => HandlerRef<any, any>
90
89
  }
91
90
  type ScrollAdditionalProps = {
@@ -110,8 +109,6 @@ type ScrollAdditionalProps = {
110
109
  onMomentumScrollEnd?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
111
110
  }
112
111
 
113
- const AnimatedScrollView = RNAnimated.createAnimatedComponent(ScrollView) as React.ComponentType<any>
114
-
115
112
  const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, ScrollViewProps>((scrollViewProps: ScrollViewProps = {}, ref): JSX.Element => {
116
113
  const { textProps, innerProps: props = {} } = splitProps(scrollViewProps)
117
114
  const {
@@ -148,14 +145,10 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
148
145
  'parent-height': parentHeight,
149
146
  'simultaneous-handlers': originSimultaneousHandlers,
150
147
  'wait-for': waitFor,
151
- 'enable-sticky': enableSticky,
152
148
  'scroll-event-throttle': scrollEventThrottle = 0,
153
- 'scroll-into-view-offset': scrollIntoViewOffset = 0,
154
149
  __selectRef
155
150
  } = props
156
151
 
157
- const scrollOffset = useRef(new RNAnimated.Value(0)).current
158
-
159
152
  const simultaneousHandlers = flatGesture(originSimultaneousHandlers)
160
153
  const waitForHandlers = flatGesture(waitFor)
161
154
 
@@ -187,7 +180,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
187
180
  const initialTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
188
181
  const intersectionObservers = useContext(IntersectionObserverContext)
189
182
 
190
- const firstScrollIntoViewChange = useRef<boolean>(true)
183
+ const firstScrollIntoViewChange = useRef<boolean>(false)
191
184
 
192
185
  const refreshColor = {
193
186
  black: ['#000'],
@@ -220,21 +213,19 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
220
213
  pagingEnabled,
221
214
  fastDeceleration: false,
222
215
  decelerationDisabled: false,
223
- scrollTo,
224
- scrollIntoView: handleScrollIntoView
216
+ scrollTo
225
217
  },
226
218
  gestureRef: scrollViewRef
227
219
  })
228
220
 
229
- const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
230
-
231
221
  const contextValue = useMemo(() => {
232
222
  return {
233
- gestureRef: scrollViewRef,
234
- scrollOffset
223
+ gestureRef: scrollViewRef
235
224
  }
236
225
  }, [])
237
226
 
227
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
228
+
238
229
  const hasRefresherLayoutRef = useRef(false)
239
230
 
240
231
  // layout 完成前先隐藏,避免安卓闪烁问题
@@ -260,15 +251,13 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
260
251
 
261
252
  useEffect(() => {
262
253
  if (scrollIntoView && __selectRef) {
263
- if (firstScrollIntoViewChange.current) {
264
- setTimeout(() => {
265
- handleScrollIntoView(scrollIntoView, { offset: scrollIntoViewOffset, animated: scrollWithAnimation })
266
- })
254
+ if (!firstScrollIntoViewChange.current) {
255
+ setTimeout(handleScrollIntoView)
267
256
  } else {
268
- handleScrollIntoView(scrollIntoView, { offset: scrollIntoViewOffset, animated: scrollWithAnimation })
257
+ handleScrollIntoView()
269
258
  }
270
259
  }
271
- firstScrollIntoViewChange.current = false
260
+ firstScrollIntoViewChange.current = true
272
261
  }, [scrollIntoView])
273
262
 
274
263
  useEffect(() => {
@@ -291,16 +280,14 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
291
280
  scrollToOffset(left, top, animated)
292
281
  }
293
282
 
294
- function handleScrollIntoView (selector = '', { offset = 0, animated = true } = {}) {
295
- const refs = __selectRef!(`#${selector}`, 'node')
283
+ function handleScrollIntoView () {
284
+ const refs = __selectRef!(`#${scrollIntoView}`, 'node')
296
285
  if (!refs) return
297
286
  const { nodeRef } = refs.getNodeInstance()
298
287
  nodeRef.current?.measureLayout(
299
288
  scrollViewRef.current,
300
289
  (left: number, top: number) => {
301
- const adjustedLeft = scrollX ? left + offset : left
302
- const adjustedTop = scrollY ? top + offset : top
303
- scrollToOffset(adjustedLeft, adjustedTop, animated)
290
+ scrollToOffset(left, top)
304
291
  }
305
292
  )
306
293
  }
@@ -500,16 +487,6 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
500
487
  updateIntersection()
501
488
  }
502
489
 
503
- const scrollHandler = RNAnimated.event(
504
- [{ nativeEvent: { contentOffset: { y: scrollOffset } } }],
505
- {
506
- useNativeDriver: true,
507
- listener: (event: NativeSyntheticEvent<NativeScrollEvent>) => {
508
- onScroll(event)
509
- }
510
- }
511
- )
512
-
513
490
  function onScrollDragStart (e: NativeSyntheticEvent<NativeScrollEvent>) {
514
491
  hasCallScrollToLower.current = false
515
492
  hasCallScrollToUpper.current = false
@@ -684,7 +661,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
684
661
  scrollEnabled: !enableScroll ? false : !!(scrollX || scrollY),
685
662
  bounces: false,
686
663
  ref: scrollViewRef,
687
- onScroll: enableSticky ? scrollHandler : onScroll,
664
+ onScroll: onScroll,
688
665
  onContentSizeChange: onContentSizeChange,
689
666
  bindtouchstart: ((enhanced && binddragstart) || bindtouchstart) && onScrollTouchStart,
690
667
  bindtouchmove: ((enhanced && binddragging) || bindtouchmove) && onScrollTouchMove,
@@ -739,13 +716,11 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
739
716
  'bindrefresherrefresh'
740
717
  ], { layoutRef })
741
718
 
742
- const ScrollViewComponent = enableSticky ? AnimatedScrollView : ScrollView
743
-
744
719
  const withRefresherScrollView = createElement(
745
720
  GestureDetector,
746
721
  { gesture: panGesture },
747
722
  createElement(
748
- ScrollViewComponent,
723
+ ScrollView,
749
724
  innerProps,
750
725
  createElement(
751
726
  Animated.View,
@@ -773,8 +748,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
773
748
  )
774
749
 
775
750
  const commonScrollView = createElement(
776
- ScrollViewComponent,
777
- extendObject({}, innerProps, {
751
+ ScrollView,
752
+ extendObject(innerProps, {
778
753
  refreshControl: refresherEnabled
779
754
  ? createElement(RefreshControl, extendObject({
780
755
  progressBackgroundColor: refresherBackground,
@@ -23,7 +23,6 @@ import Portal from './mpx-portal'
23
23
  * ✔ easing-function ="easeOutCubic"
24
24
  * ✘ display-multiple-items
25
25
  * ✘ snap-to-edge
26
- * ✔ disableGesture
27
26
  */
28
27
  type EaseType = 'default' | 'linear' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic'
29
28
  type StrAbsoType = 'absoluteX' | 'absoluteY'
@@ -207,10 +206,6 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
207
206
  const moveTranstion = useSharedValue(0)
208
207
  // 记录从onBegin 到 onTouchesUp 的时间
209
208
  const moveTime = useSharedValue(0)
210
- // 记录从onBegin 到 onTouchesCancelled 另外一个方向移动的距离
211
- const anotherDirectionMove = useSharedValue(0)
212
- // 另一个方向的
213
- const anotherAbso = 'absolute' + (dir === 'x' ? 'y' : 'x').toUpperCase() as StrAbsoType
214
209
  const timerId = useRef(0 as number | ReturnType<typeof setTimeout>)
215
210
  const intervalTimer = props.interval || 500
216
211
 
@@ -509,11 +504,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
509
504
  }, [children.length])
510
505
 
511
506
  useEffect(() => {
512
- // 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
513
- // 2. 手指滑动过程中更新索引,外部会把current再穿进来,导致offset直接更新了
514
- if (props.current !== currentIndex.value) {
515
- updateCurrent(props.current || 0, step.value)
516
- }
507
+ updateCurrent(props.current || 0, step.value)
517
508
  }, [props.current])
518
509
 
519
510
  useEffect(() => {
@@ -575,25 +566,18 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
575
566
  targetOffset: -moveToTargetPos
576
567
  }
577
568
  }
578
- function checkUnCircular (eventData: EventDataType) {
569
+ function canMove (eventData: EventDataType) {
579
570
  'worklet'
580
571
  const { translation } = eventData
581
572
  const currentOffset = Math.abs(offset.value)
582
- // 向右滑动swiper
583
- if (translation < 0) {
584
- const boundaryOffset = step.value * (childrenLength.value - 1)
585
- const gestureMovePos = Math.abs(translation) + currentOffset
586
- return {
587
- // 防止快速连续向右滑动时,手势移动的距离 加 当前的offset超出边界
588
- targetOffset: gestureMovePos > boundaryOffset ? -boundaryOffset : offset.value + translation,
589
- canMove: currentOffset < boundaryOffset
573
+ if (!circularShared.value) {
574
+ if (translation < 0) {
575
+ return currentOffset < step.value * (childrenLength.value - 1)
576
+ } else {
577
+ return currentOffset > 0
590
578
  }
591
579
  } else {
592
- const gestureMovePos = currentOffset - translation
593
- return {
594
- targetOffset: gestureMovePos < 0 ? 0 : offset.value + translation,
595
- canMove: currentOffset > 0
596
- }
580
+ return true
597
581
  }
598
582
  }
599
583
  function handleEnd (eventData: EventDataType) {
@@ -652,7 +636,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
652
636
  }
653
637
  })
654
638
  }
655
- function computeHalf () {
639
+ function handleLongPress () {
656
640
  'worklet'
657
641
  const currentOffset = Math.abs(offset.value)
658
642
  let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value
@@ -662,14 +646,6 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
662
646
  // 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
663
647
  const diffOffset = preOffset - currentOffset
664
648
  const half = Math.abs(diffOffset) > step.value / 2
665
- return {
666
- diffOffset,
667
- half
668
- }
669
- }
670
- function handleLongPress () {
671
- 'worklet'
672
- const { diffOffset, half } = computeHalf()
673
649
  if (+diffOffset === 0) {
674
650
  runOnJS(resumeLoop)()
675
651
  } else if (half) {
@@ -725,29 +701,18 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
725
701
  runOnJS(pauseLoop)()
726
702
  preAbsolutePos.value = e[strAbso]
727
703
  moveTranstion.value = e[strAbso]
728
- anotherDirectionMove.value = e[anotherAbso]
729
704
  moveTime.value = new Date().getTime()
730
705
  })
731
- .onUpdate((e) => {
706
+ .onTouchesMove((e) => {
732
707
  'worklet'
733
708
  if (touchfinish.value) return
734
- const moveDistance = e[strAbso] - preAbsolutePos.value
709
+ const touchEventData = e.changedTouches[0]
710
+ const moveDistance = touchEventData[strAbso] - preAbsolutePos.value
735
711
  const eventData = {
736
712
  translation: moveDistance
737
713
  }
738
- // 1. 在Move过程中,如果手指一直没抬起来,超过一半的话也会更新索引
739
- const { half } = computeHalf()
740
- if (half) {
741
- const { selectedIndex } = getTargetPosition(eventData)
742
- currentIndex.value = selectedIndex
743
- }
744
- // 2. 处理用户一直拖拽到临界点的场景, 不会执行onEnd
745
- const { canMove, targetOffset } = checkUnCircular(eventData)
746
- if (!circularShared.value) {
747
- if (canMove) {
748
- offset.value = targetOffset
749
- preAbsolutePos.value = e[strAbso]
750
- }
714
+ // 处理用户一直拖拽到临界点的场景, 不会执行onEnd
715
+ if (!circularShared.value && !canMove(eventData)) {
751
716
  return
752
717
  }
753
718
  const { isBoundary, resetOffset } = reachBoundary(eventData)
@@ -756,21 +721,28 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
756
721
  } else {
757
722
  offset.value = moveDistance + offset.value
758
723
  }
759
- preAbsolutePos.value = e[strAbso]
724
+ preAbsolutePos.value = touchEventData[strAbso]
760
725
  })
761
- .onFinalize((e) => {
726
+ .onTouchesUp((e) => {
762
727
  'worklet'
763
728
  if (touchfinish.value) return
764
- const moveDistance = e[strAbso] - moveTranstion.value
729
+ const touchEventData = e.changedTouches[0]
730
+ const moveDistance = touchEventData[strAbso] - moveTranstion.value
765
731
  touchfinish.value = true
766
732
  const eventData = {
767
733
  translation: moveDistance
768
734
  }
735
+ if (childrenLength.value === 1) {
736
+ return handleBackInit()
737
+ }
738
+ // 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
739
+ if (!circularShared.value && !canMove(eventData)) {
740
+ return
741
+ }
769
742
  const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000
770
743
  if (Math.abs(strVelocity) < longPressRatio) {
771
744
  handleLongPress()
772
745
  } else {
773
- // 如果触发了onTouchesCancelled,不会触发onUpdate不会更新offset值, 索引不会变更
774
746
  handleEnd(eventData)
775
747
  }
776
748
  })
@@ -1,6 +1,7 @@
1
- import { forwardRef, useRef, useContext, useMemo, useState, useCallback, useEffect } from 'react'
1
+ import { forwardRef, useRef, useContext, useMemo, useState } from 'react'
2
2
  import { warn, isFunction } from '@mpxjs/utils'
3
3
  import Portal from './mpx-portal/index'
4
+ import { usePreventRemove, PreventRemoveEvent } from '@react-navigation/native'
4
5
  import { getCustomEvent } from './getInnerListeners'
5
6
  import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
6
7
  import { WebView } from 'react-native-webview'
@@ -75,7 +76,6 @@ const styles = StyleSheet.create({
75
76
  borderRadius: 10
76
77
  }
77
78
  })
78
-
79
79
  const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
80
80
  const { src, bindmessage, bindload, binderror } = props
81
81
  const mpx = global.__mpx
@@ -100,8 +100,8 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
100
100
  const webViewRef = useRef<WebView>(null)
101
101
  const fristLoaded = useRef<boolean>(false)
102
102
  const isLoadError = useRef<boolean>(false)
103
+ const isNavigateBack = useRef<boolean>(false)
103
104
  const statusCode = useRef<string|number>('')
104
- const [isLoaded, setIsLoaded] = useState<boolean>(true)
105
105
  const defaultWebViewStyle = {
106
106
  position: 'absolute' as const,
107
107
  left: 0,
@@ -109,30 +109,18 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
109
109
  top: 0,
110
110
  bottom: 0
111
111
  }
112
- const canGoBack = useRef<boolean>(false)
113
- const isNavigateBack = useRef<boolean>(false)
114
112
 
115
- const beforeRemoveHandle = (e: Event) => {
116
- if (canGoBack.current && !isNavigateBack.current) {
113
+ const navigation = useNavigation()
114
+ const [isIntercept, setIsIntercept] = useState<boolean>(false)
115
+ usePreventRemove(isIntercept, (event: PreventRemoveEvent) => {
116
+ const { data } = event
117
+ if (isNavigateBack.current) {
118
+ navigation?.dispatch(data.action)
119
+ } else {
117
120
  webViewRef.current?.goBack()
118
- e.preventDefault()
119
121
  }
120
122
  isNavigateBack.current = false
121
- }
122
-
123
- const navigation = useNavigation()
124
-
125
- // useEffect(() => {
126
- // let beforeRemoveSubscription:any
127
- // if (__mpx_mode__ !== 'ios') {
128
- // beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
129
- // }
130
- // return () => {
131
- // if (isFunction(beforeRemoveSubscription)) {
132
- // beforeRemoveSubscription()
133
- // }
134
- // }
135
- // }, [])
123
+ })
136
124
 
137
125
  useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
138
126
  style: defaultWebViewStyle
@@ -183,14 +171,14 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
183
171
  }
184
172
  const _changeUrl = function (navState: WebViewNavigation) {
185
173
  if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
186
- canGoBack.current = navState.canGoBack
187
174
  currentPage.__webViewUrl = navState.url
175
+ setIsIntercept(navState.canGoBack)
188
176
  }
189
177
  }
190
178
 
191
179
  const _onLoadProgress = function (event: WebViewProgressEvent) {
192
180
  if (__mpx_mode__ !== 'ios') {
193
- canGoBack.current = event.nativeEvent.canGoBack
181
+ setIsIntercept(event.nativeEvent.canGoBack)
194
182
  }
195
183
  }
196
184
  const _message = function (res: WebViewMessageEvent) {
@@ -279,7 +267,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
279
267
  }
280
268
  const onLoadEndHandle = function (res: WebViewEvent) {
281
269
  fristLoaded.current = true
282
- setIsLoaded(true)
283
270
  const src = res.nativeEvent?.url
284
271
  if (isLoadError.current) {
285
272
  isLoadError.current = false
@@ -325,11 +312,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
325
312
  setPageLoadErr(true)
326
313
  }
327
314
  }
328
- const onLoadStart = function () {
329
- if (!fristLoaded.current) {
330
- setIsLoaded(false)
331
- }
332
- }
333
315
 
334
316
  return (
335
317
  <Portal>
@@ -342,7 +324,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
342
324
  )
343
325
  : (<WebView
344
326
  style={ defaultWebViewStyle }
345
- pointerEvents={ isLoaded ? 'auto' : 'none' }
346
327
  source={{ uri: src }}
347
328
  ref={webViewRef}
348
329
  javaScriptEnabled={true}
@@ -353,7 +334,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
353
334
  onLoadEnd={onLoadEnd}
354
335
  onHttpError={onHttpError}
355
336
  onError={onError}
356
- onLoadStart={onLoadStart}
357
337
  allowsBackForwardNavigationGestures={true}
358
338
  ></WebView>)}
359
339
  </Portal>
@@ -42,6 +42,21 @@ declare let global: {
42
42
 
43
43
  declare module '@react-navigation/native' {
44
44
  export function useNavigation (): Record<string, any>
45
+ export function usePreventRemove(
46
+ enabled: boolean,
47
+ callback: (e: { data: { action: any } }) => void
48
+ ): void;
49
+ export interface PreventRemoveEvent {
50
+ data: {
51
+ action: NavigationAction;
52
+ route: {
53
+ key: string;
54
+ name: string;
55
+ params?: unknown;
56
+ };
57
+ };
58
+ preventDefault(): void;
59
+ }
45
60
  }
46
61
 
47
62
  declare module '*.png'
@@ -84,88 +84,6 @@ const InitialValue: ExtendedViewStyle = Object.assign({
84
84
  const TransformOrigin = 'transformOrigin'
85
85
  // transform
86
86
  const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
87
- // 多value解析
88
- const parseValues = (str: string, char = ' ') => {
89
- let stack = 0
90
- let temp = ''
91
- const result = []
92
- for (let i = 0; i < str.length; i++) {
93
- if (str[i] === '(') {
94
- stack++
95
- } else if (str[i] === ')') {
96
- stack--
97
- }
98
- // 非括号内 或者 非分隔字符且非空
99
- if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
100
- temp += str[i]
101
- }
102
- if ((stack === 0 && str[i] === char) || i === str.length - 1) {
103
- result.push(temp)
104
- temp = ''
105
- }
106
- }
107
- return result
108
- }
109
- // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
110
- const parseTransform = (transformStr: string) => {
111
- const values = parseValues(transformStr)
112
- const transform: {[propName: string]: string|number|number[]}[] = []
113
- values.forEach(item => {
114
- const match = item.match(/([/\w]+)\((.+)\)/)
115
- if (match && match.length >= 3) {
116
- let key = match[1]
117
- const val = match[2]
118
- switch (key) {
119
- case 'translateX':
120
- case 'translateY':
121
- case 'scaleX':
122
- case 'scaleY':
123
- case 'rotateX':
124
- case 'rotateY':
125
- case 'rotateZ':
126
- case 'rotate':
127
- case 'skewX':
128
- case 'skewY':
129
- case 'perspective':
130
- // rotate 处理成 rotateZ
131
- key = key === 'rotate' ? 'rotateZ' : key
132
- // 单个值处理
133
- transform.push({ [key]: global.__formatValue(val) })
134
- break
135
- case 'matrix':
136
- transform.push({ [key]: parseValues(val, ',').map(val => +val) })
137
- break
138
- case 'translate':
139
- case 'scale':
140
- case 'skew':
141
- case 'translate3d': // x y 支持 z不支持
142
- case 'scale3d': // x y 支持 z不支持
143
- {
144
- // 2 个以上的值处理
145
- key = key.replace('3d', '')
146
- const vals = parseValues(val, ',').splice(0, 3)
147
- // scale(.5) === scaleX(.5) scaleY(.5)
148
- if (vals.length === 1 && key === 'scale') {
149
- vals.push(vals[0])
150
- }
151
- const xyz = ['X', 'Y', 'Z']
152
- transform.push(...vals.map((v, index) => {
153
- return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) }
154
- }))
155
- break
156
- }
157
- }
158
- }
159
- })
160
- return transform
161
- }
162
- // format style
163
- const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
164
- if (!style.transform || Array.isArray(style.transform)) return style
165
- return Object.assign({}, style, {
166
- transform: parseTransform(style.transform)
167
- })
168
- }
169
87
 
170
88
  // transform 数组转对象
171
89
  function getTransformObj (transforms: { [propName: string]: string | number }[]) {
@@ -176,7 +94,7 @@ function getTransformObj (transforms: { [propName: string]: string | number }[])
176
94
  }
177
95
 
178
96
  export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean, layoutRef: MutableRefObject<any>, transitionend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void }) {
179
- const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props
97
+ const { style: originalStyle = {}, animation, enableAnimation, transitionend, layoutRef } = props
180
98
  const enableStyleAnimation = enableAnimation || !!animation
181
99
  const enableAnimationRef = useRef(enableStyleAnimation)
182
100
  if (enableAnimationRef.current !== enableStyleAnimation) {
@@ -185,7 +103,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
185
103
 
186
104
  if (!enableAnimationRef.current) return { enableStyleAnimation: false }
187
105
 
188
- const originalStyle = formatStyle(style)
189
106
  // id 标识
190
107
  const id = animation?.id || -1
191
108
  // 有动画样式的 style key
@@ -214,7 +131,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
214
131
  useEffect(() => {
215
132
  // style 更新后同步更新 lastStyleRef & shareValMap
216
133
  updateStyleVal()
217
- }, [style])
134
+ }, [originalStyle])
218
135
  // ** 获取动画样式prop & 驱动动画
219
136
  // eslint-disable-next-line react-hooks/rules-of-hooks
220
137
  useEffect(() => {