@mpxjs/webpack-plugin 2.10.2 → 2.10.3-beta.4

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 (76) hide show
  1. package/lib/config.js +2 -1
  2. package/lib/dependencies/RecordPageConfigsMapDependency.js +45 -0
  3. package/lib/index.js +13 -1
  4. package/lib/platform/json/wx/index.js +6 -3
  5. package/lib/platform/style/wx/index.js +29 -16
  6. package/lib/platform/template/wx/component-config/button.js +19 -2
  7. package/lib/platform/template/wx/component-config/canvas.js +4 -0
  8. package/lib/platform/template/wx/component-config/checkbox-group.js +4 -0
  9. package/lib/platform/template/wx/component-config/checkbox.js +4 -0
  10. package/lib/platform/template/wx/component-config/cover-image.js +7 -1
  11. package/lib/platform/template/wx/component-config/cover-view.js +4 -0
  12. package/lib/platform/template/wx/component-config/fix-component-name.js +3 -2
  13. package/lib/platform/template/wx/component-config/form.js +7 -1
  14. package/lib/platform/template/wx/component-config/icon.js +4 -0
  15. package/lib/platform/template/wx/component-config/image.js +7 -1
  16. package/lib/platform/template/wx/component-config/input.js +17 -2
  17. package/lib/platform/template/wx/component-config/label.js +4 -0
  18. package/lib/platform/template/wx/component-config/movable-area.js +7 -1
  19. package/lib/platform/template/wx/component-config/movable-view.js +12 -3
  20. package/lib/platform/template/wx/component-config/navigator.js +4 -0
  21. package/lib/platform/template/wx/component-config/picker-view-column.js +4 -0
  22. package/lib/platform/template/wx/component-config/picker-view.js +7 -1
  23. package/lib/platform/template/wx/component-config/picker.js +7 -1
  24. package/lib/platform/template/wx/component-config/radio-group.js +4 -0
  25. package/lib/platform/template/wx/component-config/radio.js +4 -0
  26. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  27. package/lib/platform/template/wx/component-config/root-portal.js +4 -0
  28. package/lib/platform/template/wx/component-config/scroll-view.js +10 -2
  29. package/lib/platform/template/wx/component-config/swiper-item.js +7 -1
  30. package/lib/platform/template/wx/component-config/swiper.js +12 -3
  31. package/lib/platform/template/wx/component-config/switch.js +4 -0
  32. package/lib/platform/template/wx/component-config/text.js +7 -1
  33. package/lib/platform/template/wx/component-config/textarea.js +17 -2
  34. package/lib/platform/template/wx/component-config/unsupported.js +7 -0
  35. package/lib/platform/template/wx/component-config/video.js +10 -2
  36. package/lib/platform/template/wx/component-config/view.js +24 -2
  37. package/lib/platform/template/wx/component-config/web-view.js +4 -0
  38. package/lib/platform/template/wx/index.js +32 -13
  39. package/lib/react/index.js +0 -1
  40. package/lib/react/processJSON.js +13 -2
  41. package/lib/react/processScript.js +5 -3
  42. package/lib/react/processTemplate.js +18 -3
  43. package/lib/react/script-helper.js +18 -4
  44. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -11
  45. package/lib/runtime/components/react/dist/{KeyboardAvoidingView.jsx → mpx-keyboard-avoiding-view.jsx} +4 -3
  46. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +2 -2
  47. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +1 -2
  48. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +10 -5
  49. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +22 -0
  50. package/lib/runtime/components/react/dist/mpx-swiper.jsx +2 -2
  51. package/lib/runtime/components/react/dist/mpx-view.jsx +10 -5
  52. package/lib/runtime/components/react/dist/mpx-web-view.jsx +10 -7
  53. package/lib/runtime/components/react/dist/useAnimationHooks.js +46 -48
  54. package/lib/runtime/components/react/dist/utils.jsx +18 -7
  55. package/lib/runtime/components/react/mpx-input.tsx +1 -19
  56. package/lib/runtime/components/react/{KeyboardAvoidingView.tsx → mpx-keyboard-avoiding-view.tsx} +4 -2
  57. package/lib/runtime/components/react/mpx-picker-view-column.tsx +2 -2
  58. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +1 -2
  59. package/lib/runtime/components/react/mpx-scroll-view.tsx +13 -4
  60. package/lib/runtime/components/react/mpx-simple-view.tsx +32 -0
  61. package/lib/runtime/components/react/mpx-swiper.tsx +4 -2
  62. package/lib/runtime/components/react/mpx-view.tsx +17 -10
  63. package/lib/runtime/components/react/mpx-web-view.tsx +15 -12
  64. package/lib/runtime/components/react/types/getInnerListeners.d.ts +1 -1
  65. package/lib/runtime/components/react/types/global.d.ts +1 -1
  66. package/lib/runtime/components/react/useAnimationHooks.ts +46 -48
  67. package/lib/runtime/components/react/utils.tsx +23 -11
  68. package/lib/runtime/components/web/mini-video-controls.min.js +1 -1
  69. package/lib/runtime/optionProcessor.js +3 -2
  70. package/lib/style-compiler/index.js +8 -6
  71. package/lib/template-compiler/compiler.js +21 -13
  72. package/lib/utils/env.js +1 -1
  73. package/lib/utils/match-condition.js +14 -8
  74. package/lib/web/processJSON.js +1 -3
  75. package/package.json +3 -3
  76. package/LICENSE +0 -433
