@mpxjs/webpack-plugin 2.10.4-beta.9 → 2.10.5-beta.1
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.
- package/lib/index.js +10 -1
- package/lib/json-compiler/helper.js +1 -4
- package/lib/platform/style/wx/index.js +22 -21
- package/lib/platform/template/wx/index.js +21 -1
- package/lib/react/processScript.js +9 -1
- package/lib/react/script-helper.js +5 -1
- package/lib/resolver/PackageEntryPlugin.js +3 -1
- package/lib/runtime/components/react/dist/mpx-button.jsx +9 -4
- package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +20 -17
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-icon/index.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-image.jsx +9 -2
- package/lib/runtime/components/react/dist/mpx-input.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-label.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +76 -42
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +11 -13
- package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +8 -7
- package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +28 -10
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +9 -2
- package/lib/runtime/components/react/dist/mpx-radio.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -4
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +6 -3
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +11 -9
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +82 -36
- package/lib/runtime/components/react/dist/mpx-switch.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-text.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-video.jsx +7 -2
- package/lib/runtime/components/react/dist/mpx-view.jsx +13 -8
- package/lib/runtime/components/react/dist/useAnimationHooks.js +27 -4
- package/lib/runtime/components/react/dist/utils.jsx +87 -97
- package/lib/runtime/components/react/mpx-button.tsx +12 -3
- package/lib/runtime/components/react/mpx-canvas/Image.ts +4 -4
- package/lib/runtime/components/react/mpx-canvas/index.tsx +24 -17
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +9 -1
- package/lib/runtime/components/react/mpx-checkbox.tsx +9 -1
- package/lib/runtime/components/react/mpx-icon/index.tsx +9 -1
- package/lib/runtime/components/react/mpx-image.tsx +38 -19
- package/lib/runtime/components/react/mpx-input.tsx +10 -1
- package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-label.tsx +9 -1
- package/lib/runtime/components/react/mpx-movable-area.tsx +7 -1
- package/lib/runtime/components/react/mpx-movable-view.tsx +75 -42
- package/lib/runtime/components/react/mpx-picker/index.tsx +18 -16
- package/lib/runtime/components/react/mpx-picker-view/index.tsx +22 -8
- package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +36 -32
- package/lib/runtime/components/react/mpx-radio-group.tsx +20 -9
- package/lib/runtime/components/react/mpx-radio.tsx +9 -1
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +10 -2
- package/lib/runtime/components/react/mpx-scroll-view.tsx +14 -3
- package/lib/runtime/components/react/mpx-sticky-header.tsx +7 -4
- package/lib/runtime/components/react/mpx-swiper-item.tsx +11 -19
- package/lib/runtime/components/react/mpx-swiper.tsx +95 -38
- package/lib/runtime/components/react/mpx-switch.tsx +10 -2
- package/lib/runtime/components/react/mpx-text.tsx +10 -2
- package/lib/runtime/components/react/mpx-video.tsx +7 -2
- package/lib/runtime/components/react/mpx-view.tsx +23 -9
- package/lib/runtime/components/react/useAnimationHooks.ts +30 -9
- package/lib/runtime/components/react/utils.tsx +95 -102
- package/lib/runtime/components/web/mpx-web-view.vue +1 -1
- package/lib/runtime/mpxGlobal.js +1 -0
- package/lib/runtime/optionProcessor.d.ts +5 -0
- package/lib/template-compiler/bind-this.js +8 -7
- package/lib/template-compiler/compiler.js +1 -1
- package/lib/wxs/pre-loader.js +1 -0
- package/package.json +2 -2
|
@@ -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':
|
|
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
|
-
|
|
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
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
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
|
-
|
|
665
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -11,7 +11,7 @@ import Animated from 'react-native-reanimated';
|
|
|
11
11
|
import useAnimationHooks from './useAnimationHooks';
|
|
12
12
|
import useNodesRef from './useNodesRef';
|
|
13
13
|
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHover } from './utils';
|
|
14
|
-
import { error } from '@mpxjs/utils';
|
|
14
|
+
import { error, isFunction } from '@mpxjs/utils';
|
|
15
15
|
import LinearGradient from 'react-native-linear-gradient';
|
|
16
16
|
import { GestureDetector } from 'react-native-gesture-handler';
|
|
17
17
|
import Portal from './mpx-portal';
|
|
@@ -523,10 +523,8 @@ function useWrapImage(imageStyle, innerStyle, enableFastImage) {
|
|
|
523
523
|
setShow(true);
|
|
524
524
|
}
|
|
525
525
|
};
|
|
526
|
-
|
|
527
|
-
|
|
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, {
|
|
@@ -543,7 +541,7 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
|
|
|
543
541
|
}
|
|
544
542
|
const _View = forwardRef((viewProps, ref) => {
|
|
545
543
|
const { textProps, innerProps: props = {} } = splitProps(viewProps);
|
|
546
|
-
let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
|
|
544
|
+
let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation, catchtransitionend, bindtransitionend } = props;
|
|
547
545
|
// 默认样式
|
|
548
546
|
const defaultStyle = style.display === 'flex'
|
|
549
547
|
? {
|
|
@@ -575,10 +573,17 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
575
573
|
});
|
|
576
574
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
577
575
|
const viewStyle = extendObject({}, innerStyle, layoutStyle);
|
|
576
|
+
const transitionend = isFunction(catchtransitionend)
|
|
577
|
+
? catchtransitionend
|
|
578
|
+
: isFunction(bindtransitionend)
|
|
579
|
+
? bindtransitionend
|
|
580
|
+
: undefined;
|
|
578
581
|
const { enableStyleAnimation, animationStyle } = useAnimationHooks({
|
|
579
|
-
|
|
582
|
+
layoutRef,
|
|
580
583
|
animation,
|
|
581
|
-
|
|
584
|
+
enableAnimation,
|
|
585
|
+
style: viewStyle,
|
|
586
|
+
transitionend
|
|
582
587
|
});
|
|
583
588
|
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
584
589
|
ref: nodeRef,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation } from 'react-native-reanimated';
|
|
3
|
-
import { error, hasOwn } from '@mpxjs/utils';
|
|
2
|
+
import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation, runOnJS } from 'react-native-reanimated';
|
|
3
|
+
import { error, hasOwn, collectDataset } from '@mpxjs/utils';
|
|
4
4
|
// 微信 timingFunction 和 RN Easing 对应关系
|
|
5
5
|
const EasingKey = {
|
|
6
6
|
linear: Easing.linear,
|
|
@@ -140,7 +140,7 @@ function getTransformObj(transforms) {
|
|
|
140
140
|
}, {});
|
|
141
141
|
}
|
|
142
142
|
export default function useAnimationHooks(props) {
|
|
143
|
-
const { style = {}, animation, enableAnimation } = props;
|
|
143
|
+
const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props;
|
|
144
144
|
const enableStyleAnimation = enableAnimation || !!animation;
|
|
145
145
|
const enableAnimationRef = useRef(enableStyleAnimation);
|
|
146
146
|
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
@@ -249,10 +249,33 @@ export default function useAnimationHooks(props) {
|
|
|
249
249
|
});
|
|
250
250
|
});
|
|
251
251
|
}
|
|
252
|
+
function withTimingCallback(finished, current, duration) {
|
|
253
|
+
if (!transitionend)
|
|
254
|
+
return;
|
|
255
|
+
const target = {
|
|
256
|
+
id: animation?.id || -1,
|
|
257
|
+
dataset: collectDataset(props),
|
|
258
|
+
offsetLeft: layoutRef?.current?.offsetLeft || 0,
|
|
259
|
+
offsetTop: layoutRef?.current?.offsetTop || 0
|
|
260
|
+
};
|
|
261
|
+
transitionend({
|
|
262
|
+
type: 'transitionend',
|
|
263
|
+
// elapsedTime 对齐wx 单位s
|
|
264
|
+
detail: { elapsedTime: duration ? duration / 1000 : 0, finished, current },
|
|
265
|
+
target,
|
|
266
|
+
currentTarget: target,
|
|
267
|
+
timeStamp: Date.now()
|
|
268
|
+
});
|
|
269
|
+
}
|
|
252
270
|
// 创建单个animation
|
|
253
271
|
function getAnimation({ key, value }, { delay, duration, easing }, callback) {
|
|
254
272
|
const animation = typeof callback === 'function'
|
|
255
|
-
? withTiming(value, { duration, easing },
|
|
273
|
+
? withTiming(value, { duration, easing }, (finished, current) => {
|
|
274
|
+
callback(finished, current);
|
|
275
|
+
if (transitionend && finished) {
|
|
276
|
+
runOnJS(withTimingCallback)(finished, current, duration);
|
|
277
|
+
}
|
|
278
|
+
})
|
|
256
279
|
: withTiming(value, { duration, easing });
|
|
257
280
|
return delay ? withDelay(delay, animation) : animation;
|
|
258
281
|
}
|
|
@@ -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';
|
|
@@ -26,6 +26,7 @@ const unoVarDecRegExp = /^--un-/;
|
|
|
26
26
|
const unoVarUseRegExp = /var\(--un-/;
|
|
27
27
|
const calcUseRegExp = /calc\(/;
|
|
28
28
|
const envUseRegExp = /env\(/;
|
|
29
|
+
const filterRegExp = /(calc|env|%)/;
|
|
29
30
|
const safeAreaInsetMap = {
|
|
30
31
|
'safe-area-inset-top': 'top',
|
|
31
32
|
'safe-area-inset-right': 'right',
|
|
@@ -181,10 +182,11 @@ function resolveVar(input, varContext) {
|
|
|
181
182
|
});
|
|
182
183
|
return global.__formatValue(replaced.source());
|
|
183
184
|
}
|
|
184
|
-
function transformVar(styleObj, varKeyPaths, varContext) {
|
|
185
|
+
function transformVar(styleObj, varKeyPaths, varContext, visitOther) {
|
|
185
186
|
varKeyPaths.forEach((varKeyPath) => {
|
|
186
187
|
setStyle(styleObj, varKeyPath, ({ target, key, value }) => {
|
|
187
188
|
target[key] = resolveVar(value, varContext);
|
|
189
|
+
visitOther({ target, key, value: target[key], keyPath: varKeyPath });
|
|
188
190
|
});
|
|
189
191
|
});
|
|
190
192
|
}
|
|
@@ -224,28 +226,33 @@ function transformCalc(styleObj, calcKeyPaths, formatter) {
|
|
|
224
226
|
});
|
|
225
227
|
});
|
|
226
228
|
}
|
|
227
|
-
const stringifyProps = ['fontWeight'];
|
|
228
229
|
function transformStringify(styleObj) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
if (isNumber(styleObj.fontWeight)) {
|
|
231
|
+
styleObj.fontWeight = '' + styleObj.fontWeight;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function transformPosition(styleObj, meta) {
|
|
235
|
+
if (styleObj.position === 'fixed') {
|
|
236
|
+
styleObj.position = 'absolute';
|
|
237
|
+
meta.hasPositionFixed = true;
|
|
238
|
+
}
|
|
234
239
|
}
|
|
235
240
|
export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
|
|
236
241
|
const varStyle = {};
|
|
237
242
|
const unoVarStyle = {};
|
|
238
243
|
const normalStyle = {};
|
|
239
|
-
const normalStyleRef = useRef({});
|
|
240
|
-
const normalStyleChangedRef = useRef(false);
|
|
241
244
|
let hasVarDec = false;
|
|
242
245
|
let hasVarUse = false;
|
|
246
|
+
let hasSelfPercent = false;
|
|
243
247
|
const varKeyPaths = [];
|
|
244
248
|
const unoVarKeyPaths = [];
|
|
249
|
+
const percentKeyPaths = [];
|
|
250
|
+
const calcKeyPaths = [];
|
|
251
|
+
const envKeyPaths = [];
|
|
245
252
|
const [width, setWidth] = useState(0);
|
|
246
253
|
const [height, setHeight] = useState(0);
|
|
247
254
|
const navigation = useNavigation();
|
|
248
|
-
function varVisitor({ key, value, keyPath }) {
|
|
255
|
+
function varVisitor({ target, key, value, keyPath }) {
|
|
249
256
|
if (keyPath.length === 1) {
|
|
250
257
|
if (unoVarDecRegExp.test(key)) {
|
|
251
258
|
unoVarStyle[key] = value;
|
|
@@ -269,6 +276,33 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
|
|
|
269
276
|
hasVarUse = true;
|
|
270
277
|
varKeyPaths.push(keyPath.slice());
|
|
271
278
|
}
|
|
279
|
+
else {
|
|
280
|
+
visitOther({ target, key, value, keyPath });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function envVisitor({ value, keyPath }) {
|
|
285
|
+
if (envUseRegExp.test(value)) {
|
|
286
|
+
envKeyPaths.push(keyPath.slice());
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function calcVisitor({ value, keyPath }) {
|
|
290
|
+
if (calcUseRegExp.test(value)) {
|
|
291
|
+
calcKeyPaths.push(keyPath.slice());
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function percentVisitor({ key, value, keyPath }) {
|
|
295
|
+
if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) {
|
|
296
|
+
hasSelfPercent = true;
|
|
297
|
+
percentKeyPaths.push(keyPath.slice());
|
|
298
|
+
}
|
|
299
|
+
else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
|
|
300
|
+
percentKeyPaths.push(keyPath.slice());
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function visitOther({ target, key, value, keyPath }) {
|
|
304
|
+
if (filterRegExp.test(value)) {
|
|
305
|
+
[envVisitor, percentVisitor, calcVisitor].forEach(visitor => visitor({ target, key, value, keyPath }));
|
|
272
306
|
}
|
|
273
307
|
}
|
|
274
308
|
// traverse var & generate normalStyle
|
|
@@ -289,96 +323,57 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
|
|
|
289
323
|
if (diffAndCloneA(varContextRef.current, newVarContext).diff) {
|
|
290
324
|
varContextRef.current = newVarContext;
|
|
291
325
|
}
|
|
292
|
-
transformVar(normalStyle, varKeyPaths, varContextRef.current);
|
|
326
|
+
transformVar(normalStyle, varKeyPaths, varContextRef.current, visitOther);
|
|
293
327
|
}
|
|
294
328
|
// apply unocss var
|
|
295
329
|
if (unoVarKeyPaths.length) {
|
|
296
|
-
transformVar(normalStyle, unoVarKeyPaths, unoVarStyle);
|
|
297
|
-
}
|
|
298
|
-
const { clone, diff } = diffAndCloneA(normalStyle, normalStyleRef.current);
|
|
299
|
-
if (diff) {
|
|
300
|
-
normalStyleRef.current = clone;
|
|
301
|
-
normalStyleChangedRef.current = !normalStyleChangedRef.current;
|
|
330
|
+
transformVar(normalStyle, unoVarKeyPaths, unoVarStyle, visitOther);
|
|
302
331
|
}
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
percentKeyPaths.push(keyPath.slice());
|
|
324
|
-
}
|
|
325
|
-
else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
|
|
326
|
-
percentKeyPaths.push(keyPath.slice());
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
function transformPosition(styleObj) {
|
|
330
|
-
if (styleObj.position === 'fixed') {
|
|
331
|
-
hasPositionFixed = true;
|
|
332
|
-
styleObj.position = 'absolute';
|
|
333
|
-
}
|
|
332
|
+
const percentConfig = {
|
|
333
|
+
width,
|
|
334
|
+
height,
|
|
335
|
+
fontSize: normalStyle.fontSize,
|
|
336
|
+
parentWidth,
|
|
337
|
+
parentHeight,
|
|
338
|
+
parentFontSize
|
|
339
|
+
};
|
|
340
|
+
const positionMeta = {
|
|
341
|
+
hasPositionFixed: false
|
|
342
|
+
};
|
|
343
|
+
// apply env
|
|
344
|
+
transformEnv(normalStyle, envKeyPaths, navigation);
|
|
345
|
+
// apply percent
|
|
346
|
+
transformPercent(normalStyle, percentKeyPaths, percentConfig);
|
|
347
|
+
// apply calc
|
|
348
|
+
transformCalc(normalStyle, calcKeyPaths, (value, key) => {
|
|
349
|
+
if (PERCENT_REGEX.test(value)) {
|
|
350
|
+
const resolved = resolvePercent(value, key, percentConfig);
|
|
351
|
+
return typeof resolved === 'number' ? resolved : 0;
|
|
334
352
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
height,
|
|
340
|
-
fontSize: normalStyle.fontSize,
|
|
341
|
-
parentWidth,
|
|
342
|
-
parentHeight,
|
|
343
|
-
parentFontSize
|
|
344
|
-
};
|
|
345
|
-
// apply env
|
|
346
|
-
transformEnv(normalStyle, envKeyPaths, navigation);
|
|
347
|
-
// apply percent
|
|
348
|
-
transformPercent(normalStyle, percentKeyPaths, percentConfig);
|
|
349
|
-
// apply calc
|
|
350
|
-
transformCalc(normalStyle, calcKeyPaths, (value, key) => {
|
|
351
|
-
if (PERCENT_REGEX.test(value)) {
|
|
352
|
-
const resolved = resolvePercent(value, key, percentConfig);
|
|
353
|
-
return typeof resolved === 'number' ? resolved : 0;
|
|
353
|
+
else {
|
|
354
|
+
const formatted = global.__formatValue(value);
|
|
355
|
+
if (typeof formatted === 'number') {
|
|
356
|
+
return formatted;
|
|
354
357
|
}
|
|
355
358
|
else {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
return formatted;
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
warn('calc() only support number, px, rpx, % temporarily.');
|
|
362
|
-
return 0;
|
|
363
|
-
}
|
|
359
|
+
warn('calc() only support number, px, rpx, % temporarily.');
|
|
360
|
+
return 0;
|
|
364
361
|
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
hasSelfPercent,
|
|
373
|
-
hasPositionFixed
|
|
374
|
-
};
|
|
375
|
-
}, [normalStyleChangedRef.current, width, height, parentWidth, parentHeight, parentFontSize]);
|
|
376
|
-
return extendObject({
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
// apply position
|
|
365
|
+
transformPosition(normalStyle, positionMeta);
|
|
366
|
+
// transform number enum stringify
|
|
367
|
+
transformStringify(normalStyle);
|
|
368
|
+
return {
|
|
377
369
|
hasVarDec,
|
|
378
370
|
varContextRef,
|
|
379
371
|
setWidth,
|
|
380
|
-
setHeight
|
|
381
|
-
|
|
372
|
+
setHeight,
|
|
373
|
+
normalStyle,
|
|
374
|
+
hasSelfPercent,
|
|
375
|
+
hasPositionFixed: positionMeta.hasPositionFixed
|
|
376
|
+
};
|
|
382
377
|
}
|
|
383
378
|
export function traverseStyle(styleObj, visitors) {
|
|
384
379
|
const keyPath = [];
|
|
@@ -387,12 +382,7 @@ export function traverseStyle(styleObj, visitors) {
|
|
|
387
382
|
target.forEach((value, index) => {
|
|
388
383
|
const key = String(index);
|
|
389
384
|
keyPath.push(key);
|
|
390
|
-
visitors.forEach(visitor => visitor({
|
|
391
|
-
target,
|
|
392
|
-
key,
|
|
393
|
-
value,
|
|
394
|
-
keyPath
|
|
395
|
-
}));
|
|
385
|
+
visitors.forEach(visitor => visitor({ target, key, value, keyPath }));
|
|
396
386
|
traverse(value);
|
|
397
387
|
keyPath.pop();
|
|
398
388
|
});
|
|
@@ -538,7 +528,7 @@ export function getCurrentPage(pageId) {
|
|
|
538
528
|
}
|
|
539
529
|
export function renderImage(imageProps, enableFastImage = false) {
|
|
540
530
|
const Component = enableFastImage ? FastImage : Image;
|
|
541
|
-
return
|
|
531
|
+
return createElement(Component, imageProps);
|
|
542
532
|
}
|
|
543
533
|
export function pickStyle(styleObj = {}, pickedKeys, callback) {
|
|
544
534
|
return pickedKeys.reduce((acc, key) => {
|