@mpxjs/webpack-plugin 2.10.6-beta.2 → 2.10.6-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 (46) hide show
  1. package/lib/file-loader.js +1 -1
  2. package/lib/index.js +35 -14
  3. package/lib/platform/index.js +2 -4
  4. package/lib/platform/json/wx/index.js +43 -25
  5. package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
  6. package/lib/platform/template/wx/component-config/index.js +2 -2
  7. package/lib/platform/template/wx/component-config/template.js +1 -26
  8. package/lib/platform/template/wx/index.js +5 -11
  9. package/lib/react/LoadAsyncChunkModule.js +68 -0
  10. package/lib/react/index.js +3 -1
  11. package/lib/react/processJSON.js +72 -17
  12. package/lib/react/processScript.js +4 -3
  13. package/lib/react/script-helper.js +92 -18
  14. package/lib/runtime/components/react/AsyncContainer.tsx +217 -0
  15. package/lib/runtime/components/react/AsyncSuspense.tsx +81 -0
  16. package/lib/runtime/components/react/dist/AsyncContainer.jsx +160 -0
  17. package/lib/runtime/components/react/dist/AsyncSuspense.jsx +68 -0
  18. package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
  19. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
  20. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -2
  21. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +2 -2
  22. package/lib/runtime/components/react/dist/mpx-swiper.jsx +53 -27
  23. package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
  24. package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
  25. package/lib/runtime/components/react/dist/utils.jsx +84 -0
  26. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  27. package/lib/runtime/components/react/mpx-input.tsx +1 -1
  28. package/lib/runtime/components/react/mpx-movable-view.tsx +2 -2
  29. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -2
  30. package/lib/runtime/components/react/mpx-swiper.tsx +53 -25
  31. package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
  32. package/lib/runtime/components/react/types/global.d.ts +15 -0
  33. package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
  34. package/lib/runtime/components/react/utils.tsx +83 -1
  35. package/lib/runtime/optionProcessor.js +2 -2
  36. package/lib/template-compiler/compiler.js +11 -61
  37. package/lib/utils/dom-tag-config.js +17 -3
  38. package/lib/web/index.js +0 -2
  39. package/lib/web/processScript.js +7 -29
  40. package/lib/web/processTemplate.js +4 -10
  41. package/lib/web/script-helper.js +1 -1
  42. package/package.json +1 -1
  43. package/lib/dependencies/WriteVfsDependency.js +0 -46
  44. package/lib/utils/get-template-content.js +0 -47
  45. package/lib/web/template2vue.js +0 -280
  46. package/lib/web/wxml-template-loader.js +0 -29
@@ -223,14 +223,14 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
223
223
  setHeight(height || 0);
224
224
  }
225
225
  nodeRef.current?.measure((x, y, width, height) => {
226
- const { y: navigationY = 0 } = navigation?.layout || {};
226
+ const { top: navigationY = 0 } = navigation?.layout || {};
227
227
  layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 };
228
228
  resetBoundaryAndCheck({ width, height });
229
229
  });
230
230
  props.onLayout && props.onLayout(e);
231
231
  };