@@ -26,8 +26,8 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
26
26
  const gesture = useMemo(() => {
27
27
  return Gesture.Tap()
28
28
  .onEnd(() => {
29
- runOnJS(dismiss)()
30
- })
29
+ dismiss()
30
+ }).runOnJS(true)
31
31
  }, [])
32
32
 
33
33
  const animatedStyle = useAnimatedStyle(() => {
@@ -117,4 +117,6 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
117
117
  )
118
118
  }
119
119
 
120
+ KeyboardAvoidingView.displayName = 'MpxKeyboardAvoidingView'
121
+
120
122
  export default KeyboardAvoidingView
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react'
2
2
  import { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, ScrollView, StyleSheet, View } from 'react-native'
3
3
  import Reanimated, { AnimatedRef, useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'
4
- import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS } from './utils'
4
+ import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS, isHarmony } from './utils'
5
5
  import useNodesRef, { HandlerRef } from './useNodesRef'
6
6
  import PickerIndicator from './pickerViewIndicator'
7
7
  import PickerMask from './pickerViewMask'
@@ -140,7 +140,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
140
140
  y: initialIndex * itemRawH,
141
141
  animated: false
142
142
  })
143
- }, isAndroid ? 200 : 0)
143
+ }, isAndroid || isHarmony ? 200 : 0)
144
144
  activeIndex.current = initialIndex
145
145
  }, [itemRawH, maxIndex, initialIndex])
146
146
 
@@ -1,6 +1,5 @@
1
1
  import { useState, useCallback, forwardRef, ForwardedRef, useImperativeHandle, ReactNode, ReactElement } from 'react'
2
2
  import { View, StyleSheet } from 'react-native'
3
- import { extendObject } from '../utils'
4
3
 
