@mpxjs/webpack-plugin 2.9.65 → 2.9.67
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/dependencies/RecordGlobalComponentsDependency.js +11 -12
- package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
- package/lib/index.js +28 -8
- package/lib/json-compiler/index.js +2 -11
- package/lib/loader.js +24 -45
- package/lib/native-loader.js +49 -64
- package/lib/platform/json/wx/index.js +3 -10
- package/lib/platform/style/wx/index.js +32 -56
- package/lib/react/index.js +4 -3
- package/lib/react/processJSON.js +5 -13
- package/lib/react/processMainScript.js +7 -3
- package/lib/react/processScript.js +3 -4
- package/lib/react/processTemplate.js +6 -4
- package/lib/resolver/AddModePlugin.js +17 -4
- package/lib/runtime/components/react/context.ts +8 -0
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +30 -17
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-form.jsx +33 -24
- package/lib/runtime/components/react/dist/mpx-icon.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +44 -38
- package/lib/runtime/components/react/dist/mpx-label.jsx +10 -7
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -17
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +378 -294
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +30 -17
- package/lib/runtime/components/react/dist/mpx-radio.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +58 -30
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +77 -77
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-switch.jsx +8 -1
- package/lib/runtime/components/react/dist/mpx-text.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +31 -12
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +2 -2
- package/lib/runtime/components/react/dist/useAnimationHooks.js +303 -0
- package/lib/runtime/components/react/dist/utils.jsx +13 -3
- package/lib/runtime/components/react/getInnerListeners.ts +1 -0
- package/lib/runtime/components/react/mpx-button.tsx +1 -1
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +52 -29
- package/lib/runtime/components/react/mpx-checkbox.tsx +1 -1
- package/lib/runtime/components/react/mpx-form.tsx +42 -34
- package/lib/runtime/components/react/mpx-icon.tsx +1 -1
- package/lib/runtime/components/react/mpx-image/index.tsx +2 -3
- package/lib/runtime/components/react/mpx-input.tsx +68 -66
- package/lib/runtime/components/react/mpx-label.tsx +11 -8
- package/lib/runtime/components/react/mpx-movable-area.tsx +11 -19
- package/lib/runtime/components/react/mpx-movable-view.tsx +456 -334
- package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
- package/lib/runtime/components/react/mpx-radio-group.tsx +55 -29
- package/lib/runtime/components/react/mpx-radio.tsx +1 -1
- package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
- package/lib/runtime/components/react/mpx-scroll-view.tsx +92 -37
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -76
- package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
- package/lib/runtime/components/react/mpx-swiper-item.tsx +1 -1
- package/lib/runtime/components/react/mpx-switch.tsx +10 -2
- package/lib/runtime/components/react/mpx-text.tsx +1 -1
- package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
- package/lib/runtime/components/react/mpx-view.tsx +40 -20
- package/lib/runtime/components/react/mpx-web-view.tsx +2 -2
- package/lib/runtime/components/react/types/common.ts +8 -2
- package/lib/runtime/components/react/useAnimationHooks.ts +332 -0
- package/lib/runtime/components/react/useNodesRef.ts +1 -0
- package/lib/runtime/components/react/utils.tsx +23 -6
- package/lib/runtime/optionProcessorReact.js +0 -15
- package/lib/runtime/swanHelper.wxs +1 -1
- package/lib/style-compiler/index.js +1 -1
- package/lib/style-compiler/plugins/scope-id.js +1 -0
- package/lib/template-compiler/compiler.js +68 -33
- package/lib/template-compiler/index.js +4 -4
- package/lib/utils/pre-process-json.js +113 -0
- package/lib/web/index.js +5 -4
- package/lib/web/processJSON.js +5 -13
- package/lib/web/processTemplate.js +2 -2
- package/package.json +5 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ✔ bindchange
|
|
3
3
|
*/
|
|
4
|
-
import { useRef, forwardRef, useContext } from 'react';
|
|
4
|
+
import { useRef, forwardRef, useContext, useMemo, useEffect } from 'react';
|
|
5
5
|
import { View } from 'react-native';
|
|
6
6
|
import { warn } from '@mpxjs/utils';
|
|
7
7
|
import { FormContext, RadioGroupContext } from './context';
|
|
@@ -9,7 +9,9 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
|
9
9
|
import useNodesRef from './useNodesRef';
|
|
10
10
|
import { useLayout, useTransformStyle, wrapChildren } from './utils';
|
|
11
11
|
const radioGroup = forwardRef((props, ref) => {
|
|
12
|
-
const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight
|
|
12
|
+
const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
13
|
+
const propsRef = useRef({});
|
|
14
|
+
propsRef.current = props;
|
|
13
15
|
const formContext = useContext(FormContext);
|
|
14
16
|
let formValuesMap;
|
|
15
17
|
if (formContext) {
|
|
@@ -28,16 +30,13 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
28
30
|
const nodeRef = useRef(null);
|
|
29
31
|
useNodesRef(props, ref, nodeRef, { defaultStyle });
|
|
30
32
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
31
|
-
const
|
|
33
|
+
const getValue = () => {
|
|
32
34
|
for (const key in groupValue) {
|
|
33
35
|
if (groupValue[key].checked) {
|
|
34
36
|
return key;
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
|
-
const getValue = () => {
|
|
39
|
-
return getSelectionValue();
|
|
40
|
-
};
|
|
41
40
|
const resetValue = () => {
|
|
42
41
|
Object.keys(groupValue).forEach((key) => {
|
|
43
42
|
groupValue[key].checked = false;
|
|
@@ -52,15 +51,29 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
52
51
|
formValuesMap.set(props.name, { getValue, resetValue });
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
return () => {
|
|
56
|
+
if (formValuesMap && props.name) {
|
|
57
|
+
formValuesMap.delete(props.name);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}, []);
|
|
61
|
+
const contextValue = useMemo(() => {
|
|
62
|
+
const notifyChange = (evt) => {
|
|
63
|
+
const { bindchange } = propsRef.current;
|
|
64
|
+
bindchange &&
|
|
65
|
+
bindchange(getCustomEvent('tap', evt, {
|
|
66
|
+
layoutRef,
|
|
67
|
+
detail: {
|
|
68
|
+
value: getValue()
|
|
69
|
+
}
|
|
70
|
+
}, propsRef.current));
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
groupValue,
|
|
74
|
+
notifyChange
|
|
75
|
+
};
|
|
76
|
+
}, []);
|
|
64
77
|
const innerProps = useInnerProps(props, {
|
|
65
78
|
ref: nodeRef,
|
|
66
79
|
style: { ...normalStyle, ...layoutStyle },
|
|
@@ -69,7 +82,7 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
69
82
|
layoutRef
|
|
70
83
|
});
|
|
71
84
|
return (<View {...innerProps}>
|
|
72
|
-
<RadioGroupContext.Provider value={
|
|
85
|
+
<RadioGroupContext.Provider value={contextValue}>
|
|
73
86
|
{wrapChildren(props, {
|
|
74
87
|
hasVarDec,
|
|
75
88
|
varContext: varContextRef.current
|
|
@@ -77,5 +90,5 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
77
90
|
</RadioGroupContext.Provider>
|
|
78
91
|
</View>);
|
|
79
92
|
});
|
|
80
|
-
radioGroup.displayName = '
|
|
93
|
+
radioGroup.displayName = 'MpxRadioGroup';
|
|
81
94
|
export default radioGroup;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* ✔ lower-threshold
|
|
6
6
|
* ✔ scroll-top
|
|
7
7
|
* ✔ scroll-left
|
|
8
|
-
*
|
|
8
|
+
* ✔ scroll-into-view
|
|
9
9
|
* ✔ scroll-with-animation
|
|
10
10
|
* ✔ enable-back-to-top
|
|
11
11
|
* ✘ enable-passive
|
|
@@ -33,15 +33,18 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { ScrollView } from 'react-native-gesture-handler';
|
|
35
35
|
import { RefreshControl } from 'react-native';
|
|
36
|
-
import { useRef, useState, useEffect, forwardRef } from 'react';
|
|
36
|
+
import { useRef, useState, useEffect, forwardRef, useContext } from 'react';
|
|
37
37
|
import { useAnimatedRef } from 'react-native-reanimated';
|
|
38
38
|
import { warn } from '@mpxjs/utils';
|
|
39
39
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
40
40
|
import useNodesRef from './useNodesRef';
|
|
41
|
-
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren } from './utils';
|
|
41
|
+
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, flatGesture } from './utils';
|
|
42
|
+
import { IntersectionObserverContext } from './context';
|
|
42
43
|
const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
43
44
|
const { textProps, innerProps: props = {} } = splitProps(scrollViewProps);
|
|
44
|
-
const { enhanced = false, bounces = true, style = {}, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'paging-enabled': pagingEnabled = false, 'upper-threshold': upperThreshold = 50, 'lower-threshold': lowerThreshold = 50, 'scroll-with-animation': scrollWithAnimation, 'refresher-enabled': refresherEnabled, 'refresher-default-style': refresherDefaultStyle, 'refresher-background': refresherBackground, 'show-scrollbar': showScrollbar = true, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
45
|
+
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, '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, __selectRef } = props;
|
|
46
|
+
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
47
|
+
const waitForHandlers = flatGesture(waitFor);
|
|
45
48
|
const [refreshing, setRefreshing] = useState(true);
|
|
46
49
|
const snapScrollTop = useRef(0);
|
|
47
50
|
const snapScrollLeft = useRef(0);
|
|
@@ -56,6 +59,8 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
56
59
|
const hasCallScrollToUpper = useRef(true);
|
|
57
60
|
const hasCallScrollToLower = useRef(false);
|
|
58
61
|
const initialTimeout = useRef(null);
|
|
62
|
+
const intersectionObservers = useContext(IntersectionObserverContext);
|
|
63
|
+
const snapScrollIntoView = useRef('');
|
|
59
64
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
60
65
|
const { textStyle, innerStyle } = splitStyle(normalStyle);
|
|
61
66
|
const scrollViewRef = useAnimatedRef();
|
|
@@ -69,30 +74,42 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
69
74
|
fastDeceleration: false,
|
|
70
75
|
decelerationDisabled: false,
|
|
71
76
|
scrollTo: scrollToOffset
|
|
72
|
-
}
|
|
77
|
+
},
|
|
78
|
+
gestureRef: scrollViewRef
|
|
73
79
|
});
|
|
74
80
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout });
|
|
75
81
|
if (scrollX && scrollY) {
|
|
76
82
|
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');
|
|
77
83
|
}
|
|
78
84
|
useEffect(() => {
|
|
79
|
-
if (snapScrollTop.current !==
|
|
80
|
-
snapScrollLeft.current !== props['scroll-left']) {
|
|
81
|
-
snapScrollTop.current = props['scroll-top'] || 0;
|
|
82
|
-
snapScrollLeft.current = props['scroll-left'] || 0;
|
|
85
|
+
if (snapScrollTop.current !== scrollTop || snapScrollLeft.current !== scrollLeft) {
|
|
83
86
|
initialTimeout.current = setTimeout(() => {
|
|
84
|
-
scrollToOffset(
|
|
87
|
+
scrollToOffset(scrollLeft, scrollTop);
|
|
85
88
|
}, 0);
|
|
86
89
|
return () => {
|
|
87
90
|
initialTimeout.current && clearTimeout(initialTimeout.current);
|
|
88
91
|
};
|
|
89
92
|
}
|
|
90
|
-
}, [
|
|
93
|
+
}, [scrollTop, scrollLeft]);
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (refreshing !== refresherTriggered) {
|
|
96
|
+
setRefreshing(!!refresherTriggered);
|
|
97
|
+
}
|
|
98
|
+
}, [refresherTriggered]);
|
|
91
99
|
useEffect(() => {
|
|
92
|
-
if (
|
|
93
|
-
|
|
100
|
+
if (scrollIntoView && __selectRef && snapScrollIntoView.current !== scrollIntoView) {
|
|
101
|
+
snapScrollIntoView.current = scrollIntoView || '';
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
const refs = __selectRef(`#${scrollIntoView}`, 'node');
|
|
104
|
+
if (refs) {
|
|
105
|
+
const { nodeRef } = refs.getNodeInstance();
|
|
106
|
+
nodeRef.current?.measureLayout(scrollViewRef.current, (left, top) => {
|
|
107
|
+
scrollToOffset(left, top);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
94
111
|
}
|
|
95
|
-
}, [
|
|
112
|
+
}, [scrollIntoView]);
|
|
96
113
|
function selectLength(size) {
|
|
97
114
|
return !scrollX ? size.height : size.width;
|
|
98
115
|
}
|
|
@@ -173,6 +190,11 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
173
190
|
layoutRef
|
|
174
191
|
}, props));
|
|
175
192
|
updateScrollOptions(e, { scrollLeft, scrollTop });
|
|
193
|
+
if (enableTriggerIntersectionObserver && intersectionObservers) {
|
|
194
|
+
for (const key in intersectionObservers) {
|
|
195
|
+
intersectionObservers[key].throttleMeasure();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
176
198
|
}
|
|
177
199
|
function onScrollEnd(e) {
|
|
178
200
|
const { bindscrollend } = props;
|
|
@@ -197,6 +219,8 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
197
219
|
scrollViewRef.current.scrollTo({ x, y, animated: !!scrollWithAnimation });
|
|
198
220
|
scrollOptions.current.scrollLeft = x;
|
|
199
221
|
scrollOptions.current.scrollTop = y;
|
|
222
|
+
snapScrollLeft.current = x;
|
|
223
|
+
snapScrollTop.current = y;
|
|
200
224
|
}
|
|
201
225
|
}
|
|
202
226
|
function onRefresh() {
|
|
@@ -205,7 +229,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
205
229
|
bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef }, props));
|
|
206
230
|
}
|
|
207
231
|
function onScrollTouchStart(e) {
|
|
208
|
-
const {
|
|
232
|
+
const { bindtouchstart } = props;
|
|
209
233
|
bindtouchstart && bindtouchstart(e);
|
|
210
234
|
if (enhanced) {
|
|
211
235
|
binddragstart &&
|
|
@@ -219,7 +243,6 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
219
243
|
}
|
|
220
244
|
}
|
|
221
245
|
function onScrollTouchMove(e) {
|
|
222
|
-
const { binddragging, bindtouchmove, enhanced } = props;
|
|
223
246
|
bindtouchmove && bindtouchmove(e);
|
|
224
247
|
if (enhanced) {
|
|
225
248
|
binddragging &&
|
|
@@ -232,24 +255,23 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
232
255
|
}, props));
|
|
233
256
|
}
|
|
234
257
|
}
|
|
235
|
-
function
|
|
236
|
-
|
|
258
|
+
function onScrollTouchEnd(e) {
|
|
259
|
+
bindtouchend && bindtouchend(e);
|
|
237
260
|
if (enhanced) {
|
|
238
|
-
const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset;
|
|
239
|
-
const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize;
|
|
240
261
|
binddragend &&
|
|
241
262
|
binddragend(getCustomEvent('dragend', e, {
|
|
242
263
|
detail: {
|
|
243
|
-
scrollLeft: scrollLeft,
|
|
244
|
-
scrollTop: scrollTop
|
|
245
|
-
scrollHeight,
|
|
246
|
-
scrollWidth
|
|
264
|
+
scrollLeft: scrollOptions.current.scrollLeft || 0,
|
|
265
|
+
scrollTop: scrollOptions.current.scrollTop || 0
|
|
247
266
|
},
|
|
248
267
|
layoutRef
|
|
249
268
|
}, props));
|
|
250
|
-
updateScrollOptions(e, { scrollLeft, scrollTop });
|
|
251
269
|
}
|
|
252
270
|
}
|
|
271
|
+
function onScrollDrag(e) {
|
|
272
|
+
const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset;
|
|
273
|
+
updateScrollOptions(e, { scrollLeft, scrollTop });
|
|
274
|
+
}
|
|
253
275
|
let scrollAdditionalProps = {
|
|
254
276
|
style: { ...innerStyle, ...layoutStyle },
|
|
255
277
|
pinchGestureEnabled: false,
|
|
@@ -262,11 +284,15 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
262
284
|
ref: scrollViewRef,
|
|
263
285
|
onScroll: onScroll,
|
|
264
286
|
onContentSizeChange: onContentSizeChange,
|
|
265
|
-
bindtouchstart: onScrollTouchStart,
|
|
266
|
-
bindtouchmove: onScrollTouchMove,
|
|
267
|
-
|
|
287
|
+
bindtouchstart: ((enhanced && binddragstart) || bindtouchstart) ? onScrollTouchStart : undefined,
|
|
288
|
+
bindtouchmove: ((enhanced && binddragging) || bindtouchend) ? onScrollTouchMove : undefined,
|
|
289
|
+
bindtouchend: ((enhanced && binddragend) || bindtouchend) ? onScrollTouchEnd : undefined,
|
|
290
|
+
onScrollBeginDrag: onScrollDrag,
|
|
291
|
+
onScrollEndDrag: onScrollDrag,
|
|
268
292
|
onMomentumScrollEnd: onScrollEnd,
|
|
269
|
-
...layoutProps
|
|
293
|
+
...layoutProps,
|
|
294
|
+
...(simultaneousHandlers ? { simultaneousHandlers } : {}),
|
|
295
|
+
...(waitForHandlers ? { waitFor: waitForHandlers } : {})
|
|
270
296
|
};
|
|
271
297
|
if (enhanced) {
|
|
272
298
|
scrollAdditionalProps = {
|
|
@@ -276,9 +302,11 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
276
302
|
};
|
|
277
303
|
}
|
|
278
304
|
const innerProps = useInnerProps(props, scrollAdditionalProps, [
|
|
305
|
+
'id',
|
|
279
306
|
'scroll-x',
|
|
280
307
|
'scroll-y',
|
|
281
308
|
'enable-back-to-top',
|
|
309
|
+
'enable-trigger-intersection-observer',
|
|
282
310
|
'paging-enabled',
|
|
283
311
|
'show-scrollbar',
|
|
284
312
|
'upper-threshold',
|
|
@@ -315,5 +343,5 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
315
343
|
})}
|
|
316
344
|
</ScrollView>);
|
|
317
345
|
});
|
|
318
|
-
_ScrollView.displayName = '
|
|
346
|
+
_ScrollView.displayName = 'MpxScrollView';
|
|
319
347
|
export default _ScrollView;
|
|
@@ -67,6 +67,8 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
67
67
|
const initOffsetIndex = initIndex + (props.circular && totalElements > 1 ? 1 : 0);
|
|
68
68
|
const defaultX = (defaultWidth * initOffsetIndex) || 0;
|
|
69
69
|
const defaultY = (defaultHeight * initOffsetIndex) || 0;
|
|
70
|
+
// 主动scorllTo时是否要出发onScrollEnd
|
|
71
|
+
const needTriggerScrollEnd = useRef(true);
|
|
70
72
|
// 内部存储上一次的offset值
|
|
71
73
|
const autoplayTimerRef = useRef(null);
|
|
72
74
|
const scrollViewRef = useRef(null);
|
|
@@ -77,22 +79,21 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
77
79
|
// 内部存储上一次的偏移量
|
|
78
80
|
const internalsRef = useRef({
|
|
79
81
|
offset: {
|
|
80
|
-
x:
|
|
81
|
-
y:
|
|
82
|
+
x: 0,
|
|
83
|
+
y: 0
|
|
82
84
|
},
|
|
83
85
|
isScrolling: false
|
|
84
86
|
});
|
|
85
87
|
const isDragRef = useRef(false);
|
|
86
88
|
const [state, setState] = useState({
|
|
87
|
-
children: newChild,
|
|
88
89
|
width: dir === 'x' && typeof defaultWidth === 'number' ? defaultWidth - previousMargin - nextMargin : defaultWidth,
|
|
89
90
|
height: dir === 'y' && typeof defaultHeight === 'number' ? defaultHeight - previousMargin - nextMargin : defaultHeight,
|
|
90
91
|
// 真正的游标索引, 从0开始
|
|
91
92
|
index: initIndex,
|
|
92
93
|
total: totalElements,
|
|
93
94
|
offset: {
|
|
94
|
-
x:
|
|
95
|
-
y:
|
|
95
|
+
x: 0,
|
|
96
|
+
y: 0
|
|
96
97
|
},
|
|
97
98
|
dir
|
|
98
99
|
});
|
|
@@ -113,25 +114,38 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
113
114
|
}, [props.autoplay, props.current, state.index, state.width, state.height]);
|
|
114
115
|
useEffect(() => {
|
|
115
116
|
// 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
|
|
116
|
-
if (!props.autoplay && props.current !== state.index) {
|
|
117
|
+
if (!props.autoplay && props.current !== undefined && props.current !== state.index) {
|
|
117
118
|
const initIndex = props.current || 0;
|
|
118
119
|
// 这里要排除超过元素个数的设置
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
120
|
+
const { nextIndex, nextOffset } = getMultiNextConfig(props.current);
|
|
121
|
+
// 1. 安卓需要主动更新下内部状态, 2. IOS不能触发完wcrollTo之后立即updateState, 会造成滑动两次
|
|
122
|
+
// 2. setTimeout 是fix 当再渲染过程中触发scrollTo失败的问题
|
|
123
|
+
if (Platform.OS === 'ios') {
|
|
124
|
+
needTriggerScrollEnd.current = false;
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
scrollViewRef.current?.scrollTo({
|
|
127
|
+
...nextOffset,
|
|
128
|
+
animated: true
|
|
129
|
+
});
|
|
130
|
+
}, 50);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
updateState(nextIndex, nextOffset);
|
|
134
|
+
}
|
|
133
135
|
}
|
|
134
|
-
}, [props.current]);
|
|
136
|
+
}, [props.current, state.width, state.height]);
|
|
137
|
+
function getMultiNextConfig(target) {
|
|
138
|
+
const step = state.dir === 'x' ? state.width : state.height;
|
|
139
|
+
const targetPos = step * props.current;
|
|
140
|
+
const targetOffset = {
|
|
141
|
+
x: dir === 'x' ? targetPos : 0,
|
|
142
|
+
y: dir === 'y' ? targetPos : 0
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
nextIndex: target,
|
|
146
|
+
nextOffset: targetOffset
|
|
147
|
+
};
|
|
148
|
+
}
|
|
135
149
|
/**
|
|
136
150
|
* @desc: 更新状态: index和offset, 并响应索引变化的事件
|
|
137
151
|
* scrollViewOffset: 移动到的目标位置
|
|
@@ -181,7 +195,6 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
181
195
|
nextIndex = isBack ? nextIndex - 2 : nextIndex;
|
|
182
196
|
}
|
|
183
197
|
if (!props.circular) {
|
|
184
|
-
// nextIndex = isBack ? nextIndex - 2 : nextIndex
|
|
185
198
|
nextOffset = Object.assign({}, currentOffset, { [state.dir]: step * nextIndex });
|
|
186
199
|
}
|
|
187
200
|
else {
|
|
@@ -230,13 +243,12 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
230
243
|
createAutoPlay();
|
|
231
244
|
return;
|
|
232
245
|
}
|
|
233
|
-
if (!Array.isArray(
|
|
246
|
+
if (!Array.isArray(props.children)) {
|
|
234
247
|
return;
|
|
235
248
|
}
|
|
236
249
|
const step = state.dir === 'x' ? state.width : state.height;
|
|
237
250
|
const { nextOffset, autoMoveOffset, isAutoEnd } = getNextConfig(state.offset);
|
|
238
251
|
// 这里可以scroll到下一个元素, 但是把scrollView的偏移量在设置为content,视觉效果就没了吧
|
|
239
|
-
// scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: true })
|
|
240
252
|
if (Platform.OS === 'ios') {
|
|
241
253
|
if (!isAutoEnd) {
|
|
242
254
|
scrollViewRef.current?.scrollTo({ x: nextOffset.x, y: nextOffset.y, animated: true });
|
|
@@ -266,7 +278,6 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
266
278
|
// 安卓无法实现视觉的无缝连接, 只能回到真正的位置, 且安卓调用scrollTo不能触发onMomentumScrollEnd,还未找到为啥
|
|
267
279
|
if (state.dir === 'x') {
|
|
268
280
|
scrollViewRef.current?.scrollTo({ x: step, y: step, animated: true });
|
|
269
|
-
// scrollViewRef.current?.scrollTo({ x: autoMoveOffset.x, y: autoMoveOffset.y, animated: true })
|
|
270
281
|
}
|
|
271
282
|
else {
|
|
272
283
|
scrollViewRef.current?.scrollTo({ x: autoMoveOffset.x, y: step, animated: true });
|
|
@@ -283,9 +294,15 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
283
294
|
}
|
|
284
295
|
/**
|
|
285
296
|
* 当用户开始拖动结束
|
|
297
|
+
* 注意: 当手动调用scrollTo的时候, 安卓不会触发onMomentumScrollEnd, IOS会触发onMomentumScrollEnd
|
|
286
298
|
*/
|
|
287
299
|
function onScrollEnd(event) {
|
|
288
|
-
|
|
300
|
+
if (Platform.OS === 'ios' && !needTriggerScrollEnd.current) {
|
|
301
|
+
const { nextIndex, nextOffset } = getMultiNextConfig(props.current);
|
|
302
|
+
updateState(nextIndex, nextOffset);
|
|
303
|
+
needTriggerScrollEnd.current = true;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
289
306
|
if (totalElements === 1) {
|
|
290
307
|
return;
|
|
291
308
|
}
|
|
@@ -311,58 +328,41 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
311
328
|
* @desc: 水平方向时,获取元素的布局,更新, 其中如果传递100%时需要依赖measure计算元算的宽高
|
|
312
329
|
*/
|
|
313
330
|
function onWrapperLayout(e) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
331
|
+
scrollViewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
|
|
332
|
+
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
|
|
333
|
+
const isWDiff = state.width !== width;
|
|
334
|
+
const isHDiff = state.height !== height;
|
|
335
|
+
if (isWDiff || isHDiff) {
|
|
336
|
+
const changeState = {
|
|
337
|
+
width: isWDiff ? width : state.width,
|
|
338
|
+
height: isHDiff ? height : state.height
|
|
339
|
+
};
|
|
340
|
+
const attr = state.dir === 'x' ? 'width' : 'height';
|
|
341
|
+
changeState[attr] = changeState[attr] - previousMargin - nextMargin;
|
|
342
|
+
const correctOffset = Object.assign({}, state.offset, {
|
|
343
|
+
[state.dir]: initOffsetIndex * (state.dir === 'x' ? changeState.width : changeState.height)
|
|
344
|
+
});
|
|
345
|
+
state.width = changeState.width;
|
|
346
|
+
state.height = changeState.height;
|
|
347
|
+
// 这里setState之后,会再触发重新渲染, renderScrollView会再次触发onScrollEnd,
|
|
348
|
+
setState((preState) => {
|
|
349
|
+
return {
|
|
350
|
+
...preState,
|
|
351
|
+
width: changeState.width,
|
|
352
|
+
height: changeState.height
|
|
328
353
|
};
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
});
|
|
334
|
-
state.offset = correctOffset;
|
|
335
|
-
state.width = changeState.width;
|
|
336
|
-
state.height = changeState.height;
|
|
337
|
-
setState((preState) => {
|
|
338
|
-
return {
|
|
339
|
-
...preState,
|
|
340
|
-
offset: correctOffset,
|
|
341
|
-
width: changeState.width,
|
|
342
|
-
height: changeState.height
|
|
343
|
-
};
|
|
344
|
-
});
|
|
345
|
-
scrollViewRef.current?.scrollTo({ x: correctOffset.x, y: correctOffset.y, animated: false });
|
|
346
|
-
}
|
|
347
|
-
props.getInnerLayout && props.getInnerLayout(layoutRef);
|
|
348
|
-
});
|
|
349
|
-
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
props.getInnerLayout && props.getInnerLayout(layoutRef);
|
|
357
|
+
});
|
|
350
358
|
}
|
|
351
359
|
function getOffset() {
|
|
352
360
|
const step = state.dir === 'x' ? state.width : state.height;
|
|
353
361
|
if (!step || Number.isNaN(+step))
|
|
354
362
|
return [];
|
|
355
363
|
const offsetArray = [];
|
|
356
|
-
|
|
357
|
-
offsetArray.push(
|
|
358
|
-
for (let i = 1; i < totalElements; i++) {
|
|
359
|
-
offsetArray.push(i * step - previousMargin);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
for (let i = 0; i < totalElements; i++) {
|
|
364
|
-
offsetArray.push(i * step);
|
|
365
|
-
}
|
|
364
|
+
for (let i = 0; i < totalElements; i++) {
|
|
365
|
+
offsetArray.push(i * step);
|
|
366
366
|
}
|
|
367
367
|
return offsetArray;
|
|
368
368
|
}
|
|
@@ -371,7 +371,7 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
371
371
|
const scrollElementProps = {
|
|
372
372
|
ref: scrollViewRef,
|
|
373
373
|
horizontal: props.horizontal,
|
|
374
|
-
pagingEnabled:
|
|
374
|
+
pagingEnabled: true,
|
|
375
375
|
snapToOffsets: offsetsArray,
|
|
376
376
|
decelerationRate: 0.99,
|
|
377
377
|
showsHorizontalScrollIndicator: false,
|
|
@@ -423,20 +423,21 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
423
423
|
</View>);
|
|
424
424
|
}
|
|
425
425
|
function renderPages() {
|
|
426
|
-
const { width, height
|
|
426
|
+
const { width, height } = state;
|
|
427
|
+
const { children } = props;
|
|
427
428
|
const { circular } = props;
|
|
428
429
|
const pageStyle = { width: width, height: height };
|
|
429
430
|
// 设置了previousMargin或者nextMargin,
|
|
430
431
|
// 1. 元素的宽度是减去这两个数目之和
|
|
431
432
|
// 2. previousMargin设置marginLeft正值, nextmargin设置marginRight负值
|
|
432
433
|
// 3. 第一个元素设置previousMargin 和 nextMargin, 最后一个元素
|
|
433
|
-
if (
|
|
434
|
+
if (totalElements > 1 && Array.isArray(children)) {
|
|
434
435
|
let arrElements = [];
|
|
435
436
|
// pages = ["2", "0", "1", "2", "0"]
|
|
436
437
|
const pages = Array.isArray(children) ? Object.keys(children) : [];
|
|
437
438
|
/* 无限循环的时候 */
|
|
438
439
|
if (circular) {
|
|
439
|
-
pages.unshift(
|
|
440
|
+
pages.unshift(totalElements - 1 + '');
|
|
440
441
|
pages.push('0');
|
|
441
442
|
}
|
|
442
443
|
arrElements = pages.map((page, i) => {
|
|
@@ -447,7 +448,6 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
447
448
|
else if (i === pages.length - 1 && typeof width === 'number') {
|
|
448
449
|
nextMargin && (extraStyle.marginRight = nextMargin);
|
|
449
450
|
}
|
|
450
|
-
// return (<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>{children[+page]}</View>)
|
|
451
451
|
return (<View style={[pageStyle, styles.slide, extraStyle]} key={'page' + i}>
|
|
452
452
|
{wrapChildren({
|
|
453
453
|
children: children[+page]
|
|
@@ -474,5 +474,5 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
474
474
|
{props.showsPagination && renderPagination()}
|
|
475
475
|
</View>);
|
|
476
476
|
});
|
|
477
|
-
_Carouse.displayName = '
|
|
477
|
+
_Carouse.displayName = 'MpxCarouse';
|
|
478
478
|
export default _Carouse;
|
|
@@ -58,6 +58,13 @@ const _Switch = forwardRef((props, ref) => {
|
|
|
58
58
|
formValuesMap.set(props.name, { getValue, resetValue });
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
return () => {
|
|
63
|
+
if (formValuesMap && props.name) {
|
|
64
|
+
formValuesMap.delete(props.name);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}, []);
|
|
61
68
|
const innerProps = useInnerProps(props, {
|
|
62
69
|
ref: nodeRef,
|
|
63
70
|
style: { ...normalStyle, ...layoutStyle },
|
|
@@ -76,5 +83,5 @@ const _Switch = forwardRef((props, ref) => {
|
|
|
76
83
|
}
|
|
77
84
|
return <Switch {...innerProps} style={normalStyle} value={isChecked} trackColor={{ false: '#FFF', true: color }} thumbColor={isChecked ? '#FFF' : '#f4f3f4'} ios_backgroundColor="#FFF"/>;
|
|
78
85
|
});
|
|
79
|
-
_Switch.displayName = '
|
|
86
|
+
_Switch.displayName = 'MpxSwitch';
|
|
80
87
|
export default _Switch;
|
|
@@ -23,5 +23,5 @@ const Textarea = forwardRef((props, ref) => {
|
|
|
23
23
|
]);
|
|
24
24
|
return (<Input ref={ref} multiline confirm-type='next' bindblur={() => Keyboard.dismiss()} {...restProps}/>);
|
|
25
25
|
});
|
|
26
|
-
Textarea.displayName = '
|
|
26
|
+
Textarea.displayName = 'MpxTextarea';
|
|
27
27
|
export default Textarea;
|