@mpxjs/webpack-plugin 2.10.7-beta.8 → 2.10.7-beta.9
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/platform/style/wx/index.js +7 -0
- package/lib/platform/template/wx/component-config/movable-view.js +1 -10
- package/lib/runtime/components/react/context.ts +12 -2
- package/lib/runtime/components/react/dist/context.js +1 -1
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +63 -9
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +306 -61
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +15 -10
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +3 -1
- package/lib/runtime/components/react/mpx-movable-area.tsx +98 -11
- package/lib/runtime/components/react/mpx-movable-view.tsx +356 -62
- package/lib/runtime/components/react/mpx-scroll-view.tsx +16 -9
- package/lib/runtime/components/react/mpx-sticky-header.tsx +3 -1
- package/lib/runtime/components/web/mpx-scroll-view.vue +4 -7
- package/lib/runtime/components/web/mpx-sticky-header.vue +39 -31
- package/lib/template-compiler/bind-this.js +2 -1
- package/lib/template-compiler/compiler.js +1 -1
- package/package.json +1 -1
|
@@ -44,7 +44,7 @@ import Portal from './mpx-portal';
|
|
|
44
44
|
const AnimatedScrollView = RNAnimated.createAnimatedComponent(ScrollView);
|
|
45
45
|
const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
46
46
|
const { textProps, innerProps: props = {} } = splitProps(scrollViewProps);
|
|
47
|
-
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, 'enable-sticky': enableSticky, 'scroll-event-throttle': scrollEventThrottle = 0, __selectRef } = props;
|
|
47
|
+
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, 'enable-sticky': enableSticky, 'scroll-event-throttle': scrollEventThrottle = 0, 'scroll-into-view-offset': scrollIntoViewOffset = 0, __selectRef } = props;
|
|
48
48
|
const scrollOffset = useRef(new RNAnimated.Value(0)).current;
|
|
49
49
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
50
50
|
const waitForHandlers = flatGesture(waitFor);
|
|
@@ -69,7 +69,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
69
69
|
const hasCallScrollToLower = useRef(false);
|
|
70
70
|
const initialTimeout = useRef(null);
|
|
71
71
|
const intersectionObservers = useContext(IntersectionObserverContext);
|
|
72
|
-
const firstScrollIntoViewChange = useRef(
|
|
72
|
+
const firstScrollIntoViewChange = useRef(true);
|
|
73
73
|
const refreshColor = {
|
|
74
74
|
black: ['#000'],
|
|
75
75
|
white: ['#fff']
|
|
@@ -89,7 +89,8 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
89
89
|
pagingEnabled,
|
|
90
90
|
fastDeceleration: false,
|
|
91
91
|
decelerationDisabled: false,
|
|
92
|
-
scrollTo
|
|
92
|
+
scrollTo,
|
|
93
|
+
scrollIntoView: handleScrollIntoView
|
|
93
94
|
},
|
|
94
95
|
gestureRef: scrollViewRef
|
|
95
96
|
});
|
|
@@ -119,14 +120,16 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
119
120
|
}, [scrollTop, scrollLeft]);
|
|
120
121
|
useEffect(() => {
|
|
121
122
|
if (scrollIntoView && __selectRef) {
|
|
122
|
-
if (
|
|
123
|
-
setTimeout(
|
|
123
|
+
if (firstScrollIntoViewChange.current) {
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
handleScrollIntoView(scrollIntoView, { offset: scrollIntoViewOffset, animated: scrollWithAnimation });
|
|
126
|
+
});
|
|
124
127
|
}
|
|
125
128
|
else {
|
|
126
|
-
handleScrollIntoView();
|
|
129
|
+
handleScrollIntoView(scrollIntoView, { offset: scrollIntoViewOffset, animated: scrollWithAnimation });
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
|
-
firstScrollIntoViewChange.current =
|
|
132
|
+
firstScrollIntoViewChange.current = false;
|
|
130
133
|
}, [scrollIntoView]);
|
|
131
134
|
useEffect(() => {
|
|
132
135
|
if (refresherEnabled) {
|
|
@@ -146,13 +149,15 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
146
149
|
function scrollTo({ top = 0, left = 0, animated = false }) {
|
|
147
150
|
scrollToOffset(left, top, animated);
|
|
148
151
|
}
|
|
149
|
-
function handleScrollIntoView() {
|
|
150
|
-
const refs = __selectRef(`#${
|
|
152
|
+
function handleScrollIntoView(selector = '', { offset = 0, animated = true } = {}) {
|
|
153
|
+
const refs = __selectRef(`#${selector}`, 'node');
|
|
151
154
|
if (!refs)
|
|
152
155
|
return;
|
|
153
156
|
const { nodeRef } = refs.getNodeInstance();
|
|
154
157
|
nodeRef.current?.measureLayout(scrollViewRef.current, (left, top) => {
|
|
155
|
-
|
|
158
|
+
const adjustedLeft = scrollX ? left + offset : left;
|
|
159
|
+
const adjustedTop = scrollY ? top + offset : top;
|
|
160
|
+
scrollToOffset(adjustedLeft, adjustedTop, animated);
|
|
156
161
|
});
|
|
157
162
|
}
|
|
158
163
|
function selectLength(size) {
|
|
@@ -108,7 +108,9 @@ const _StickyHeader = forwardRef((stickyHeaderProps = {}, ref) => {
|
|
|
108
108
|
const styles = StyleSheet.create({
|
|
109
109
|
content: {
|
|
110
110
|
width: '100%',
|
|
111
|
-
zIndex: 10
|
|
111
|
+
zIndex: 10,
|
|
112
|
+
// harmony 需要手动设置 relative, zIndex 才生效
|
|
113
|
+
position: 'relative'
|
|
112
114
|
}
|
|
113
115
|
});
|
|
114
116
|
_StickyHeader.displayName = 'MpxStickyHeader';
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ✔ scale-area
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { View } from 'react-native'
|
|
6
|
-
import { JSX, forwardRef, ReactNode, useRef, useMemo, createElement } from 'react'
|
|
6
|
+
import { JSX, forwardRef, ReactNode, useRef, useMemo, useCallback, createElement } from 'react'
|
|
7
|
+
import { GestureDetector, Gesture } from 'react-native-gesture-handler'
|
|
8
|
+
import { useSharedValue } from 'react-native-reanimated'
|
|
7
9
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
8
10
|
import useInnerProps from './getInnerListeners'
|
|
9
|
-
import { MovableAreaContext } from './context'
|
|
11
|
+
import { MovableAreaContext, MovableAreaContextValue } from './context'
|
|
10
12
|
import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils'
|
|
11
13
|
import Portal from './mpx-portal'
|
|
12
14
|
|
|
@@ -15,6 +17,7 @@ interface MovableAreaProps {
|
|
|
15
17
|
children: ReactNode
|
|
16
18
|
width?: number
|
|
17
19
|
height?: number
|
|
20
|
+
'scale-area'?: boolean
|
|
18
21
|
'enable-offset'?: boolean
|
|
19
22
|
'enable-var'?: boolean
|
|
20
23
|
'external-var-context'?: Record<string, any>
|
|
@@ -23,8 +26,21 @@ interface MovableAreaProps {
|
|
|
23
26
|
'parent-height'?: number
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
interface MovableViewCallbacks {
|
|
30
|
+
onScale: (scaleInfo: {scale: number}) => void
|
|
31
|
+
onScaleEnd?: () => void
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaProps>((props: MovableAreaProps, ref): JSX.Element => {
|
|
27
|
-
const {
|
|
35
|
+
const {
|
|
36
|
+
style = {},
|
|
37
|
+
'scale-area': scaleArea = false,
|
|
38
|
+
'enable-var': enableVar,
|
|
39
|
+
'external-var-context': externalVarContext,
|
|
40
|
+
'parent-font-size': parentFontSize,
|
|
41
|
+
'parent-width': parentWidth,
|
|
42
|
+
'parent-height': parentHeight
|
|
43
|
+
} = props
|
|
28
44
|
|
|
29
45
|
const {
|
|
30
46
|
hasSelfPercent,
|
|
@@ -36,17 +52,67 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
|
|
|
36
52
|
setHeight
|
|
37
53
|
} = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
|
|
38
54
|
|
|
39
|
-
const
|
|
40
|
-
|
|
55
|
+
const movableAreaRef = useRef(null)
|
|
56
|
+
const movableViewsValue = useSharedValue<Record<string, MovableViewCallbacks>>({})
|
|
57
|
+
useNodesRef(props, ref, movableAreaRef, {
|
|
41
58
|
style: normalStyle
|
|
42
59
|
})
|
|
43
60
|
|
|
44
|
-
|
|
61
|
+
// 注册/注销 MovableView 的回调
|
|
62
|
+
const registerMovableView = useCallback((id: string, callbacks: { onScale?: (scaleInfo: { scale: number }) => void; onScaleEnd?: () => void }) => {
|
|
63
|
+
movableViewsValue.value = extendObject(movableViewsValue.value, { [id]: callbacks })
|
|
64
|
+
}, [])
|
|
65
|
+
|
|
66
|
+
const unregisterMovableView = useCallback((id: string) => {
|
|
67
|
+
delete movableViewsValue.value[id]
|
|
68
|
+
}, [])
|
|
69
|
+
|
|
70
|
+
// 处理区域缩放手势
|
|
71
|
+
const handleAreaScale = useCallback((scaleInfo: { scale: number }) => {
|
|
72
|
+
'worklet'
|
|
73
|
+
if (scaleArea) {
|
|
74
|
+
// 将缩放信息广播给所有注册的 MovableView
|
|
75
|
+
Object.values(movableViewsValue.value).forEach((callbacks) => {
|
|
76
|
+
callbacks.onScale && callbacks.onScale(scaleInfo)
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
}, [scaleArea])
|
|
80
|
+
|
|
81
|
+
// 处理区域缩放结束
|
|
82
|
+
const handleAreaScaleEnd = useCallback(() => {
|
|
83
|
+
'worklet'
|
|
84
|
+
if (scaleArea) {
|
|
85
|
+
// 通知所有注册的 MovableView 缩放结束
|
|
86
|
+
Object.values(movableViewsValue.value).forEach((callbacks) => {
|
|
87
|
+
callbacks.onScaleEnd && callbacks.onScaleEnd()
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}, [scaleArea])
|
|
91
|
+
|
|
92
|
+
const contextValue: MovableAreaContextValue = useMemo(() => ({
|
|
45
93
|
height: normalStyle.height || 10,
|
|
46
|
-
width: normalStyle.width || 10
|
|
47
|
-
|
|
94
|
+
width: normalStyle.width || 10,
|
|
95
|
+
scaleArea,
|
|
96
|
+
registerMovableView,
|
|
97
|
+
unregisterMovableView
|
|
98
|
+
}), [normalStyle.width, normalStyle.height, scaleArea])
|
|
48
99
|
|
|
49
|
-
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef:
|
|
100
|
+
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableAreaRef })
|
|
101
|
+
|
|
102
|
+
// 创建缩放手势
|
|
103
|
+
const scaleGesture = useMemo(() => {
|
|
104
|
+
if (!scaleArea) return null
|
|
105
|
+
|
|
106
|
+
return Gesture.Pinch()
|
|
107
|
+
.onUpdate((e) => {
|
|
108
|
+
'worklet'
|
|
109
|
+
handleAreaScale(e)
|
|
110
|
+
})
|
|
111
|
+
.onEnd(() => {
|
|
112
|
+
'worklet'
|
|
113
|
+
handleAreaScaleEnd()
|
|
114
|
+
})
|
|
115
|
+
}, [scaleArea])
|
|
50
116
|
|
|
51
117
|
const innerProps = useInnerProps(
|
|
52
118
|
extendObject(
|
|
@@ -55,7 +121,7 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
|
|
|
55
121
|
layoutProps,
|
|
56
122
|
{
|
|
57
123
|
style: extendObject({ height: contextValue.height, width: contextValue.width }, normalStyle, layoutStyle),
|
|
58
|
-
ref:
|
|
124
|
+
ref: movableAreaRef
|
|
59
125
|
}
|
|
60
126
|
),
|
|
61
127
|
[],
|
|
@@ -73,9 +139,30 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
|
|
|
73
139
|
}
|
|
74
140
|
)
|
|
75
141
|
))
|
|
142
|
+
|
|
143
|
+
// 如果启用了 scale-area,包装一个 GestureDetector
|
|
144
|
+
if (scaleArea && scaleGesture) {
|
|
145
|
+
movableComponent = createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(
|
|
146
|
+
GestureDetector,
|
|
147
|
+
{ gesture: scaleGesture },
|
|
148
|
+
createElement(
|
|
149
|
+
View,
|
|
150
|
+
innerProps,
|
|
151
|
+
wrapChildren(
|
|
152
|
+
props,
|
|
153
|
+
{
|
|
154
|
+
hasVarDec,
|
|
155
|
+
varContext: varContextRef.current
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
))
|
|
160
|
+
}
|
|
161
|
+
|
|
76
162
|
if (hasPositionFixed) {
|
|
77
163
|
movableComponent = createElement(Portal, null, movableComponent)
|
|
78
164
|
}
|
|
165
|
+
|
|
79
166
|
return movableComponent
|
|
80
167
|
})
|
|
81
168
|
|