@mpxjs/webpack-plugin 2.10.3 → 2.10.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.
- package/lib/config.js +2 -1
- package/lib/index.js +1 -1
- package/lib/platform/json/wx/index.js +6 -3
- package/lib/platform/style/wx/index.js +23 -12
- package/lib/platform/template/wx/component-config/button.js +19 -2
- package/lib/platform/template/wx/component-config/canvas.js +4 -0
- package/lib/platform/template/wx/component-config/checkbox-group.js +4 -0
- package/lib/platform/template/wx/component-config/checkbox.js +4 -0
- package/lib/platform/template/wx/component-config/cover-image.js +7 -1
- package/lib/platform/template/wx/component-config/cover-view.js +4 -0
- package/lib/platform/template/wx/component-config/fix-component-name.js +3 -2
- package/lib/platform/template/wx/component-config/form.js +7 -1
- package/lib/platform/template/wx/component-config/icon.js +4 -0
- package/lib/platform/template/wx/component-config/image.js +7 -1
- package/lib/platform/template/wx/component-config/input.js +18 -3
- package/lib/platform/template/wx/component-config/label.js +4 -0
- package/lib/platform/template/wx/component-config/movable-area.js +7 -1
- package/lib/platform/template/wx/component-config/movable-view.js +12 -3
- package/lib/platform/template/wx/component-config/navigator.js +4 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +4 -0
- package/lib/platform/template/wx/component-config/picker-view.js +7 -1
- package/lib/platform/template/wx/component-config/picker.js +7 -1
- package/lib/platform/template/wx/component-config/radio-group.js +4 -0
- package/lib/platform/template/wx/component-config/radio.js +4 -0
- package/lib/platform/template/wx/component-config/rich-text.js +4 -0
- package/lib/platform/template/wx/component-config/root-portal.js +4 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +10 -2
- package/lib/platform/template/wx/component-config/swiper-item.js +7 -1
- package/lib/platform/template/wx/component-config/swiper.js +12 -3
- package/lib/platform/template/wx/component-config/switch.js +4 -0
- package/lib/platform/template/wx/component-config/text.js +24 -3
- package/lib/platform/template/wx/component-config/textarea.js +17 -2
- package/lib/platform/template/wx/component-config/unsupported.js +7 -0
- package/lib/platform/template/wx/component-config/video.js +10 -2
- package/lib/platform/template/wx/component-config/view.js +11 -1
- package/lib/platform/template/wx/component-config/web-view.js +4 -0
- package/lib/platform/template/wx/index.js +42 -75
- package/lib/react/processScript.js +1 -18
- package/lib/runtime/components/react/dist/event.config.js +1 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +18 -7
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +3 -6
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
- package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +178 -96
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
- package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +3 -3
- package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +64 -16
- package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +8 -5
- package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
- package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
- package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +192 -25
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +8 -7
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
- package/lib/runtime/components/react/dist/mpx-video.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +7 -4
- package/lib/runtime/components/react/dist/utils.jsx +2 -1
- package/lib/runtime/components/react/event.config.ts +2 -0
- package/lib/runtime/components/react/getInnerListeners.ts +28 -25
- package/lib/runtime/components/react/mpx-canvas/index.tsx +2 -2
- package/lib/runtime/components/react/mpx-inline-text.tsx +18 -0
- package/lib/runtime/components/react/mpx-input.tsx +2 -6
- package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker/date.tsx +226 -69
- package/lib/runtime/components/react/mpx-picker/dateData.ts +22 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +239 -118
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +96 -139
- package/lib/runtime/components/react/mpx-picker/region.tsx +217 -89
- package/lib/runtime/components/react/mpx-picker/selector.tsx +75 -80
- package/lib/runtime/components/react/mpx-picker/time.tsx +119 -236
- package/lib/runtime/components/react/mpx-picker/type.ts +85 -71
- package/lib/runtime/components/react/{mpx-picker-view.tsx → mpx-picker-view/index.tsx} +7 -7
- package/lib/runtime/components/react/{mpx-picker-view-column.tsx → mpx-picker-view-column/index.tsx} +70 -19
- package/lib/runtime/components/react/{mpx-picker-view-column-item.tsx → mpx-picker-view-column/pickerViewColumnItem.tsx} +8 -5
- package/lib/runtime/components/react/{pickerFaces.ts → mpx-picker-view-column/pickerViewFaces.ts} +7 -0
- package/lib/runtime/components/react/mpx-popup/index.tsx +86 -0
- package/lib/runtime/components/react/mpx-popup/popupBase.tsx +130 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +249 -43
- package/lib/runtime/components/react/mpx-simple-text.tsx +10 -8
- package/lib/runtime/components/react/mpx-simple-view.tsx +11 -16
- package/lib/runtime/components/react/mpx-video.tsx +2 -2
- package/lib/runtime/components/react/mpx-web-view.tsx +7 -4
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +5 -1
- package/lib/runtime/components/react/types/global.d.ts +1 -1
- package/lib/runtime/components/react/utils.tsx +3 -2
- package/lib/runtime/components/web/mini-video-controls.min.js +1 -1
- package/lib/runtime/components/web/mpx-input.vue +1 -1
- package/lib/runtime/stringify.wxs +2 -2
- package/lib/template-compiler/compiler.js +8 -8
- package/lib/utils/env.js +1 -1
- package/package.json +4 -5
- /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
- /package/lib/runtime/components/react/{pickerVIewContext.ts → mpx-picker-view/pickerVIewContext.ts} +0 -0
- /package/lib/runtime/components/react/{pickerViewIndicator.tsx → mpx-picker-view-column/pickerViewIndicator.tsx} +0 -0
- /package/lib/runtime/components/react/{pickerViewMask.tsx → mpx-picker-view-column/pickerViewMask.tsx} +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
|
|
3
|
+
import { getWindowInfo } from '@mpxjs/api-proxy';
|
|
4
|
+
import { useUpdateEffect } from '../utils';
|
|
5
|
+
const windowInfo = getWindowInfo();
|
|
6
|
+
const bottom = windowInfo.screenHeight - windowInfo.safeArea.bottom;
|
|
7
|
+
const styles = StyleSheet.create({
|
|
8
|
+
mask: {
|
|
9
|
+
left: 0,
|
|
10
|
+
top: 0,
|
|
11
|
+
bottom: 0,
|
|
12
|
+
right: 0,
|
|
13
|
+
backgroundColor: 'rgba(0,0,0,0.6)',
|
|
14
|
+
position: 'absolute',
|
|
15
|
+
zIndex: 1000
|
|
16
|
+
},
|
|
17
|
+
content: {
|
|
18
|
+
backgroundColor: '#ffffff',
|
|
19
|
+
borderTopLeftRadius: 10,
|
|
20
|
+
borderTopRightRadius: 10,
|
|
21
|
+
position: 'absolute',
|
|
22
|
+
bottom: 0,
|
|
23
|
+
left: 0,
|
|
24
|
+
right: 0,
|
|
25
|
+
paddingBottom: bottom
|
|
26
|
+
},
|
|
27
|
+
buttonStyle: {
|
|
28
|
+
fontSize: 18,
|
|
29
|
+
paddingTop: 10,
|
|
30
|
+
paddingBottom: 10
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const MASK_ON = 1;
|
|
34
|
+
const MASK_OFF = 0;
|
|
35
|
+
const MOVEOUT_HEIGHT = 330;
|
|
36
|
+
/**
|
|
37
|
+
* 类似微信 picker 弹窗的动画效果都可以复用此类容器
|
|
38
|
+
* 其他特定类型的弹窗容器组件可以在此基础上封装,或者扩展实现
|
|
39
|
+
*/
|
|
40
|
+
const PopupBase = (props = {}) => {
|
|
41
|
+
const { children, hide = () => null, contentHeight = MOVEOUT_HEIGHT, visible = false } = props;
|
|
42
|
+
const fade = useSharedValue(MASK_OFF);
|
|
43
|
+
const slide = useSharedValue(contentHeight);
|
|
44
|
+
const animatedStylesMask = useAnimatedStyle(() => ({
|
|
45
|
+
opacity: fade.value
|
|
46
|
+
}));
|
|
47
|
+
const animatedStylesContent = useAnimatedStyle(() => ({
|
|
48
|
+
transform: [{ translateY: slide.value }]
|
|
49
|
+
}));
|
|
50
|
+
const showAimation = () => {
|
|
51
|
+
fade.value = withTiming(MASK_ON, {
|
|
52
|
+
easing: Easing.inOut(Easing.poly(3)),
|
|
53
|
+
duration: 300
|
|
54
|
+
});
|
|
55
|
+
slide.value = withTiming(0, {
|
|
56
|
+
easing: Easing.out(Easing.poly(3)),
|
|
57
|
+
duration: 300
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
const hideAnimation = () => {
|
|
61
|
+
fade.value = withTiming(MASK_OFF, {
|
|
62
|
+
easing: Easing.inOut(Easing.poly(3)),
|
|
63
|
+
duration: 300
|
|
64
|
+
});
|
|
65
|
+
slide.value = withTiming(contentHeight, {
|
|
66
|
+
easing: Easing.inOut(Easing.poly(3)),
|
|
67
|
+
duration: 300
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
useUpdateEffect(() => {
|
|
71
|
+
if (visible) {
|
|
72
|
+
showAimation();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
hideAnimation();
|
|
76
|
+
}
|
|
77
|
+
}, [visible]);
|
|
78
|
+
const preventMaskClick = (e) => {
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
};
|
|
81
|
+
return (<Animated.View onTouchEnd={hide} style={[
|
|
82
|
+
styles.mask,
|
|
83
|
+
animatedStylesMask,
|
|
84
|
+
{ pointerEvents: visible ? 'auto' : 'none' }
|
|
85
|
+
]}>
|
|
86
|
+
<Animated.View style={[styles.content, animatedStylesContent]} onTouchEnd={preventMaskClick}>
|
|
87
|
+
{children}
|
|
88
|
+
</Animated.View>
|
|
89
|
+
</Animated.View>);
|
|
90
|
+
};
|
|
91
|
+
PopupBase.displayName = 'MpxPopupBase';
|
|
92
|
+
export default PopupBase;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* ✔ enable-back-to-top
|
|
11
11
|
* ✘ enable-passive
|
|
12
12
|
* ✔ refresher-enabled
|
|
13
|
-
*
|
|
13
|
+
* ✔ refresher-threshold(仅自定义下拉节点样式支持)
|
|
14
14
|
* ✔ refresher-default-style(仅 android 支持)
|
|
15
15
|
* ✔ refresher-background(仅 android 支持)
|
|
16
16
|
* ✔ refresher-triggered
|
|
@@ -31,22 +31,29 @@
|
|
|
31
31
|
* ✔ bindscrolltolower
|
|
32
32
|
* ✔ bindscroll
|
|
33
33
|
*/
|
|
34
|
-
import { ScrollView, RefreshControl } from 'react-native-gesture-handler';
|
|
35
|
-
import { useRef, useState, useEffect, forwardRef, useContext,
|
|
36
|
-
import { useAnimatedRef } from 'react-native-reanimated';
|
|
34
|
+
import { ScrollView, RefreshControl, Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
35
|
+
import { isValidElement, Children, useRef, useState, useEffect, forwardRef, useContext, useMemo, createElement } from 'react';
|
|
36
|
+
import Animated, { useAnimatedRef, useSharedValue, withTiming, useAnimatedStyle, runOnJS } from 'react-native-reanimated';
|
|
37
37
|
import { warn } from '@mpxjs/utils';
|
|
38
38
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
39
39
|
import useNodesRef from './useNodesRef';
|
|
40
|
-
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture } from './utils';
|
|
40
|
+
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, HIDDEN_STYLE } from './utils';
|
|
41
41
|
import { IntersectionObserverContext, ScrollViewContext } from './context';
|
|
42
42
|
const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
43
43
|
const { textProps, innerProps: props = {} } = splitProps(scrollViewProps);
|
|
44
|
-
const { enhanced = false, bounces = true, style = {}, binddragstart, binddragging, binddragend, bindtouchstart, bindtouchmove, bindtouchend, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'enable-trigger-intersection-observer': enableTriggerIntersectionObserver = false, 'paging-enabled': pagingEnabled = false, 'upper-threshold': upperThreshold = 50, 'lower-threshold': lowerThreshold = 50, 'scroll-with-animation': scrollWithAnimation = false, 'refresher-enabled': refresherEnabled, 'refresher-default-style': refresherDefaultStyle, 'refresher-background': refresherBackground, 'show-scrollbar': showScrollbar = true, 'scroll-into-view': scrollIntoView = '', 'scroll-top': scrollTop = 0, 'scroll-left': scrollLeft = 0, 'refresher-triggered': refresherTriggered, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'simultaneous-handlers': originSimultaneousHandlers, 'wait-for': waitFor, 'scroll-event-throttle': scrollEventThrottle = 0, __selectRef } = props;
|
|
44
|
+
const { enhanced = false, bounces = true, style = {}, binddragstart, binddragging, binddragend, bindtouchstart, bindtouchmove, bindtouchend, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'enable-trigger-intersection-observer': enableTriggerIntersectionObserver = false, 'paging-enabled': pagingEnabled = false, 'upper-threshold': upperThreshold = 50, 'lower-threshold': lowerThreshold = 50, 'scroll-with-animation': scrollWithAnimation = false, 'refresher-enabled': refresherEnabled, 'refresher-default-style': refresherDefaultStyle, 'refresher-background': refresherBackground, 'refresher-threshold': refresherThreshold = 45, 'show-scrollbar': showScrollbar = true, 'scroll-into-view': scrollIntoView = '', 'scroll-top': scrollTop = 0, 'scroll-left': scrollLeft = 0, 'refresher-triggered': refresherTriggered, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'simultaneous-handlers': originSimultaneousHandlers, 'wait-for': waitFor, 'scroll-event-throttle': scrollEventThrottle = 0, __selectRef } = props;
|
|
45
45
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
46
46
|
const waitForHandlers = flatGesture(waitFor);
|
|
47
|
-
const [refreshing, setRefreshing] = useState(true);
|
|
48
47
|
const snapScrollTop = useRef(0);
|
|
49
48
|
const snapScrollLeft = useRef(0);
|
|
49
|
+
const [refreshing, setRefreshing] = useState(false);
|
|
50
|
+
const [enableScroll, setEnableScroll] = useState(true);
|
|
51
|
+
const enableScrollValue = useSharedValue(true);
|
|
52
|
+
const [scrollBounces, setScrollBounces] = useState(false);
|
|
53
|
+
const bouncesValue = useSharedValue(!!false);
|
|
54
|
+
const translateY = useSharedValue(0);
|
|
55
|
+
const isAtTop = useSharedValue(true);
|
|
56
|
+
const refresherHeight = useSharedValue(0);
|
|
50
57
|
const scrollOptions = useRef({
|
|
51
58
|
contentLength: 0,
|
|
52
59
|
offset: 0,
|
|
@@ -59,6 +66,12 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
59
66
|
const initialTimeout = useRef(null);
|
|
60
67
|
const intersectionObservers = useContext(IntersectionObserverContext);
|
|
61
68
|
const firstScrollIntoViewChange = useRef(false);
|
|
69
|
+
const refreshColor = {
|
|
70
|
+
black: ['#000'],
|
|
71
|
+
white: ['#fff']
|
|
72
|
+
};
|
|
73
|
+
const { refresherContent, otherContent } = getRefresherContent(props.children);
|
|
74
|
+
const hasRefresher = refresherContent && refresherEnabled;
|
|
62
75
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
63
76
|
const { textStyle, innerStyle = {} } = splitStyle(normalStyle);
|
|
64
77
|
const scrollViewRef = useAnimatedRef();
|
|
@@ -82,6 +95,9 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
82
95
|
};
|
|
83
96
|
}, []);
|
|
84
97
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout });
|
|
98
|
+
const hasRefresherLayoutRef = useRef(false);
|
|
99
|
+
// layout 完成前先隐藏,避免安卓闪烁问题
|
|
100
|
+
const refresherLayoutStyle = useMemo(() => { return !hasRefresherLayoutRef.current ? HIDDEN_STYLE : {}; }, [hasRefresherLayoutRef.current]);
|
|
85
101
|
const lastOffset = useRef(0);
|
|
86
102
|
if (scrollX && scrollY) {
|
|
87
103
|
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');
|
|
@@ -96,11 +112,6 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
96
112
|
};
|
|
97
113
|
}
|
|
98
114
|
}, [scrollTop, scrollLeft]);
|
|
99
|
-
useEffect(() => {
|
|
100
|
-
if (refreshing !== refresherTriggered) {
|
|
101
|
-
setRefreshing(!!refresherTriggered);
|
|
102
|
-
}
|
|
103
|
-
}, [refresherTriggered]);
|
|
104
115
|
useEffect(() => {
|
|
105
116
|
if (scrollIntoView && __selectRef) {
|
|
106
117
|
if (!firstScrollIntoViewChange.current) {
|
|
@@ -112,6 +123,21 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
112
123
|
}
|
|
113
124
|
firstScrollIntoViewChange.current = true;
|
|
114
125
|
}, [scrollIntoView]);
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (refresherEnabled) {
|
|
128
|
+
setRefreshing(!!refresherTriggered);
|
|
129
|
+
if (!refresherContent)
|
|
130
|
+
return;
|
|
131
|
+
if (refresherTriggered) {
|
|
132
|
+
translateY.value = withTiming(refresherHeight.value);
|
|
133
|
+
resetScrollState(false);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
translateY.value = withTiming(0);
|
|
137
|
+
resetScrollState(true);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}, [refresherTriggered]);
|
|
115
141
|
function scrollTo({ top = 0, left = 0, animated = false }) {
|
|
116
142
|
scrollToOffset(left, top, animated);
|
|
117
143
|
}
|
|
@@ -192,6 +218,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
192
218
|
const { bindscroll } = props;
|
|
193
219
|
const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset;
|
|
194
220
|
const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize;
|
|
221
|
+
isAtTop.value = scrollTop <= 0;
|
|
195
222
|
bindscroll &&
|
|
196
223
|
bindscroll(getCustomEvent('scroll', e, {
|
|
197
224
|
detail: {
|
|
@@ -215,6 +242,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
215
242
|
const { bindscrollend } = props;
|
|
216
243
|
const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset;
|
|
217
244
|
const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize;
|
|
245
|
+
isAtTop.value = scrollTop <= 0;
|
|
218
246
|
bindscrollend &&
|
|
219
247
|
bindscrollend(getCustomEvent('scrollend', e, {
|
|
220
248
|
detail: {
|
|
@@ -247,11 +275,6 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
247
275
|
snapScrollTop.current = y;
|
|
248
276
|
}
|
|
249
277
|
}
|
|
250
|
-
function onRefresh() {
|
|
251
|
-
const { bindrefresherrefresh } = props;
|
|
252
|
-
bindrefresherrefresh &&
|
|
253
|
-
bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef }, props));
|
|
254
|
-
}
|
|
255
278
|
function onScrollTouchStart(e) {
|
|
256
279
|
const { bindtouchstart } = props;
|
|
257
280
|
bindtouchstart && bindtouchstart(e);
|
|
@@ -302,6 +325,144 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
302
325
|
hasCallScrollToUpper.current = false;
|
|
303
326
|
onScrollDrag(e);
|
|
304
327
|
}
|
|
328
|
+
// 处理刷新
|
|
329
|
+
function onRefresh() {
|
|
330
|
+
if (hasRefresher && refresherTriggered === undefined) {
|
|
331
|
+
// 处理使用了自定义刷新组件,又没设置 refresherTriggered 的情况
|
|
332
|
+
setRefreshing(true);
|
|
333
|
+
setTimeout(() => {
|
|
334
|
+
setRefreshing(false);
|
|
335
|
+
translateY.value = withTiming(0);
|
|
336
|
+
if (!enableScrollValue.value) {
|
|
337
|
+
resetScrollState(true);
|
|
338
|
+
}
|
|
339
|
+
}, 500);
|
|
340
|
+
}
|
|
341
|
+
const { bindrefresherrefresh } = props;
|
|
342
|
+
bindrefresherrefresh &&
|
|
343
|
+
bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef }, props));
|
|
344
|
+
}
|
|
345
|
+
function getRefresherContent(children) {
|
|
346
|
+
let refresherContent = null;
|
|
347
|
+
const otherContent = [];
|
|
348
|
+
Children.forEach(children, (child) => {
|
|
349
|
+
if (isValidElement(child) && child.props.slot === 'refresher') {
|
|
350
|
+
refresherContent = child;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
otherContent.push(child);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
return {
|
|
357
|
+
refresherContent,
|
|
358
|
+
otherContent
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
// 刷新控件的动画样式
|
|
362
|
+
const refresherAnimatedStyle = useAnimatedStyle(() => {
|
|
363
|
+
return {
|
|
364
|
+
position: 'absolute',
|
|
365
|
+
left: 0,
|
|
366
|
+
right: 0,
|
|
367
|
+
top: -refresherHeight.value,
|
|
368
|
+
transform: [{ translateY: Math.min(translateY.value, refresherHeight.value) }],
|
|
369
|
+
backgroundColor: refresherBackground || 'transparent'
|
|
370
|
+
};
|
|
371
|
+
});
|
|
372
|
+
// 内容区域的动画样式 - 只有内容区域需要下移
|
|
373
|
+
const contentAnimatedStyle = useAnimatedStyle(() => {
|
|
374
|
+
return {
|
|
375
|
+
transform: [{
|
|
376
|
+
translateY: translateY.value > refresherHeight.value
|
|
377
|
+
? refresherHeight.value
|
|
378
|
+
: translateY.value
|
|
379
|
+
}]
|
|
380
|
+
};
|
|
381
|
+
});
|
|
382
|
+
function onRefresherLayout(e) {
|
|
383
|
+
const { height } = e.nativeEvent.layout;
|
|
384
|
+
refresherHeight.value = height;
|
|
385
|
+
hasRefresherLayoutRef.current = true;
|
|
386
|
+
}
|
|
387
|
+
function updateScrollState(newValue) {
|
|
388
|
+
'worklet';
|
|
389
|
+
if (enableScrollValue.value !== newValue) {
|
|
390
|
+
enableScrollValue.value = newValue;
|
|
391
|
+
runOnJS(setEnableScroll)(newValue);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const resetScrollState = (value) => {
|
|
395
|
+
enableScrollValue.value = value;
|
|
396
|
+
setEnableScroll(value);
|
|
397
|
+
};
|
|
398
|
+
function updateBouncesState(newValue) {
|
|
399
|
+
'worklet';
|
|
400
|
+
if (bouncesValue.value !== newValue) {
|
|
401
|
+
bouncesValue.value = newValue;
|
|
402
|
+
runOnJS(setScrollBounces)(newValue);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// 处理下拉刷新的手势
|
|
406
|
+
const panGesture = Gesture.Pan()
|
|
407
|
+
.onUpdate((event) => {
|
|
408
|
+
'worklet';
|
|
409
|
+
if (enhanced && !!bounces) {
|
|
410
|
+
if (event.translationY > 0 && bouncesValue.value) {
|
|
411
|
+
updateBouncesState(false);
|
|
412
|
+
}
|
|
413
|
+
else if ((event.translationY < 0) && !bouncesValue.value) {
|
|
414
|
+
updateBouncesState(true);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (translateY.value <= 0 && event.translationY < 0) {
|
|
418
|
+
// 滑动到顶再向上开启滚动
|
|
419
|
+
updateScrollState(true);
|
|
420
|
+
}
|
|
421
|
+
else if (event.translationY > 0 && isAtTop.value) {
|
|
422
|
+
// 滚动到顶再向下禁止滚动
|
|
423
|
+
updateScrollState(false);
|
|
424
|
+
}
|
|
425
|
+
// 禁止滚动后切换为滑动
|
|
426
|
+
if (!enableScrollValue.value && isAtTop.value) {
|
|
427
|
+
if (refreshing) {
|
|
428
|
+
// 从完全展开状态(refresherHeight.value)开始计算偏移
|
|
429
|
+
translateY.value = Math.max(0, Math.min(refresherHeight.value, refresherHeight.value + event.translationY));
|
|
430
|
+
}
|
|
431
|
+
else if (event.translationY > 0) {
|
|
432
|
+
// 非刷新状态下的下拉逻辑保持不变
|
|
433
|
+
translateY.value = Math.min(event.translationY * 0.6, refresherHeight.value);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
})
|
|
437
|
+
.onEnd((event) => {
|
|
438
|
+
'worklet';
|
|
439
|
+
if (enableScrollValue.value)
|
|
440
|
+
return;
|
|
441
|
+
if (refreshing) {
|
|
442
|
+
// 刷新状态下,根据滑动距离决定是否隐藏
|
|
443
|
+
// 如果向下滑动没超过 refresherThreshold,就完全隐藏,如果向上滑动完全隐藏
|
|
444
|
+
if ((event.translationY > 0 && translateY.value < refresherThreshold) || event.translationY < 0) {
|
|
445
|
+
translateY.value = withTiming(0);
|
|
446
|
+
updateScrollState(true);
|
|
447
|
+
runOnJS(setRefreshing)(false);
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
translateY.value = withTiming(refresherHeight.value);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
else if (event.translationY >= refresherHeight.value) {
|
|
454
|
+
// 触发刷新
|
|
455
|
+
translateY.value = withTiming(refresherHeight.value);
|
|
456
|
+
runOnJS(onRefresh)();
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
// 回弹
|
|
460
|
+
translateY.value = withTiming(0);
|
|
461
|
+
updateScrollState(true);
|
|
462
|
+
runOnJS(setRefreshing)(false);
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
.simultaneousWithExternalGesture(scrollViewRef);
|
|
305
466
|
const scrollAdditionalProps = extendObject({
|
|
306
467
|
style: extendObject({}, innerStyle, layoutStyle),
|
|
307
468
|
pinchGestureEnabled: false,
|
|
@@ -312,7 +473,8 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
312
473
|
scrollsToTop: enableBackToTop,
|
|
313
474
|
showsHorizontalScrollIndicator: scrollX && showScrollbar,
|
|
314
475
|
showsVerticalScrollIndicator: scrollY && showScrollbar,
|
|
315
|
-
scrollEnabled: scrollX || scrollY,
|
|
476
|
+
scrollEnabled: !enableScroll ? false : !!(scrollX || scrollY),
|
|
477
|
+
bounces: false,
|
|
316
478
|
ref: scrollViewRef,
|
|
317
479
|
onScroll: onScroll,
|
|
318
480
|
onContentSizeChange: onContentSizeChange,
|
|
@@ -325,7 +487,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
325
487
|
}, (simultaneousHandlers ? { simultaneousHandlers } : {}), (waitForHandlers ? { waitFor: waitForHandlers } : {}), layoutProps);
|
|
326
488
|
if (enhanced) {
|
|
327
489
|
Object.assign(scrollAdditionalProps, {
|
|
328
|
-
bounces,
|
|
490
|
+
bounces: hasRefresher ? scrollBounces : !!bounces,
|
|
329
491
|
pagingEnabled
|
|
330
492
|
});
|
|
331
493
|
}
|
|
@@ -356,17 +518,21 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
356
518
|
'bindscrolltolower',
|
|
357
519
|
'bindrefresherrefresh'
|
|
358
520
|
], { layoutRef });
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
521
|
+
const withRefresherScrollView = createElement(GestureDetector, { gesture: panGesture }, createElement(ScrollView, innerProps, createElement(Animated.View, { style: [refresherAnimatedStyle, refresherLayoutStyle], onLayout: onRefresherLayout }, refresherContent), createElement(Animated.View, { style: contentAnimatedStyle }, createElement(ScrollViewContext.Provider, { value: contextValue }, wrapChildren(extendObject({}, props, { children: otherContent }), {
|
|
522
|
+
hasVarDec,
|
|
523
|
+
varContext: varContextRef.current,
|
|
524
|
+
textStyle,
|
|
525
|
+
textProps
|
|
526
|
+
})))));
|
|
527
|
+
const commonScrollView = createElement(ScrollView, extendObject(innerProps, {
|
|
364
528
|
refreshControl: refresherEnabled
|
|
365
529
|
? createElement(RefreshControl, extendObject({
|
|
366
530
|
progressBackgroundColor: refresherBackground,
|
|
367
531
|
refreshing: refreshing,
|
|
368
532
|
onRefresh: onRefresh
|
|
369
|
-
},
|
|
533
|
+
}, refresherDefaultStyle && refresherDefaultStyle !== 'none'
|
|
534
|
+
? { colors: refreshColor[refresherDefaultStyle] }
|
|
535
|
+
: {}))
|
|
370
536
|
: undefined
|
|
371
537
|
}), createElement(ScrollViewContext.Provider, { value: contextValue }, wrapChildren(props, {
|
|
372
538
|
hasVarDec,
|
|
@@ -374,6 +540,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
374
540
|
textStyle,
|
|
375
541
|
textProps
|
|
376
542
|
})));
|
|
543
|
+
return hasRefresher ? withRefresherScrollView : commonScrollView;
|
|
377
544
|
});
|
|
378
545
|
_ScrollView.displayName = 'MpxScrollView';
|
|
379
546
|
export default _ScrollView;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Text } from 'react-native';
|
|
2
2
|
import { createElement } from 'react';
|
|
3
|
-
import
|
|
4
|
-
const
|
|
5
|
-
const { allowFontScaling = false } = props;
|
|
6
|
-
|
|
3
|
+
import useInnerProps from './getInnerListeners';
|
|
4
|
+
const SimpleText = (props) => {
|
|
5
|
+
const { allowFontScaling = false, children } = props;
|
|
6
|
+
const innerProps = useInnerProps(props, {
|
|
7
7
|
allowFontScaling
|
|
8
|
-
})
|
|
8
|
+
}, []);
|
|
9
|
+
return createElement(Text, innerProps, children);
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
export default
|
|
11
|
+
SimpleText.displayName = 'MpxSimpleText';
|
|
12
|
+
export default SimpleText;
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { View } from 'react-native';
|
|
2
|
-
import { createElement
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
const
|
|
6
|
-
const nodeRef = useRef(null);
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
import { splitProps, splitStyle, wrapChildren } from './utils';
|
|
4
|
+
import useInnerProps from './getInnerListeners';
|
|
5
|
+
const SimpleView = (simpleViewProps) => {
|
|
7
6
|
const { textProps, innerProps: props = {} } = splitProps(simpleViewProps);
|
|
8
7
|
const { textStyle, innerStyle = {} } = splitStyle(props.style || {});
|
|
9
|
-
|
|
10
|
-
style: innerStyle
|
|
11
|
-
});
|
|
12
|
-
return createElement(View,
|
|
13
|
-
style: innerStyle,
|
|
14
|
-
ref: nodeRef
|
|
15
|
-
}), wrapChildren(props, {
|
|
8
|
+
const innerProps = useInnerProps(props, {
|
|
9
|
+
style: innerStyle
|
|
10
|
+
}, []);
|
|
11
|
+
return createElement(View, innerProps, wrapChildren(props, {
|
|
16
12
|
hasVarDec: false,
|
|
17
13
|
textStyle: textStyle,
|
|
18
14
|
textProps
|
|
19
15
|
}));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default
|
|
16
|
+
};
|
|
17
|
+
SimpleView.displayName = 'MpxSimpleView';
|
|
18
|
+
export default SimpleView;
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
*/
|
|
65
65
|
import { useRef, forwardRef, createElement } from 'react';
|
|
66
66
|
import Video, { DRMType } from 'react-native-video';
|
|
67
|
-
import { StyleSheet, View
|
|
67
|
+
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';
|
|
@@ -132,7 +132,7 @@ const MpxVideo = forwardRef((videoProps, ref) => {
|
|
|
132
132
|
// 手动拖拽进度条场景,android 可以触发,ios 不可以
|
|
133
133
|
bindseekcomplete(getCustomEvent('seekcomplete', {}, {
|
|
134
134
|
detail: {
|
|
135
|
-
position:
|
|
135
|
+
position: __mpx_mode__ !== 'ios' ? seekTime * 1000 : seekTime
|
|
136
136
|
},
|
|
137
137
|
layoutRef
|
|
138
138
|
}, propsRef.current));
|
|
@@ -202,7 +202,7 @@ const MpxVideo = forwardRef((videoProps, ref) => {
|
|
|
202
202
|
if (isDrm) {
|
|
203
203
|
source.drm = {
|
|
204
204
|
type: DRMType.FAIRPLAY,
|
|
205
|
-
certificateUrl:
|
|
205
|
+
certificateUrl: __mpx_mode__ !== 'ios' ? provisionUrl : certificateUrl,
|
|
206
206
|
licenseServer: licenseUrl
|
|
207
207
|
};
|
|
208
208
|
}
|
|
@@ -75,7 +75,10 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
75
75
|
};
|
|
76
76
|
const navigation = useNavigation();
|
|
77
77
|
useEffect(() => {
|
|
78
|
-
|
|
78
|
+
let beforeRemoveSubscription;
|
|
79
|
+
if (__mpx_mode__ !== 'ios') {
|
|
80
|
+
beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle);
|
|
81
|
+
}
|
|
79
82
|
return () => {
|
|
80
83
|
if (isFunction(beforeRemoveSubscription)) {
|
|
81
84
|
beforeRemoveSubscription();
|
|
@@ -89,7 +92,7 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
89
92
|
return null;
|
|
90
93
|
}
|
|
91
94
|
const _reload = function () {
|
|
92
|
-
if (__mpx_mode__
|
|
95
|
+
if (__mpx_mode__ !== 'ios') {
|
|
93
96
|
fristLoaded.current = false; // 安卓需要重新设置
|
|
94
97
|
}
|
|
95
98
|
setPageLoadErr(false);
|
|
@@ -133,7 +136,7 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
133
136
|
}
|
|
134
137
|
};
|
|
135
138
|
const _onLoadProgress = function (event) {
|
|
136
|
-
if (__mpx_mode__
|
|
139
|
+
if (__mpx_mode__ !== 'ios') {
|
|
137
140
|
canGoBack.current = event.nativeEvent.canGoBack;
|
|
138
141
|
}
|
|
139
142
|
};
|
|
@@ -251,7 +254,7 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
251
254
|
}
|
|
252
255
|
};
|
|
253
256
|
const onLoadEnd = function (res) {
|
|
254
|
-
if (__mpx_mode__
|
|
257
|
+
if (__mpx_mode__ !== 'ios') {
|
|
255
258
|
res.persist();
|
|
256
259
|
setTimeout(() => {
|
|
257
260
|
onLoadEndHandle(res);
|
|
@@ -19,6 +19,7 @@ export const HIDDEN_STYLE = {
|
|
|
19
19
|
};
|
|
20
20
|
export const isIOS = __mpx_mode__ === 'ios';
|
|
21
21
|
export const isAndroid = __mpx_mode__ === 'android';
|
|
22
|
+
export const isHarmony = __mpx_mode__ === 'harmony';
|
|
22
23
|
const varDecRegExp = /^--/;
|
|
23
24
|
const varUseRegExp = /var\(/;
|
|
24
25
|
const unoVarDecRegExp = /^--un-/;
|
|
@@ -80,7 +81,7 @@ export function isText(ele) {
|
|
|
80
81
|
if (isValidElement(ele)) {
|
|
81
82
|
const displayName = ele.type?.displayName;
|
|
82
83
|
const isCustomText = ele.type?.isCustomText;
|
|
83
|
-
return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'Text' || !!isCustomText;
|
|
84
|
+
return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'MpxInlineText' || displayName === 'Text' || !!isCustomText;
|
|
84
85
|
}
|
|
85
86
|
return false;
|
|
86
87
|
}
|
|
@@ -4,6 +4,8 @@ interface EventConfig {
|
|
|
4
4
|
|
|
5
5
|
export const TAP_EVENTS = ['bindtap', 'catchtap', 'capture-bindtap', 'capture-catchtap']
|
|
6
6
|
|
|
7
|
+
export const LONGPRESS_EVENTS = ['bindlongpress', 'catchlongpress', 'capture-bindlongpress', 'capture-catchlongpress']
|
|
8
|
+
|
|
7
9
|
const eventConfigMap: { [key: string]: { bitFlag: string; events: string[] } } = {
|
|
8
10
|
bindtap: { bitFlag: '0', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd'] },
|
|
9
11
|
bindlongpress: { bitFlag: '1', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'] },
|