5
4
  export type State = {
6
5
  portals: Array<{
@@ -27,7 +26,7 @@ const _PortalManager = forwardRef((props: PortalManagerProps, ref:ForwardedRef<u
27
26
  setState((prevState) => ({
28
27
  portals: prevState.portals.map((item) => {
29
28
  if (item.key === key) {
30
- return extendObject({}, item, { children })
29
+ return Object.assign({}, item, { children })
31
30
  }
32
31
  return item
33
32
  })
@@ -70,6 +70,7 @@ interface ScrollViewProps {
70
70
  'parent-height'?: number;
71
71
  'wait-for'?: Array<GestureHandler>;
72
72
  'simultaneous-handlers'?: Array<GestureHandler>;
73
+ 'scroll-event-throttle'?:number;
73
74
  bindscrolltoupper?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
74
75
  bindscrolltolower?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
75
76
  bindscroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
@@ -140,6 +141,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
140
141
  'parent-height': parentHeight,
141
142
  'simultaneous-handlers': originSimultaneousHandlers,
142
143
  'wait-for': waitFor,
144
+ 'scroll-event-throttle': scrollEventThrottle = 0,
143
145
  __selectRef
144
146
  } = props
145
147
 
@@ -159,7 +161,6 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
159
161
  visibleLength: 0
160
162
  })
161
163
 
162
- const scrollEventThrottle = 50
163
164
  const hasCallScrollToUpper = useRef(true)
164
165
  const hasCallScrollToLower = useRef(false)
165
166
  const initialTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
@@ -202,6 +203,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
202
203
 
203
204
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
204
205
 
206
+ const lastOffset = useRef(0)
207
+
205
208
  if (scrollX && scrollY) {
206
209
  warn('scroll-x and scroll-y cannot be set to true at the same time, Mpx will use the value of scroll-y as the criterion')
207
210
  }
@@ -263,7 +266,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
263
266
  function onStartReached (e: NativeSyntheticEvent<NativeScrollEvent>) {
264
267
  const { bindscrolltoupper } = props
265
268
  const { offset } = scrollOptions.current
266
- if (bindscrolltoupper && (offset <= upperThreshold)) {
269
+ const isScrollingBackward = offset < lastOffset.current
270
+ if (bindscrolltoupper && (offset <= upperThreshold) && isScrollingBackward) {
267
271
  if (!hasCallScrollToUpper.current) {
268
272
  bindscrolltoupper(
269
273
  getCustomEvent('scrolltoupper', e, {
@@ -284,13 +288,15 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
284
288
  const { bindscrolltolower } = props
285
289
  const { contentLength, visibleLength, offset } = scrollOptions.current
286
290
  const distanceFromEnd = contentLength - visibleLength - offset
287
- if (bindscrolltolower && (distanceFromEnd < lowerThreshold)) {
291
+ const isScrollingForward = offset > lastOffset.current
292
+
293
+ if (bindscrolltolower && (distanceFromEnd < lowerThreshold) && isScrollingForward) {
288
294
  if (!hasCallScrollToLower.current) {
289
295
  hasCallScrollToLower.current = true
290
296
  bindscrolltolower(
291
297
  getCustomEvent('scrolltolower', e, {
292
298
  detail: {
293
- direction: scrollX ? 'right' : 'botttom'
299
+ direction: scrollX ? 'right' : 'bottom'
294
300
  },
295
301
  layoutRef
296
302
  }, props)
@@ -345,6 +351,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
345
351
  onStartReached(e)
346
352
  onEndReached(e)
347
353
  updateIntersection()
354
+ // 在 onStartReached、onEndReached 执行完后更新 lastOffset
355
+ lastOffset.current = scrollOptions.current.offset
348
356
  }
349
357
 
350
358
  function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
@@ -367,6 +375,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
367
375
  onStartReached(e)
368
376
  onEndReached(e)
369
377
  updateIntersection()
378
+ lastOffset.current = scrollOptions.current.offset
370
379
  }
371
380
  function updateIntersection () {
372
381
  if (enableTriggerIntersectionObserver && intersectionObservers) {
@@ -0,0 +1,32 @@
1
+ import { View, ViewProps, TextStyle } from 'react-native'
2
+ import { createElement, forwardRef, useRef } from 'react'
3
+ import useNodesRef, { HandlerRef } from './useNodesRef'
4
+ import { extendObject, splitProps, splitStyle, wrapChildren } from './utils'
5
+
6
+ const _View2 = forwardRef<HandlerRef<View, ViewProps>, ViewProps>((simpleViewProps: ViewProps, ref) => {
7
+ const nodeRef = useRef(null)
8
+
9
+ const { textProps, innerProps: props = {} } = splitProps(simpleViewProps)
10
+
11
+ const { textStyle, innerStyle = {} } = splitStyle(props.style || {})
12
+
13
+ useNodesRef(props, ref, nodeRef, {
14
+ style: innerStyle || {}
15
+ })
16
+
17
+ return createElement(View, extendObject({}, props, {
18
+ style: innerStyle,
19
+ ref: nodeRef
20
+ }), wrapChildren(
21
+ props,
22
+ {
23
+ hasVarDec: false,
24
+ textStyle: textStyle as TextStyle,
25
+ textProps
26
+ }
27
+ ))
28
+ })
29
+
30
+ _View2.displayName = 'MpxSimpleView'
31
+
32
+ export default _View2
@@ -55,6 +55,7 @@ interface SwiperProps {
55
55
  'parent-width'?: number;
56
56
  'parent-height'?: number;
57
57
  'external-var-context'?: Record<string, any>;
58
+ disableGesture?: boolean;
58
59
  bindchange?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void;
59
60
  }
60
61
 
@@ -136,7 +137,8 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
136
137
  'external-var-context': externalVarContext,
137
138
  style = {},
138
139
  autoplay = false,
139
- circular = false
140
+ circular = false,
141
+ disableGesture = false
140
142
  } = props
141
143
  const easeingFunc = props['easing-function'] || 'default'
142
144
  const easeDuration = props.duration || 500
@@ -730,7 +732,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
730
732
  </View>)
731
733
  }
732
734
 
733
- if (children.length === 1) {
735
+ if (children.length === 1 || disableGesture) {
734
736
  return renderSwiper()
735
737
  } else {
736
738
  return (<GestureDetector gesture={gestureHandler}>
@@ -16,6 +16,7 @@ import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wra
16
16
  import { error } from '@mpxjs/utils'
17
17
  import LinearGradient from 'react-native-linear-gradient'
18
18
  import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
19
+ import Portal from './mpx-portal'
19
20
 
20
21
  export interface _ViewProps extends ViewProps {
21
22
  style?: ExtendedViewStyle
@@ -79,7 +80,7 @@ type PreImageInfo = {
79
80
  type ImageProps = {
80
81
  style: ImageStyle,
81
82
  src?: string,
82
- source?: {uri: string },
83
+ source?: { uri: string },
83
84
  colors: Array<string>,
84
85
  locations?: Array<number>
85
86
  angle?: number
@@ -483,8 +484,8 @@ function parseLinearGradient (text: string): LinearInfo | undefined {
483
484
  }
484
485
 
485
486
  function parseBgImage (text: string): {
486
- linearInfo?: LinearInfo;
487
- direction?: string;
487
+ linearInfo?: LinearInfo
488
+ direction?: string
488
489
  type?: 'image' | 'linear'
489
490
  src?: string
490
491
  } {
@@ -578,7 +579,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
578
579
  if (!src) {
579
580
  setShow(false)
580
581
  return
581
- // 一开始未出现,数据改变时出现
582
+ // 一开始未出现,数据改变时出现
582
583
  } else if (!(needLayout || needImageSize)) {
583
584
  setShow(true)
584
585
  return
@@ -602,7 +603,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
602
603
  }
603
604
  })
604
605
  }
605
- // type 添加type 处理无渐变 有渐变的场景
606
+ // type 添加type 处理无渐变 有渐变的场景
606
607
  }, [src, type])
607
608
 
608
609
  if (!type) return null
@@ -636,7 +637,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
636
637
  }
637
638
 
638
639
  return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
639
- {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
640
+ {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
640
641
  {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size), enableFastImage))}
641
642
  </View>
642
643
  }
@@ -703,6 +704,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
703
704
  const {
704
705
  normalStyle,
705
706
  hasSelfPercent,
707
+ hasPositionFixed,
706
708
  hasVarDec,
707
709
  varContextRef,
708
710
  setWidth,
@@ -769,13 +771,18 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
769
771
  enableFastImage
770
772
  })
771
773
 
772
- const BaseComponent = enableStyleAnimation
774
+ let finalComponent: JSX.Element = enableStyleAnimation
773
775
  ? createElement(Animated.View, innerProps, childNode)
774
776
  : createElement(View, innerProps, childNode)
775
777
 
776
- return enableHover
777
- ? createElement(GestureDetector, { gesture: gesture as PanGesture }, BaseComponent)
778
- : BaseComponent
778
+ if (enableHover) {
779
+ finalComponent = createElement(GestureDetector, { gesture: gesture as PanGesture }, finalComponent)
780
+ }
781
+
782
+ if (hasPositionFixed) {
783
+ finalComponent = createElement(Portal, null, finalComponent)
784
+ }
785
+ return finalComponent
779
786
  })
780
787
 
781
788
  _View.displayName = 'MpxView'
@@ -89,7 +89,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
89
89
  button: 'Reload'
90
90
  }
91
91
  }
92
- const currentErrorText = errorText[(mpx.i18n.locale as LanguageCode) || 'zh-CN']
92
+ const currentErrorText = errorText[(mpx.i18n?.locale as LanguageCode) || 'zh-CN']
93
93
 
94
94
  if (props.style) {
95
95
  warn('The web-view component does not support the style prop.')
@@ -103,11 +103,11 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
103
103
  const statusCode = useRef<string|number>('')
104
104
  const [isLoaded, setIsLoaded] = useState<boolean>(true)
105
105
  const defaultWebViewStyle = {
106
- position: 'absolute' as 'absolute' | 'relative' | 'static',
107
- left: 0 as number,
108
- right: 0 as number,
109
- top: 0 as number,
110
- bottom: 0 as number
106
+ position: 'absolute' as const,
107
+ left: 0,
108
+ right: 0,
109
+ top: 0,
110
+ bottom: 0
111
111
  }
112
112
  const canGoBack = useRef<boolean>(false)
113
113
  const isNavigateBack = useRef<boolean>(false)
@@ -123,7 +123,10 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
123
123
  const navigation = useNavigation()
124
124
 
125
125
  useEffect(() => {
126
- const beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
126
+ let beforeRemoveSubscription:any
127
+ if (__mpx_mode__ !== 'ios') {
128
+ beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
129
+ }
127
130
  return () => {
128
131
  if (isFunction(beforeRemoveSubscription)) {
129
132
  beforeRemoveSubscription()
@@ -140,7 +143,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
140
143
  }
141
144
 
142
145
  const _reload = function () {
143
- if (__mpx_mode__ === 'android') {
146
+ if (__mpx_mode__ === 'android' || __mpx_mode__ === 'harmony') {
144
147
  fristLoaded.current = false // 安卓需要重新设置
145
148
  }
146
149
  setPageLoadErr(false)
@@ -186,7 +189,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
186
189
  }
187
190
 
188
191
  const _onLoadProgress = function (event: WebViewProgressEvent) {
189
- if (__mpx_mode__ === 'android') {
192
+ if (__mpx_mode__ === 'android' || __mpx_mode__ === 'harmony') {
190
193
  canGoBack.current = event.nativeEvent.canGoBack
191
194
  }
192
195
  }
@@ -302,8 +305,8 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
302
305
  }
303
306
  }
304
307
  const onLoadEnd = function (res: WebViewEvent) {
305
- if (__mpx_mode__ === 'android') {
306
- res.persist()
308
+ res.persist()
309
+ if (__mpx_mode__ === 'android' || __mpx_mode__ === 'harmony') {
307
310
  setTimeout(() => {
308
311
  onLoadEndHandle(res)
309
312
  }, 0)
@@ -329,7 +332,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
329
332
  }
330
333
 
331
334
  return (
332
- <Portal key={pageLoadErr ? 'error' : 'webview'}>
335
+ <Portal>
333
336
  {pageLoadErr
334
337
  ? (
335
338
  <View style={[styles.loadErrorContext, defaultWebViewStyle]}>
@@ -46,7 +46,7 @@ interface InnerRef {
46
46
  };
47
47
  }
48
48
  interface UseInnerPropsConfig {
49
- layoutRef: LayoutRef;
49
+ layoutRef?: LayoutRef;
50
50
  disableTouch?: boolean;
51
51
  disableTap?: boolean
52
52
  }
@@ -1,4 +1,4 @@
1
- declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | 'qa' | 'jd' | 'android' | 'ios'
1
+ declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | 'qa' | 'jd' | 'android' | 'ios' | 'harmony'
2
2
  declare module '@mpxjs/utils' {
3
3
  export function isEmptyObject (obj: Object): boolean
4
4
  export function isFunction (fn: unknown): boolean
@@ -13,7 +13,7 @@ import {
13
13
  WithTimingConfig,
14
14
  AnimationCallback
15
15
  } from 'react-native-reanimated'
16
- import { error } from '@mpxjs/utils'
16
+ import { error, hasOwn } from '@mpxjs/utils'
17
17
  import { ExtendedViewStyle } from './types/common'
18
18
  import type { _ViewProps } from './mpx-view'
19
19
 
@@ -50,20 +50,20 @@ const EasingKey = {
50
50
  const TransformInitial: ExtendedViewStyle = {
51
51
  // matrix: 0,
52
52
  // matrix3d: 0,
53
- rotate: '0deg',
53
+ // rotate: '0deg',
54
54
  rotateX: '0deg',
55
55
  rotateY: '0deg',
56
56
  rotateZ: '0deg',
57
57
  // rotate3d:[0,0,0]
58
- scale: 1,
58
+ // scale: 1,
59
59
  // scale3d: [1, 1, 1],
60
60
  scaleX: 1,
61
61
  scaleY: 1,
62
62
  // scaleZ: 1,
63
- skew: 0,
63
+ // skew: 0,
64
64
  skewX: '0deg',
65
65
  skewY: '0deg',
66
- translate: 0,
66
+ // translate: 0,
67
67
  // translate3d: 0,
68
68
  translateX: 0,
69
69
  translateY: 0
@@ -127,23 +127,23 @@ const parseTransform = (transformStr: string) => {
127
127
  case 'skewX':
128
128
  case 'skewY':
129
129
  case 'perspective':
130
+ // rotate 处理成 rotateZ
131
+ key = key === 'rotate' ? 'rotateZ' : key
130
132
  // 单个值处理
131
133
  transform.push({ [key]: global.__formatValue(val) })
132
134
  break
133
135
  case 'matrix':
134
- case 'matrix3d':
135
136
  transform.push({ [key]: parseValues(val, ',').map(val => +val) })
136
137
  break
137
138
  case 'translate':
138
139
  case 'scale':
139
140
  case 'skew':
140
- case 'rotate3d': // x y z angle
141
141
  case 'translate3d': // x y 支持 z不支持
142
142
  case 'scale3d': // x y 支持 z不支持
143
143
  {
144
144
  // 2 个以上的值处理
145
145
  key = key.replace('3d', '')
146
- const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
146
+ const vals = parseValues(val, ',').splice(0, 3)
147
147
  // scale(.5) === scaleX(.5) scaleY(.5)
148
148
  if (vals.length === 1 && key === 'scale') {
149
149
  vals.push(vals[0])
@@ -167,6 +167,14 @@ const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
167
167
  })
168
168
  }
169
169
 
170
+ // transform 数组转对象
171
+ function getTransformObj (transforms: { [propName: string]: string | number }[]) {
172
+ 'worklet'
173
+ return transforms.reduce((transformObj, item) => {
174
+ return Object.assign(transformObj, item)
175
+ }, {} as { [propName: string]: string | number })
176
+ }
177
+
170
178
  export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean }) {
171
179
  const { style = {}, animation, enableAnimation } = props
172
180
 
@@ -187,7 +195,9 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
187
195
  // 记录动画key的style样式值 没有的话设置为false
188
196
  // eslint-disable-next-line react-hooks/rules-of-hooks
189
197
  const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean})
190
- // const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
198
+ // 记录上次style map
199
+ // eslint-disable-next-line react-hooks/rules-of-hooks
200
+ const lastStyleRef = useRef({} as {[propName: keyof ExtendedViewStyle]: number|string})
191
201
  // ** 全量 style prop sharedValue
192
202
  // 不能做增量的原因:
193
203
  // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
@@ -200,6 +210,12 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
200
210
  return valMap
201
211
  }, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
202
212
  }, [])
213
+ // ** style更新同步
214
+ // eslint-disable-next-line react-hooks/rules-of-hooks
215
+ useEffect(() => {
216
+ // style 更新后同步更新 lastStyleRef & shareValMap
217
+ updateStyleVal()
218
+ }, [style])
203
219
  // ** 获取动画样式prop & 驱动动画
204
220
  // eslint-disable-next-line react-hooks/rules-of-hooks
205
221
  useEffect(() => {
@@ -211,16 +227,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
211
227
  // 驱动动画
212
228
  createAnimation(keys)
213
229
  }, [id])
214
- // 同步style更新
215
- // useEffect(() => {
216
- // Object.keys(animatedKeys.current).forEach(key => {
217
- // const originVal = getOriginalStyleVal(key, isTransform(key))
218
- // if (originVal && animatedKeys.current[key] !== originVal) {
219
- // animatedKeys.current[key] = originVal
220
- // shareValMap[key].value = originVal
221
- // }
222
- // })
223
- // }, [style])
224
230
  // ** 清空动画
225
231
  // eslint-disable-next-line react-hooks/rules-of-hooks
226
232
  useEffect(() => {
@@ -230,7 +236,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
230
236
  })
231
237
  }
232
238
  }, [])
233
- // 根据 animation action 创建&驱动动画 key => wi
239
+ // 根据 animation action 创建&驱动动画
234
240
  function createAnimation (animatedKeys: string[] = []) {
235
241
  const actions = animation?.actions || []
236
242
  const sequence = {} as { [propName: keyof ExtendedViewStyle]: (string|number)[] }
@@ -286,6 +292,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
286
292
  : withTiming(value, { duration, easing })
287
293
  return delay ? withDelay(delay, animation) : animation
288
294
  }
295
+ // 获取样式初始值(prop style or 默认值)
289
296
  function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
290
297
  if (isTransform && Array.isArray(originalStyle.transform)) {
291
298
  let initialVal = InitialValue[key]
@@ -297,38 +304,19 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
297
304
  }
298
305
  return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key]
299
306
  }
300
- // 从 prop style 中获取样式初始值 没有为undefined
301
- // function getOriginalStyleVal (key: keyof ExtendedViewStyle, isTransform = false) {
302
- // if (isTransform && Array.isArray(originalStyle.transform)) {
303
- // let initialVal = undefined // InitialValue[key]
304
- // // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
305
- // originalStyle.transform.forEach(item => {
306
- // if (item[key] !== undefined) initialVal = item[key]
307
- // })
308
- // return initialVal
309
- // }
310
- // return originalStyle[key] // === undefined ? InitialValue[key] : originalStyle[key]
311
- // }
312
- // 获取动画shareVal初始值(prop style or 默认值)
313
- // function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
314
- // const originalVal = getOriginalStyleVal(key, isTransform)
315
- // return originalVal === undefined ? InitialValue[key] : originalStyle[key]
316
- // }
317
307
  // 循环 animation actions 获取所有有动画的 style prop name
318
308
  function getAnimatedStyleKeys () {
319
309
  return (animation?.actions || []).reduce((keyMap, action) => {
320
310
  const { rules, transform } = action
321
311
  const ruleArr = [...rules.keys(), ...transform.keys()]
322
312
  ruleArr.forEach(key => {
323
- // const originalVal = getOriginalStyleVal(key, isTransform(key))
324
- // if (!keyMap[key]) keyMap[key] = originalVal === undefined ? false : originalVal
325
313
  if (!keyMap[key]) keyMap[key] = true
326
314
  })
327
315
  return keyMap
328
316
  }, animatedKeys.current)
329
317
  }
330
318
  // animated key transform 格式化
331
- function formatAnimatedKeys (keys: string[] = []) {
319
+ function formatAnimatedKeys (keys: string[]) {
332
320
  const animatedKeys = [] as (string|string[])[]
333
321
  const transforms = [] as string[]
334
322
  keys.forEach(key => {
@@ -341,13 +329,23 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
341
329
  if (transforms.length) animatedKeys.push(transforms)
342
330
  return animatedKeys
343
331
  }
344
- // transform 数组转对象
345
- function getTransformObj () {
346
- 'worklet'
347
- const transforms = originalStyle.transform || []
348
- return transforms.reduce((transformObj, item) => {
349
- return Object.assign(transformObj, item)
350
- }, {} as { [propName: string]: string | number })
332
+ // 设置 lastShareValRef & shareValMap
333
+ function updateStyleVal () {
334
+ Object.entries(originalStyle).forEach(([key, value]) => {
335
+ if (key === 'transform') {
336
+ Object.entries(getTransformObj(value)).forEach(([key, value]) => {
337
+ if (value !== lastStyleRef.current[key]) {
338
+ lastStyleRef.current[key] = value
339
+ shareValMap[key].value = value
340
+ }
341
+ })
342
+ } else if (hasOwn(shareValMap, key)) {
343
+ if (value !== lastStyleRef.current[key]) {
344
+ lastStyleRef.current[key] = value
345
+ shareValMap[key].value = value
346
+ }
347
+ }
348
+ })
351
349
  }
352
350
  // ** 生成动画样式
353
351
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -356,7 +354,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
356
354
  return animatedStyleKeys.value.reduce((styles, key) => {
357
355
  // console.info('getAnimationStyles', key, shareValMap[key].value)
358
356
  if (Array.isArray(key)) {
359
- const transformStyle = getTransformObj()
357
+ const transformStyle = getTransformObj(originalStyle.transform || [])
360
358
  key.forEach((transformKey) => {
361
359
  transformStyle[transformKey] = shareValMap[transformKey].value
362
360
  })