@mpxjs/webpack-plugin 2.10.5 → 2.10.6

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 (62) hide show
  1. package/lib/index.js +10 -1
  2. package/lib/json-compiler/helper.js +1 -4
  3. package/lib/platform/template/wx/index.js +21 -1
  4. package/lib/resolver/PackageEntryPlugin.js +3 -1
  5. package/lib/runtime/components/react/dist/mpx-button.jsx +7 -2
  6. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
  7. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +20 -17
  8. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +7 -2
  9. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +7 -2
  10. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +7 -2
  11. package/lib/runtime/components/react/dist/mpx-image.jsx +9 -2
  12. package/lib/runtime/components/react/dist/mpx-input.jsx +7 -2
  13. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +1 -1
  14. package/lib/runtime/components/react/dist/mpx-label.jsx +7 -2
  15. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +7 -2
  16. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +76 -42
  17. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +11 -13
  18. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +8 -7
  19. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +26 -8
  20. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +9 -2
  21. package/lib/runtime/components/react/dist/mpx-radio.jsx +7 -2
  22. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +7 -2
  23. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -4
  24. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +11 -9
  25. package/lib/runtime/components/react/dist/mpx-swiper.jsx +82 -36
  26. package/lib/runtime/components/react/dist/mpx-switch.jsx +7 -2
  27. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -2
  28. package/lib/runtime/components/react/dist/mpx-video.jsx +7 -2
  29. package/lib/runtime/components/react/dist/mpx-view.jsx +2 -4
  30. package/lib/runtime/components/react/dist/utils.jsx +2 -2
  31. package/lib/runtime/components/react/mpx-button.tsx +9 -1
  32. package/lib/runtime/components/react/mpx-canvas/Image.ts +4 -4
  33. package/lib/runtime/components/react/mpx-canvas/index.tsx +24 -17
  34. package/lib/runtime/components/react/mpx-checkbox-group.tsx +9 -1
  35. package/lib/runtime/components/react/mpx-checkbox.tsx +9 -1
  36. package/lib/runtime/components/react/mpx-icon/index.tsx +9 -1
  37. package/lib/runtime/components/react/mpx-image.tsx +38 -19
  38. package/lib/runtime/components/react/mpx-input.tsx +10 -1
  39. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
  40. package/lib/runtime/components/react/mpx-label.tsx +9 -1
  41. package/lib/runtime/components/react/mpx-movable-area.tsx +7 -1
  42. package/lib/runtime/components/react/mpx-movable-view.tsx +75 -42
  43. package/lib/runtime/components/react/mpx-picker/index.tsx +18 -16
  44. package/lib/runtime/components/react/mpx-picker-view/index.tsx +22 -8
  45. package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +34 -30
  46. package/lib/runtime/components/react/mpx-radio-group.tsx +20 -9
  47. package/lib/runtime/components/react/mpx-radio.tsx +9 -1
  48. package/lib/runtime/components/react/mpx-rich-text/index.tsx +10 -2
  49. package/lib/runtime/components/react/mpx-scroll-view.tsx +14 -3
  50. package/lib/runtime/components/react/mpx-swiper-item.tsx +11 -19
  51. package/lib/runtime/components/react/mpx-swiper.tsx +95 -38
  52. package/lib/runtime/components/react/mpx-switch.tsx +10 -2
  53. package/lib/runtime/components/react/mpx-text.tsx +10 -2
  54. package/lib/runtime/components/react/mpx-video.tsx +7 -2
  55. package/lib/runtime/components/react/mpx-view.tsx +8 -4
  56. package/lib/runtime/components/react/utils.tsx +4 -4
  57. package/lib/runtime/components/web/mpx-web-view.vue +1 -1
  58. package/lib/runtime/mpxGlobal.js +1 -0
  59. package/lib/runtime/optionProcessor.d.ts +5 -0
  60. package/lib/template-compiler/bind-this.js +8 -7
  61. package/lib/wxs/pre-loader.js +1 -0
  62. package/package.json +4 -4
@@ -1,11 +1,12 @@
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 } from 'react';
4
+ import React, { forwardRef, useRef, useEffect, useMemo, createElement } from 'react';
5
5
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
6
6
  import useNodesRef from './useNodesRef'; // 引入辅助函数