232
232
  const extendEvent = useCallback((e, type) => {
233
- const { y: navigationY = 0 } = navigation?.layout || {};
233
+ const { top: navigationY = 0 } = navigation?.layout || {};
234
234
  const touchArr = [e.changedTouches, e.allTouches];
235
235
  touchArr.forEach(touches => {
236
236
  touches && touches.forEach((item) => {
@@ -2,7 +2,7 @@ import Animated, { useAnimatedStyle, interpolate } from 'react-native-reanimated
2
2
  import { forwardRef, useRef, useContext, createElement } from 'react';
3
3
  import useInnerProps from './getInnerListeners';
4
4
  import useNodesRef from './useNodesRef'; // 引入辅助函数
5
- import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject } from './utils';
5
+ import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject, isHarmony } from './utils';
6
6
  import { SwiperContext } from './context';
7
7
  const _SwiperItem = forwardRef((props, ref) => {
8
8
  const { 'enable-var': enableVar, 'external-var-context': externalVarContext, style, customStyle, itemIndex } = props;
@@ -29,7 +29,7 @@ const _SwiperItem = forwardRef((props, ref) => {
29
29
  'style'
30
30
  ], { layoutRef });
31
31
  const itemAnimatedStyle = useAnimatedStyle(() => {
32
- if (!step.value)
32
+ if (!step.value && !isHarmony)
33
33
  return {};
34
34
  const inputRange = [step.value, 0];
35
35
  const outputRange = [0.7, 1];
@@ -125,6 +125,10 @@ const SwiperWrapper = forwardRef((props, ref) => {
125
125
  const moveTranstion = useSharedValue(0);
126
126
  // 记录从onBegin 到 onTouchesUp 的时间
127
127
  const moveTime = useSharedValue(0);
128
+ // 记录从onBegin 到 onTouchesCancelled 另外一个方向移动的距离
129
+ const anotherDirectionMove = useSharedValue(0);
130
+ // 另一个方向的
131
+ const anotherAbso = 'absolute' + (dir === 'x' ? 'y' : 'x').toUpperCase();
128
132
  const timerId = useRef(0);
129
133
  const intervalTimer = props.interval || 500;
130
134
  const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
@@ -405,7 +409,11 @@ const SwiperWrapper = forwardRef((props, ref) => {
405
409
  }
406
410
  }, [children.length]);
407
411
  useEffect(() => {
408
- updateCurrent(props.current || 0, step.value);
412
+ // 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
413
+ // 2. 手指滑动过程中更新索引,外部会把current再穿进来,导致offset直接更新了
414
+ if (props.current !== currentIndex.value) {
415
+ updateCurrent(props.current || 0, step.value);
416
+ }
409
417
  }, [props.current]);
410
418
  useEffect(() => {
411
419
  autoplayShared.value = autoplay;
@@ -468,20 +476,26 @@ const SwiperWrapper = forwardRef((props, ref) => {
468
476
  targetOffset: -moveToTargetPos
469
477
  };
470
478
  }
471
- function canMove(eventData) {
479
+ function checkUnCircular(eventData) {
472
480
  'worklet';
473
481
  const { translation } = eventData;
474
482
  const currentOffset = Math.abs(offset.value);
475
- if (!circularShared.value) {
476
- if (translation < 0) {
477
- return currentOffset < step.value * (childrenLength.value - 1);
478
- }
479
- else {
480
- return currentOffset > 0;
481
- }
483
+ // 向右滑动swiper
484
+ if (translation < 0) {
485
+ const boundaryOffset = step.value * (childrenLength.value - 1);
486
+ const gestureMovePos = Math.abs(translation) + currentOffset;
487
+ return {
488
+ // 防止快速连续向右滑动时,手势移动的距离 当前的offset超出边界
489
+ targetOffset: gestureMovePos > boundaryOffset ? -boundaryOffset : offset.value + translation,
490
+ canMove: currentOffset < boundaryOffset
491
+ };
482
492
  }
483
493
  else {
484
- return true;
494
+ const gestureMovePos = currentOffset - translation;
495
+ return {
496
+ targetOffset: gestureMovePos < 0 ? 0 : offset.value + translation,
497
+ canMove: currentOffset > 0
498
+ };
485
499
  }
486
500
  }
487
501
  function handleEnd(eventData) {
@@ -541,7 +555,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
541
555
  }
542
556
  });
543
557
  }
544
- function handleLongPress() {
558
+ function computeHalf() {
545
559
  'worklet';
546
560
  const currentOffset = Math.abs(offset.value);
547
561
  let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value;
@@ -551,6 +565,14 @@ const SwiperWrapper = forwardRef((props, ref) => {
551
565
  // 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
552
566
  const diffOffset = preOffset - currentOffset;
553
567
  const half = Math.abs(diffOffset) > step.value / 2;
568
+ return {
569
+ diffOffset,
570
+ half
571
+ };
572
+ }
573
+ function handleLongPress() {
574
+ 'worklet';
575
+ const { diffOffset, half } = computeHalf();
554
576
  if (+diffOffset === 0) {
555
577
  runOnJS(resumeLoop)();
556
578
  }
@@ -610,19 +632,30 @@ const SwiperWrapper = forwardRef((props, ref) => {
610
632
  runOnJS(pauseLoop)();
611
633
  preAbsolutePos.value = e[strAbso];
612
634
  moveTranstion.value = e[strAbso];
635
+ anotherDirectionMove.value = e[anotherAbso];
613
636
  moveTime.value = new Date().getTime();
614
637
  })
615
- .onTouchesMove((e) => {
638
+ .onUpdate((e) => {
616
639
  'worklet';
617
640
  if (touchfinish.value)
618
641
  return;
619
- const touchEventData = e.changedTouches[0];
620
- const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
642
+ const moveDistance = e[strAbso] - preAbsolutePos.value;
621
643
  const eventData = {
622
644
  translation: moveDistance
623
645
  };
624
- // 处理用户一直拖拽到临界点的场景, 不会执行onEnd
625
- if (!circularShared.value && !canMove(eventData)) {
646
+ // 1. 在Move过程中,如果手指一直没抬起来,超过一半的话也会更新索引
647
+ const { half } = computeHalf();
648
+ if (half) {
649
+ const { selectedIndex } = getTargetPosition(eventData);
650
+ currentIndex.value = selectedIndex;
651
+ }
652
+ // 2. 处理用户一直拖拽到临界点的场景, 不会执行onEnd
653
+ const { canMove, targetOffset } = checkUnCircular(eventData);
654
+ if (!circularShared.value) {
655
+ if (canMove) {
656
+ offset.value = targetOffset;
657
+ preAbsolutePos.value = e[strAbso];
658
+ }
626
659
  return;
627
660
  }
628
661
  const { isBoundary, resetOffset } = reachBoundary(eventData);
@@ -632,30 +665,23 @@ const SwiperWrapper = forwardRef((props, ref) => {
632
665
  else {
633
666
  offset.value = moveDistance + offset.value;
634
667
  }
635
- preAbsolutePos.value = touchEventData[strAbso];
668
+ preAbsolutePos.value = e[strAbso];
636
669
  })
637
- .onTouchesUp((e) => {
670
+ .onFinalize((e) => {
638
671
  'worklet';
639
672
  if (touchfinish.value)
640
673
  return;
641
- const touchEventData = e.changedTouches[0];
642
- const moveDistance = touchEventData[strAbso] - moveTranstion.value;
674
+ const moveDistance = e[strAbso] - moveTranstion.value;
643
675
  touchfinish.value = true;
644
676
  const eventData = {
645
677
  translation: moveDistance
646
678
  };
647
- if (childrenLength.value === 1) {
648
- return handleBackInit();
649
- }
650
- // 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
651
- if (!circularShared.value && !canMove(eventData)) {
652
- return;
653
- }
654
679
  const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000;
655
680
  if (Math.abs(strVelocity) < longPressRatio) {
656
681
  handleLongPress();
657
682
  }
658
683
  else {
684
+ // 如果触发了onTouchesCancelled,不会触发onUpdate不会更新offset值, 索引不会变更
659
685
  handleEnd(eventData);
660
686
  }
661
687
  })
@@ -1,6 +1,7 @@
1
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 } 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';
@@ -55,8 +56,8 @@ const _WebView = forwardRef((props, ref) => {
55
56
  const webViewRef = useRef(null);
56
57
  const fristLoaded = useRef(false);
57
58
  const isLoadError = useRef(false);
59
+ const isNavigateBack = useRef(false);
58
60
  const statusCode = useRef('');
59
- const [isLoaded, setIsLoaded] = useState(true);
60
61
  const defaultWebViewStyle = {
61
62
  position: 'absolute',
62
63
  left: 0,
@@ -64,27 +65,18 @@ const _WebView = forwardRef((props, ref) => {
64
65
  top: 0,
65
66
  bottom: 0
66
67
  };
67
- const canGoBack = useRef(false);
68
- const isNavigateBack = useRef(false);
69
- const beforeRemoveHandle = (e) => {
70
- if (canGoBack.current && !isNavigateBack.current) {
68
+ const navigation = useNavigation();
69
+ const [isIntercept, setIsIntercept] = useState(false);
70
+ usePreventRemove(isIntercept, (event) => {
71
+ const { data } = event;
72
+ if (isNavigateBack.current) {
73
+ navigation?.dispatch(data.action);
74
+ }
75
+ else {
71
76
  webViewRef.current?.goBack();
72
- e.preventDefault();
73
77
  }
74
78
  isNavigateBack.current = false;
75
- };
76
- const navigation = useNavigation();
77
- // useEffect(() => {
78
- // let beforeRemoveSubscription:any
79
- // if (__mpx_mode__ !== 'ios') {
80
- // beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
81
- // }
82
- // return () => {
83
- // if (isFunction(beforeRemoveSubscription)) {
84
- // beforeRemoveSubscription()
85
- // }
86
- // }
87
- // }, [])
79
+ });
88
80
  useNodesRef(props, ref, webViewRef, {
89
81
  style: defaultWebViewStyle
90
82
  });
@@ -131,13 +123,13 @@ const _WebView = forwardRef((props, ref) => {
131
123
  };
132
124
  const _changeUrl = function (navState) {
133
125
  if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
134
- canGoBack.current = navState.canGoBack;
135
126
  currentPage.__webViewUrl = navState.url;
127
+ setIsIntercept(navState.canGoBack);
136
128
  }
137
129
  };
138
130
  const _onLoadProgress = function (event) {
139
131
  if (__mpx_mode__ !== 'ios') {
140
- canGoBack.current = event.nativeEvent.canGoBack;
132
+ setIsIntercept(event.nativeEvent.canGoBack);
141
133
  }
142
134
  };
143
135
  const _message = function (res) {
@@ -227,7 +219,6 @@ const _WebView = forwardRef((props, ref) => {
227
219
  };
228
220
  const onLoadEndHandle = function (res) {
229
221
  fristLoaded.current = true;
230
- setIsLoaded(true);
231
222
  const src = res.nativeEvent?.url;
232
223
  if (isLoadError.current) {
233
224
  isLoadError.current = false;
@@ -275,18 +266,13 @@ const _WebView = forwardRef((props, ref) => {
275
266
  setPageLoadErr(true);
276
267
  }
277
268
  };
278
- const onLoadStart = function () {
279
- if (!fristLoaded.current) {
280
- setIsLoaded(false);
281
- }
282
- };
283
269
  return (<Portal>
284
270
  {pageLoadErr
285
271
  ? (<View style={[styles.loadErrorContext, defaultWebViewStyle]}>
286
272
  <View style={styles.loadErrorText}><Text style={{ fontSize: 14, color: '#999999' }}>{currentErrorText.text}</Text></View>
287
273
  <View style={styles.loadErrorButton} onTouchEnd={_reload}><Text style={{ fontSize: 12, color: '#666666' }}>{currentErrorText.button}</Text></View>
288
274
  </View>)
289
- : (<WebView style={defaultWebViewStyle} pointerEvents={isLoaded ? 'auto' : 'none'} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} onLoadStart={onLoadStart} allowsBackForwardNavigationGestures={true}></WebView>)}
275
+ : (<WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} allowsBackForwardNavigationGestures={true}></WebView>)}
290
276
  </Portal>);
291
277
  });
292
278
  _WebView.displayName = 'MpxWebview';
@@ -48,90 +48,6 @@ const InitialValue = Object.assign({
48
48
  const TransformOrigin = 'transformOrigin';
49
49
  // transform
50
50
  const isTransform = (key) => Object.keys(TransformInitial).includes(key);
51
- // 多value解析
52
- const parseValues = (str, char = ' ') => {
53
- let stack = 0;
54
- let temp = '';
55
- const result = [];
56
- for (let i = 0; i < str.length; i++) {
57
- if (str[i] === '(') {
58
- stack++;
59
- }
60
- else if (str[i] === ')') {
61
- stack--;
62
- }
63
- // 非括号内 或者 非分隔字符且非空
64
- if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
65
- temp += str[i];
66
- }
67
- if ((stack === 0 && str[i] === char) || i === str.length - 1) {
68
- result.push(temp);
69
- temp = '';
70
- }
71
- }
72
- return result;
73
- };
74
- // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
75
- const parseTransform = (transformStr) => {
76
- const values = parseValues(transformStr);
77
- const transform = [];
78
- values.forEach(item => {
79
- const match = item.match(/([/\w]+)\((.+)\)/);
80
- if (match && match.length >= 3) {
81
- let key = match[1];
82
- const val = match[2];
83
- switch (key) {
84
- case 'translateX':
85
- case 'translateY':
86
- case 'scaleX':
87
- case 'scaleY':
88
- case 'rotateX':
89
- case 'rotateY':
90
- case 'rotateZ':
91
- case 'rotate':
92
- case 'skewX':
93
- case 'skewY':
94
- case 'perspective':
95
- // rotate 处理成 rotateZ
96
- key = key === 'rotate' ? 'rotateZ' : key;
97
- // 单个值处理
98
- transform.push({ [key]: global.__formatValue(val) });
99
- break;
100
- case 'matrix':
101
- transform.push({ [key]: parseValues(val, ',').map(val => +val) });
102
- break;
103
- case 'translate':
104
- case 'scale':
105
- case 'skew':
106
- case 'translate3d': // x y 支持 z不支持
107
- case 'scale3d': // x y 支持 z不支持
108
- {
109
- // 2 个以上的值处理
110
- key = key.replace('3d', '');
111
- const vals = parseValues(val, ',').splice(0, 3);
112
- // scale(.5) === scaleX(.5) scaleY(.5)
113
- if (vals.length === 1 && key === 'scale') {
114
- vals.push(vals[0]);
115
- }
116
- const xyz = ['X', 'Y', 'Z'];
117
- transform.push(...vals.map((v, index) => {
118
- return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
119
- }));
120
- break;
121
- }
122
- }
123
- }
124
- });
125
- return transform;
126
- };
127
- // format style
128
- const formatStyle = (style) => {
129
- if (!style.transform || Array.isArray(style.transform))
130
- return style;
131
- return Object.assign({}, style, {
132
- transform: parseTransform(style.transform)
133
- });
134
- };
135
51
  // transform 数组转对象
136
52
  function getTransformObj(transforms) {
137
53
  'worklet';
@@ -140,7 +56,7 @@ function getTransformObj(transforms) {
140
56
  }, {});
141
57
  }
142
58
  export default function useAnimationHooks(props) {
143
- const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props;
59
+ const { style: originalStyle = {}, animation, enableAnimation, transitionend, layoutRef } = props;
144
60
  const enableStyleAnimation = enableAnimation || !!animation;
145
61
  const enableAnimationRef = useRef(enableStyleAnimation);
146
62
  if (enableAnimationRef.current !== enableStyleAnimation) {
@@ -148,7 +64,6 @@ export default function useAnimationHooks(props) {
148
64
  }
149
65
  if (!enableAnimationRef.current)
150
66
  return { enableStyleAnimation: false };
151
- const originalStyle = formatStyle(style);
152
67
  // id 标识
153
68
  const id = animation?.id || -1;
154
69
  // 有动画样式的 style key
@@ -177,7 +92,7 @@ export default function useAnimationHooks(props) {
177
92
  useEffect(() => {
178
93
  // style 更新后同步更新 lastStyleRef & shareValMap
179
94
  updateStyleVal();
180
- }, [style]);
95
+ }, [originalStyle]);
181
96
  // ** 获取动画样式prop & 驱动动画
182
97
  // eslint-disable-next-line react-hooks/rules-of-hooks
183
98
  useEffect(() => {
@@ -237,6 +237,88 @@ function transformPosition(styleObj, meta) {
237
237
  meta.hasPositionFixed = true;
238
238
  }
239
239
  }
240
+ // 多value解析
241
+ function parseValues(str, char = ' ') {
242
+ let stack = 0;
243
+ let temp = '';
244
+ const result = [];
245
+ for (let i = 0; i < str.length; i++) {
246
+ if (str[i] === '(') {
247
+ stack++;
248
+ }
249
+ else if (str[i] === ')') {
250
+ stack--;
251
+ }
252
+ // 非括号内 或者 非分隔字符且非空
253
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
254
+ temp += str[i];
255
+ }
256
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
257
+ result.push(temp);
258
+ temp = '';
259
+ }
260
+ }
261
+ return result;
262
+ }
263
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
264
+ function parseTransform(transformStr) {
265
+ const values = parseValues(transformStr);
266
+ const transform = [];
267
+ values.forEach(item => {
268
+ const match = item.match(/([/\w]+)\((.+)\)/);
269
+ if (match && match.length >= 3) {
270
+ let key = match[1];
271
+ const val = match[2];
272
+ switch (key) {
273
+ case 'translateX':
274
+ case 'translateY':
275
+ case 'scaleX':
276
+ case 'scaleY':
277
+ case 'rotateX':
278
+ case 'rotateY':
279
+ case 'rotateZ':
280
+ case 'rotate':
281
+ case 'skewX':
282
+ case 'skewY':
283
+ case 'perspective':
284
+ // rotate 处理成 rotateZ
285
+ key = key === 'rotate' ? 'rotateZ' : key;
286
+ // 单个值处理
287
+ transform.push({ [key]: global.__formatValue(val) });
288
+ break;
289
+ case 'matrix':
290
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) });
291
+ break;
292
+ case 'translate':
293
+ case 'scale':
294
+ case 'skew':
295
+ case 'translate3d': // x y 支持 z不支持
296
+ case 'scale3d': // x y 支持 z不支持
297
+ {
298
+ // 2 个以上的值处理
299
+ key = key.replace('3d', '');
300
+ const vals = parseValues(val, ',').splice(0, 3);
301
+ // scale(.5) === scaleX(.5) scaleY(.5)
302
+ if (vals.length === 1 && key === 'scale') {
303
+ vals.push(vals[0]);
304
+ }
305
+ const xyz = ['X', 'Y', 'Z'];
306
+ transform.push(...vals.map((v, index) => {
307
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
308
+ }));
309
+ break;
310
+ }
311
+ }
312
+ }
313
+ });
314
+ return transform;
315
+ }
316
+ // format style transform
317
+ function transformTransform(style) {
318
+ if (!style.transform || Array.isArray(style.transform))
319
+ return;
320
+ style.transform = parseTransform(style.transform);
321
+ }
240
322
  export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
241
323
  const varStyle = {};
242
324
  const unoVarStyle = {};
@@ -365,6 +447,8 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
365
447
  transformPosition(normalStyle, positionMeta);
366
448
  // transform number enum stringify
367
449
  transformStringify(normalStyle);
450
+ // transform 字符串格式转化数组格式
451
+ transformTransform(normalStyle);
368
452
  return {
369
453
  hasVarDec,
370
454
  varContextRef,
@@ -24,7 +24,7 @@ const getTouchEvent = (
24
24
  ) => {
25
25
  const { navigation, propsRef, layoutRef } = config
26
26
  const props = propsRef.current
27
- const { y: navigationY = 0 } = navigation?.layout || {}
27
+ const { top: navigationY = 0 } = navigation?.layout || {}
28
28
  const nativeEvent = event.nativeEvent
29
29
  const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent
30
30
  const { id } = props
@@ -218,7 +218,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
218
218
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
219
219
 
220
220
  useEffect(() => {
221
- if (inputValue !== value) {
221
+ if (value !== tmpValue.current) {
222
222
  const parsed = parseValue(value)
223
223
  tmpValue.current = parsed
224
224
  setInputValue(parsed)
@@ -327,7 +327,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
327
327
  setHeight(height || 0)
328
328
  }
329
329
  nodeRef.current?.measure((x: number, y: number, width: number, height: number) => {
330
- const { y: navigationY = 0 } = navigation?.layout || {}
330
+ const { top: navigationY = 0 } = navigation?.layout || {}
331
331
  layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 }
332
332
  resetBoundaryAndCheck({ width, height })
333
333
  })
@@ -335,7 +335,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
335
335
  }
336
336
 
337
337
  const extendEvent = useCallback((e: any, type: 'start' | 'move' | 'end') => {
338
- const { y: navigationY = 0 } = navigation?.layout || {}
338
+ const { top: navigationY = 0 } = navigation?.layout || {}
339
339
  const touchArr = [e.changedTouches, e.allTouches]
340
340
  touchArr.forEach(touches => {
341
341
  touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number; clientX: number; clientY: number }) => {
@@ -3,7 +3,7 @@ import Animated, { useAnimatedStyle, interpolate, SharedValue } from 'react-nati
3
3
  import { ReactNode, forwardRef, useRef, useContext, createElement } from 'react'
4
4
  import useInnerProps from './getInnerListeners'
5
5
  import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
6
- import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject } from './utils'
6
+ import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject, isHarmony } from './utils'
7
7
  import { SwiperContext } from './context'
8
8
 
9
9
  interface SwiperItemProps {
@@ -80,7 +80,7 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
80
80
  ],
81
81
  { layoutRef })
82
82
  const itemAnimatedStyle = useAnimatedStyle(() => {
83
- if (!step.value) return {}
83
+ if (!step.value && !isHarmony) return {}
84
84
  const inputRange = [step.value, 0]
85
85
  const outputRange = [0.7, 1]
86
86
  // 实现元素的宽度跟随step从0到真实宽度,且不能触发重新渲染整个组件,通过AnimatedStyle的方式实现