7
- import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject } 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';
9
10
  /**
10
11
  * 默认的Style类型
11
12
  */
@@ -70,14 +71,19 @@ const easeMap = {
70
71
  easeInOutCubic: Easing.inOut(Easing.cubic)
71
72
  };
72
73
  const SwiperWrapper = forwardRef((props, ref) => {
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, style = {}, autoplay = false, circular = false } = props;
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 } = props;
74
75
  const easeingFunc = props['easing-function'] || 'default';
75
76
  const easeDuration = props.duration || 500;
76
77
  const horizontal = props.vertical !== undefined ? !props.vertical : true;
77
78
  const nodeRef = useRef(null);
78
- useNodesRef(props, ref, nodeRef, {});
79
+ // 手势协同gesture 1.0
80
+ const swiperGestureRef = useRef();
81
+ useNodesRef(props, ref, nodeRef, {
82
+ // scrollView内部会过滤是否绑定了gestureRef,withRef(swiperGestureRef)给gesture对象设置一个ref(2.0版本)
83
+ gestureRef: swiperGestureRef
84
+ });
79
85
  // 计算transfrom之类的
80
- const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, {
86
+ const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, hasPositionFixed, setWidth, setHeight } = useTransformStyle(style, {
81
87
  enableVar,
82
88
  externalVarContext,
83
89
  parentFontSize,
@@ -121,6 +127,23 @@ const SwiperWrapper = forwardRef((props, ref) => {
121
127
  const moveTime = useSharedValue(0);
122
128
  const timerId = useRef(0);
123
129
  const intervalTimer = props.interval || 500;
130
+ const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
131
+ const waitForHandlers = flatGesture(waitFor);
132
+ // 判断gesture手势是否需要协同处理、等待手势失败响应
133
+ const gestureSwitch = useRef(false);
134
+ // 初始化上一次的手势
135
+ const prevSimultaneousHandlersRef = useRef(originSimultaneousHandlers || []);
136
+ const prevWaitForHandlersRef = useRef(waitFor || []);
137
+ const hasSimultaneousHandlersChanged = prevSimultaneousHandlersRef.current.length !== (originSimultaneousHandlers?.length || 0) ||
138
+ (originSimultaneousHandlers || []).some((handler, index) => handler !== prevSimultaneousHandlersRef.current[index]);
139
+ const hasWaitForHandlersChanged = prevWaitForHandlersRef.current.length !== (waitFor?.length || 0) ||
140
+ (waitFor || []).some((handler, index) => handler !== prevWaitForHandlersRef.current[index]);
141
+ if (hasSimultaneousHandlersChanged || hasWaitForHandlersChanged) {
142
+ gestureSwitch.current = !gestureSwitch.current;
143
+ }
144
+ // 存储上一次的手势
145
+ prevSimultaneousHandlersRef.current = originSimultaneousHandlers || [];
146
+ prevWaitForHandlersRef.current = waitFor || [];
124
147
  const {
125
148
  // 存储layout布局信息
126
149
  layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef, onLayout: onWrapperLayout });
@@ -164,8 +187,6 @@ const SwiperWrapper = forwardRef((props, ref) => {
164
187
  }
165
188
  });
166
189
  function renderPagination() {
167
- if (children.length <= 1)
168
- return null;
169
190
  const activeColor = activeDotColor || '#007aff';
170
191
  const unActionColor = dotColor || 'rgba(0,0,0,.2)';
171
192
  // 正常渲染所有dots
@@ -490,6 +511,15 @@ const SwiperWrapper = forwardRef((props, ref) => {
490
511
  });
491
512
  }
492
513
  }
514
+ function handleBackInit() {
515
+ 'worklet';
516
+ // 微信的效果
517
+ // 1. 只有一个元素,即使设置了circular,也不会产生循环的效果,2. 可以响应手势,但是会有回弹的效果
518
+ offset.value = withTiming(0, {
519
+ duration: easeDuration,
520
+ easing: easeMap[easeingFunc]
521
+ });
522
+ }
493
523
  function handleBack(eventData) {
494
524
  'worklet';
495
525
  const { translation } = eventData;
@@ -596,7 +626,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
596
626
  return;
597
627
  }
598
628
  const { isBoundary, resetOffset } = reachBoundary(eventData);
599
- if (isBoundary && circularShared.value) {
629
+ if (childrenLength.value > 1 && isBoundary && circularShared.value) {
600
630
  offset.value = resetOffset;
601
631
  }
602
632
  else {
@@ -614,6 +644,9 @@ const SwiperWrapper = forwardRef((props, ref) => {
614
644
  const eventData = {
615
645
  translation: moveDistance
616
646
  };
647
+ if (childrenLength.value === 1) {
648
+ return handleBackInit();
649
+ }
617
650
  // 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
618
651
  if (!circularShared.value && !canMove(eventData)) {
619
652
  return;
@@ -625,11 +658,26 @@ const SwiperWrapper = forwardRef((props, ref) => {
625
658
  else {
626
659
  handleEnd(eventData);
627
660
  }
628
- });
661
+ })
662
+ .withRef(swiperGestureRef);
663
+ // swiper横向,当y轴滑动5像素手势失效;swiper纵向只响应swiper的滑动事件
664
+ if (dir === 'x') {
665
+ gesturePan.activeOffsetX([-2, 2]).failOffsetY([-5, 5]);
666
+ }
667
+ else {
668
+ gesturePan.activeOffsetY([-2, 2]).failOffsetX([-5, 5]);
669
+ }
670
+ // 手势协同2.0
671
+ if (simultaneousHandlers && simultaneousHandlers.length) {
672
+ gesturePan.simultaneousWithExternalGesture(...simultaneousHandlers);
673
+ }
674
+ if (waitForHandlers && waitForHandlers.length) {
675
+ gesturePan.requireExternalGestureToFail(...waitForHandlers);
676
+ }
629
677
  return {
630
678
  gestureHandler: gesturePan
631
679
  };
632
- }, []);
680
+ }, [gestureSwitch.current]);
633
681
  const animatedStyles = useAnimatedStyle(() => {
634
682
  if (dir === 'x') {
635
683
  return { transform: [{ translateX: offset.value }], opacity: step.value > 0 ? 1 : 0 };
@@ -638,34 +686,32 @@ const SwiperWrapper = forwardRef((props, ref) => {
638
686
  return { transform: [{ translateY: offset.value }], opacity: step.value > 0 ? 1 : 0 };
639
687
  }
640
688
  });
641
- function renderSwiper() {
642
- const arrPages = renderItems();
643
- return (<View style={[normalStyle, layoutStyle, styles.swiper]} {...layoutProps} {...innerProps}>
644
- <Animated.View style={[{
645
- flexDirection: dir === 'x' ? 'row' : 'column',
646
- width: '100%',
647
- height: '100%'
648
- }, animatedStyles]}>
649
- {wrapChildren({
650
- children: arrPages
651
- }, {
652
- hasVarDec,
653
- varContext: varContextRef.current,
654
- textStyle,
655
- textProps
656
- })}
657
- </Animated.View>
658
- {showsPagination && renderPagination()}
659
- </View>);
660
- }
661
- if (children.length === 1) {
662
- return renderSwiper();
689
+ let finalComponent;
690
+ const arrPages = renderItems();
691
+ const mergeProps = Object.assign({
692
+ style: [normalStyle, layoutStyle, styles.swiper]
693
+ }, layoutProps, innerProps);
694
+ const animateComponent = createElement(Animated.View, {
695
+ style: [{ flexDirection: dir === 'x' ? 'row' : 'column', width: '100%', height: '100%' }, animatedStyles]
696
+ }, wrapChildren({
697
+ children: arrPages
698
+ }, {
699
+ hasVarDec,
700
+ varContext: varContextRef.current,
701
+ textStyle,
702
+ textProps
703
+ }));
704
+ const renderChildrens = showPagination ? [animateComponent, renderPagination()] : animateComponent;
705
+ finalComponent = createElement(View, mergeProps, renderChildrens);
706
+ if (!disableGesture) {
707
+ finalComponent = createElement(GestureDetector, {
708
+ gesture: gestureHandler
709
+ }, finalComponent);
663
710
  }
664
- else {
665
- return (<GestureDetector gesture={gestureHandler}>
666
- {renderSwiper()}
667
- </GestureDetector>);
711
+ if (hasPositionFixed) {
712
+ finalComponent = createElement(Portal, null, finalComponent);
668
713
  }
714
+ return finalComponent;
669
715
  });
670
716
  SwiperWrapper.displayName = 'MpxSwiperWrapper';
671
717
  export default SwiperWrapper;
@@ -10,6 +10,7 @@ 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';
13
14
  import { FormContext } from './context';
14
15
  import { useTransformStyle, useLayout, extendObject } from './utils';
15
16
  const _Switch = forwardRef((props, ref) => {
@@ -21,7 +22,7 @@ const _Switch = forwardRef((props, ref) => {
21
22
  if (formContext) {
22
23
  formValuesMap = formContext.formValuesMap;
23
24
  }
24
- const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, {
25
+ const { normalStyle, hasSelfPercent, setWidth, setHeight, hasPositionFixed } = useTransformStyle(style, {
25
26
  enableVar,
26
27
  externalVarContext,
27
28
  parentFontSize,
@@ -83,13 +84,17 @@ const _Switch = forwardRef((props, ref) => {
83
84
  checked: isChecked
84
85
  }));
85
86
  }
86
- return createElement(Switch, extendObject({}, innerProps, {
87
+ let finalComponent = createElement(Switch, extendObject({}, innerProps, {
87
88
  style: normalStyle,
88
89
  value: isChecked,
89
90
  trackColor: { false: '#FFF', true: color },
90
91
  thumbColor: isChecked ? '#FFF' : '#f4f3f4',
91
92
  ios_backgroundColor: '#FFF'
92
93
  }));
94
+ if (hasPositionFixed) {
95
+ finalComponent = createElement(Portal, null, finalComponent);
96
+ }
97
+ return finalComponent;
93
98
  });
94
99
  _Switch.displayName = 'MpxSwitch';
95
100
  export default _Switch;
@@ -5,12 +5,13 @@
5
5
  */
6
6
  import { Text } from 'react-native';
7
7
  import { useRef, forwardRef, createElement } from 'react';
8
+ import Portal from './mpx-portal';
8
9
  import useInnerProps from './getInnerListeners';
9
10
  import useNodesRef from './useNodesRef'; // 引入辅助函数
10
11
  import { useTransformStyle, wrapChildren, extendObject } from './utils';
11
12
  const _Text = forwardRef((props, ref) => {
12
13
  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;
13
- const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, {
14
+ const { normalStyle, hasVarDec, varContextRef, hasPositionFixed } = useTransformStyle(style, {
14
15
  enableVar,
15
16
  externalVarContext,
16
17
  parentFontSize,
@@ -29,10 +30,14 @@ const _Text = forwardRef((props, ref) => {
29
30
  }), [
30
31
  'user-select'
31
32
  ]);
32
- return createElement(Text, innerProps, wrapChildren(props, {
33
+ let finalComponent = createElement(Text, innerProps, wrapChildren(props, {
33
34
  hasVarDec,
34
35
  varContext: varContextRef.current
35
36
  }));
37
+ if (hasPositionFixed) {
38
+ finalComponent = createElement(Portal, null, finalComponent);
39
+ }
40
+ return finalComponent;
36
41
  });
37
42
  _Text.displayName = 'MpxText';
38
43
  export default _Text;
@@ -68,6 +68,7 @@ import { StyleSheet, View } from 'react-native';
68
68
  import { splitProps, useTransformStyle, useLayout, extendObject } from './utils';
69
69
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
70
70
  import useNodesRef from './useNodesRef';
71
+ import Portal from './mpx-portal';
71
72
  const styles = StyleSheet.create({
72
73
  container: {
73
74
  width: 300,
@@ -85,7 +86,7 @@ const MpxVideo = forwardRef((videoProps, ref) => {
85
86
  const videoInfoRef = useRef({});
86
87
  const propsRef = useRef({});
87
88
  propsRef.current = props;
88
- const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(extendObject({}, styles.container, style), {
89
+ const { normalStyle, hasSelfPercent, setWidth, setHeight, hasPositionFixed } = useTransformStyle(extendObject({}, styles.container, style), {
89
90
  enableVar,
90
91
  externalVarContext,
91
92
  parentFontSize,
@@ -243,6 +244,10 @@ const MpxVideo = forwardRef((videoProps, ref) => {
243
244
  'bindcontrolstoggle',
244
245
  'bindseekcomplete'
245
246
  ], { layoutRef });
246
- return createElement(View, { style: extendObject({}, normalStyle, layoutStyle), ref: viewRef }, createElement(Video, innerProps));
247
+ let videoComponent = createElement(View, { style: extendObject({}, normalStyle, layoutStyle), ref: viewRef }, createElement(Video, innerProps));
248
+ if (hasPositionFixed) {
249
+ videoComponent = createElement(Portal, null, videoComponent);
250
+ }
251
+ return videoComponent;
247
252
  });
248
253
  export default MpxVideo;
@@ -523,10 +523,8 @@ function useWrapImage(imageStyle, innerStyle, enableFastImage) {
523
523
  setShow(true);
524
524
  }
525
525
  };
526
- return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
527
- {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
528
- {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage))}
529
- </View>;
526
+ const backgroundProps = extendObject({ key: 'backgroundImage' }, needLayout ? { onLayout } : {}, { style: extendObject({}, inheritStyle(innerStyle), StyleSheet.absoluteFillObject, { overflow: 'hidden' }) });
527
+ return createElement(View, backgroundProps, show && type === 'linear' && createElement(LinearGradient, extendObject({ useAngle: true }, imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current))), show && type === 'image' && renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage));
530
528
  }
531
529
  function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }) {
532
530
  const children = wrapChildren(props, {
@@ -1,4 +1,4 @@
1
- import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement } from 'react';
1
+ import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement, createElement } from 'react';
2
2
  import { Image } from 'react-native';
3
3
  import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils';
4
4
  import { VarContext, ScrollViewContext, RouteContext } from './context';
@@ -517,7 +517,7 @@ export function getCurrentPage(pageId) {
517
517
  }
518
518
  export function renderImage(imageProps, enableFastImage = false) {
519
519
  const Component = enableFastImage ? FastImage : Image;
520
- return <Component {...imageProps}/>;
520
+ return createElement(Component, imageProps);
521
521
  }
522
522
  export function pickStyle(styleObj = {}, pickedKeys, callback) {
523
523
  return pickedKeys.reduce((acc, key) => {
@@ -51,6 +51,7 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners'
51
51
  import useNodesRef, { HandlerRef } from './useNodesRef'
52
52
  import { RouteContext, FormContext } from './context'
53
53
  import type { ExtendedViewStyle } from './types/common'
54
+ import Portal from './mpx-portal'
54
55
 
55
56
  export type Type = 'default' | 'primary' | 'warn'
56
57
 
@@ -290,6 +291,7 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
290
291
  )
291
292
 
292
293
  const {
294
+ hasPositionFixed,
293
295
  hasSelfPercent,
294
296
  normalStyle,
295
297
  hasVarDec,
@@ -412,9 +414,15 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
412
414
  )
413
415
  )
414
416
 
415
- return enableHover
417
+ const finalComponent = enableHover
416
418
  ? createElement(GestureDetector, { gesture: gesture as PanGesture }, baseButton)
417
419
  : baseButton
420
+
421
+ if (hasPositionFixed) {
422
+ return createElement(Portal, null, finalComponent)
423
+ }
424
+
425
+ return finalComponent
418
426
  })
419
427
 
420
428
  Button.displayName = 'MpxButton'
@@ -1,4 +1,5 @@
1
1
  import { WebviewMessage, WEBVIEW_TARGET, registerWebviewProperties, CanvasInstance } from './utils'
2
+ import { extendObject } from '../utils'
2
3
 
3
4
  const PROPERTIES = {
4
5
  crossOrigin: undefined,
@@ -60,10 +61,9 @@ export class Image {
60
61
  this[key] = value
61
62
  }
62
63
  }
63
- callbackFn({
64
- ...message.payload,
65
- target: this
66
- })
64
+ callbackFn(
65
+ extendObject({}, message.payload, { target: this })
66
+ )
67
67
  }
68
68
  })
69
69
  }
@@ -9,7 +9,7 @@
9
9
  * ✔ bindlongtap
10
10
  * ✔ binderror
11
11
  */
12
- import React, { createElement, useRef, useState, useCallback, useEffect, forwardRef, JSX, TouchEvent, MutableRefObject } from 'react'
12
+ import { createElement, useRef, useState, useCallback, useEffect, forwardRef, JSX, TouchEvent, MutableRefObject } from 'react'
13
13
  import { View, Platform, StyleSheet, NativeSyntheticEvent } from 'react-native'
14
14
  import { WebView } from 'react-native-webview'
15
15
  import useNodesRef, { HandlerRef } from '../useNodesRef'
@@ -31,6 +31,7 @@ import './CanvasGradient'
31
31
  import { createImage as canvasCreateImage } from './Image'
32
32
  import { createImageData as canvasCreateImageData } from './ImageData'
33
33
  import { useConstructorsRegistry } from './constructorsRegistry'
34
+ import Portal from '../mpx-portal'
34
35
 
35
36
  const stylesheet = StyleSheet.create({
36
37
  container: { overflow: 'hidden', flex: 0 },
@@ -71,6 +72,7 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
71
72
  const {
72
73
  normalStyle,
73
74
  hasSelfPercent,
75
+ hasPositionFixed,
74
76
  setWidth,
75
77
  setHeight
76
78
  } = useTransformStyle(extendObject({}, style, stylesheet.container), {
@@ -166,10 +168,7 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
166
168
 
167
169
  const postMessage = useCallback(async (message: WebviewMessage) => {
168
170
  if (!canvasRef.current?.bus) return
169
- const { type, payload } = await canvasRef.current.bus.post({
170
- id: ID(),
171
- ...message
172
- })
171
+ const { type, payload } = await canvasRef.current.bus.post(extendObject({ id: ID() }, message))
173
172
 
174
173
  switch (type) {
175
174
  case 'error': {
@@ -204,7 +203,7 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
204
203
  }
205
204
 
206
205
  const onMessage = useCallback((e: { nativeEvent: { data: string } }) => {
207
- let data = JSON.parse(e.nativeEvent.data)
206
+ const data = JSON.parse(e.nativeEvent.data)
208
207
  switch (data.type) {
209
208
  case 'error': {
210
209
  const { binderror } = props
@@ -220,27 +219,27 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
220
219
  break
221
220
  }
222
221
  default: {
222
+ const newData: { payload?: unknown } = {}
223
+ // createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
224
+ const constructor = constructors[data.meta.constructor]
223
225
  if (data.payload) {
224
- // createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
225
- const constructor = constructors[data.meta.constructor]
226
226
  if (constructor) {
227
227
  const { args, payload } = data
228
228
  // RN 端同步生成一个 CanvasGradient 的实例
229
229
  const object = constructor.constructLocally(canvasRef.current, ...args)
230
- Object.assign(object, payload, {
230
+ extendObject(object, payload, {
231
231
  [WEBVIEW_TARGET]: data.meta.target
232
232
  })
233
- data = {
234
- ...data,
233
+ extendObject(newData, data, {
235
234
  payload: object
236
- }
235
+ })
237
236
  }
238
237
  for (const listener of canvasRef.current.listeners) {
239
- listener(data.payload)
238
+ listener(constructor ? newData.payload : data.payload)
240
239
  }
241
240
  }
242
241
  if (canvasRef.current.bus) {
243
- canvasRef.current.bus.handle(data)
242
+ canvasRef.current.bus.handle(constructor && data.payload ? newData : data)
244
243
  }
245
244
  }
246
245
  }
@@ -259,9 +258,11 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
259
258
  context: context2D
260
259
  })
261
260
 
262
- if (__mpx_mode__ !== 'ios') {
261
+ let canvasComponent
262
+
263
+ if (__mpx_mode__ === 'android') {
263
264
  const isAndroid9 = Platform.Version as number >= 28
264
- return createElement(View, innerProps, createElement(
265
+ canvasComponent = createElement(View, innerProps, createElement(
265
266
  WebView,
266
267
  {
267
268
  ref: (element) => {
@@ -288,7 +289,7 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
288
289
  )
289
290
  }
290
291
 
291
- return createElement(View, innerProps, createElement(WebView, {
292
+ canvasComponent = createElement(View, innerProps, createElement(WebView, {
292
293
  ref: (element) => {
293
294
  if (canvasRef.current) {
294
295
  canvasRef.current.webview = element
@@ -301,6 +302,12 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
301
302
  onLoad: onLoad,
302
303
  scrollEnabled: false
303
304
  }))
305
+
306
+ if (hasPositionFixed) {
307
+ canvasComponent = createElement(Portal, null, canvasComponent)
308
+ }
309
+
310
+ return canvasComponent
304
311
  })
305
312
 
306
313
  _Canvas.displayName = 'mpxCanvas'
@@ -21,6 +21,7 @@ import { FormContext, FormFieldValue, CheckboxGroupContext, GroupValue } from '.
21
21
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
22
22
  import useNodesRef, { HandlerRef } from './useNodesRef'
23
23
  import { useLayout, useTransformStyle, wrapChildren, extendObject } from './utils'
24
+ import Portal from './mpx-portal'
24
25
 
25
26
  export interface CheckboxGroupProps {
26
27
  name: string
@@ -68,6 +69,7 @@ const CheckboxGroup = forwardRef<
68
69
  const styleObj = extendObject({}, defaultStyle, style)
69
70
 
70
71
  const {
72
+ hasPositionFixed,
71
73
  hasSelfPercent,
72
74
  normalStyle,
73
75
  hasVarDec,
@@ -159,7 +161,7 @@ const CheckboxGroup = forwardRef<
159
161
  }
160
162
  }, [])
161
163
 
162
- return createElement(
164
+ const finalComponent = createElement(
163
165
  View,
164
166
  innerProps,
165
167
  createElement(
@@ -174,6 +176,12 @@ const CheckboxGroup = forwardRef<
174
176
  )
175
177
  )
176
178
  )
179
+
180
+ if (hasPositionFixed) {
181
+ return createElement(Portal, null, finalComponent)
182
+ }
183
+
184
+ return finalComponent
177
185
  })
178
186
 
179
187
  CheckboxGroup.displayName = 'MpxCheckboxGroup'
@@ -28,6 +28,7 @@ import useNodesRef, { HandlerRef } from './useNodesRef'
28
28
  import Icon from './mpx-icon'
29
29
  import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils'
30
30
  import { CheckboxGroupContext, LabelContext } from './context'
31
+ import Portal from './mpx-portal'
31
32
 
32
33
  interface Selection {
33
34
  value?: string
@@ -128,6 +129,7 @@ const Checkbox = forwardRef<HandlerRef<View, CheckboxProps>, CheckboxProps>(
128
129
  }
129
130
 
130
131
  const {
132
+ hasPositionFixed,
131
133
  hasSelfPercent,
132
134
  normalStyle,
133
135
  hasVarDec,
@@ -206,7 +208,7 @@ const Checkbox = forwardRef<HandlerRef<View, CheckboxProps>, CheckboxProps>(
206
208
  }
207
209
  }, [checked])
208
210
 
209
- return createElement(View, innerProps,
211
+ const finalComponent = createElement(View, innerProps,
210
212
  createElement(
211
213
  View,
212
214
  { style: defaultStyle },
@@ -227,6 +229,12 @@ const Checkbox = forwardRef<HandlerRef<View, CheckboxProps>, CheckboxProps>(
227
229
  }
228
230
  )
229
231
  )
232
+
233
+ if (hasPositionFixed) {
234
+ return createElement(Portal, null, finalComponent)
235
+ }
236
+
237
+ return finalComponent
230
238
  }
231
239
  )
232
240
 
@@ -17,6 +17,7 @@ import Cancel from './icons/cancel.png'
17
17
  import Download from './icons/download.png'
18
18
  import Search from './icons/search.png'
19
19
  import Clear from './icons/clear.png'
20
+ import Portal from '../mpx-portal'
20
21
 
21
22
  export type IconType =
22
23
  | 'success'
@@ -75,6 +76,7 @@ const Icon = forwardRef<HandlerRef<Text, IconProps>, IconProps>(
75
76
  const styleObj = extendObject({}, defaultStyle, style)
76
77
 
77
78
  const {
79
+ hasPositionFixed,
78
80
  hasSelfPercent,
79
81
  normalStyle,
80
82
  setWidth,
@@ -103,7 +105,13 @@ const Icon = forwardRef<HandlerRef<Text, IconProps>, IconProps>(
103
105
  }
104
106
  )
105
107
 
106
- return createElement(Image, innerProps)
108
+ const finalComponent = createElement(Image, innerProps)
109
+
110
+ if (hasPositionFixed) {
111
+ return createElement(Portal, null, finalComponent)
112
+ }
113
+
114
+ return finalComponent
107
115
  }
108
116
  )
109
117