@mpxjs/webpack-plugin 2.10.4-beta.9 → 2.10.5
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/LICENSE +433 -0
- package/lib/platform/json/wx/index.js +1 -0
- package/lib/platform/style/wx/index.js +22 -21
- package/lib/platform/template/wx/component-config/button.js +1 -1
- package/lib/platform/template/wx/component-config/index.js +1 -5
- package/lib/platform/template/wx/component-config/input.js +1 -1
- package/lib/react/processJSON.js +6 -7
- package/lib/react/processScript.js +9 -1
- package/lib/react/script-helper.js +5 -1
- package/lib/runtime/components/react/context.ts +3 -12
- package/lib/runtime/components/react/dist/context.js +1 -4
- package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +6 -17
- package/lib/runtime/components/react/dist/mpx-view.jsx +11 -4
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +13 -13
- package/lib/runtime/components/react/dist/useAnimationHooks.js +27 -4
- package/lib/runtime/components/react/dist/utils.jsx +86 -107
- package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +3 -3
- package/lib/runtime/components/react/mpx-scroll-view.tsx +50 -68
- package/lib/runtime/components/react/mpx-view.tsx +15 -5
- package/lib/runtime/components/react/mpx-web-view.tsx +12 -12
- package/lib/runtime/components/react/useAnimationHooks.ts +30 -9
- package/lib/runtime/components/react/utils.tsx +92 -110
- package/lib/runtime/components/web/mpx-scroll-view.vue +4 -21
- package/lib/template-compiler/compiler.js +1 -1
- package/package.json +3 -3
- package/lib/platform/template/wx/component-config/sticky-header.js +0 -23
- package/lib/platform/template/wx/component-config/sticky-section.js +0 -23
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +0 -112
- package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +0 -45
- package/lib/runtime/components/react/mpx-sticky-header.tsx +0 -176
- package/lib/runtime/components/react/mpx-sticky-section.tsx +0 -96
- package/lib/runtime/components/web/mpx-sticky-header.vue +0 -91
- package/lib/runtime/components/web/mpx-sticky-section.vue +0 -15
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
* ✔ bindscroll
|
|
33
33
|
*/
|
|
34
34
|
import { ScrollView, RefreshControl, Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
35
|
-
import { Animated as RNAnimated } from 'react-native';
|
|
36
35
|
import { isValidElement, Children, useRef, useState, useEffect, forwardRef, useContext, useMemo, createElement } from 'react';
|
|
37
36
|
import Animated, { useAnimatedRef, useSharedValue, withTiming, useAnimatedStyle, runOnJS } from 'react-native-reanimated';
|
|
38
37
|
import { warn } from '@mpxjs/utils';
|
|
@@ -40,11 +39,9 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
|
40
39
|
import useNodesRef from './useNodesRef';
|
|
41
40
|
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, HIDDEN_STYLE } from './utils';
|
|
42
41
|
import { IntersectionObserverContext, ScrollViewContext } from './context';
|
|
43
|
-
const AnimatedScrollView = RNAnimated.createAnimatedComponent(ScrollView);
|
|
44
42
|
const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
45
43
|
const { textProps, innerProps: props = {} } = splitProps(scrollViewProps);
|
|
46
|
-
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, '
|
|
47
|
-
const scrollOffset = useRef(new RNAnimated.Value(0)).current;
|
|
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;
|
|
48
45
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
49
46
|
const waitForHandlers = flatGesture(waitFor);
|
|
50
47
|
const snapScrollTop = useRef(0);
|
|
@@ -92,13 +89,12 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
92
89
|
},
|
|
93
90
|
gestureRef: scrollViewRef
|
|
94
91
|
});
|
|
95
|
-
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout });
|
|
96
92
|
const contextValue = useMemo(() => {
|
|
97
93
|
return {
|
|
98
|
-
gestureRef: scrollViewRef
|
|
99
|
-
scrollOffset
|
|
94
|
+
gestureRef: scrollViewRef
|
|
100
95
|
};
|
|
101
96
|
}, []);
|
|
97
|
+
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout });
|
|
102
98
|
const hasRefresherLayoutRef = useRef(false);
|
|
103
99
|
// layout 完成前先隐藏,避免安卓闪烁问题
|
|
104
100
|
const refresherLayoutStyle = useMemo(() => { return !hasRefresherLayoutRef.current ? HIDDEN_STYLE : {}; }, [hasRefresherLayoutRef.current]);
|
|
@@ -324,12 +320,6 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
324
320
|
updateScrollOptions(e, { scrollLeft, scrollTop });
|
|
325
321
|
updateIntersection();
|
|
326
322
|
}
|
|
327
|
-
const scrollHandler = RNAnimated.event([{ nativeEvent: { contentOffset: { y: scrollOffset } } }], {
|
|
328
|
-
useNativeDriver: true,
|
|
329
|
-
listener: (event) => {
|
|
330
|
-
onScroll(event);
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
323
|
function onScrollDragStart(e) {
|
|
334
324
|
hasCallScrollToLower.current = false;
|
|
335
325
|
hasCallScrollToUpper.current = false;
|
|
@@ -486,7 +476,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
486
476
|
scrollEnabled: !enableScroll ? false : !!(scrollX || scrollY),
|
|
487
477
|
bounces: false,
|
|
488
478
|
ref: scrollViewRef,
|
|
489
|
-
onScroll:
|
|
479
|
+
onScroll: onScroll,
|
|
490
480
|
onContentSizeChange: onContentSizeChange,
|
|
491
481
|
bindtouchstart: ((enhanced && binddragstart) || bindtouchstart) && onScrollTouchStart,
|
|
492
482
|
bindtouchmove: ((enhanced && binddragging) || bindtouchmove) && onScrollTouchMove,
|
|
@@ -528,14 +518,13 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
528
518
|
'bindscrolltolower',
|
|
529
519
|
'bindrefresherrefresh'
|
|
530
520
|
], { layoutRef });
|
|
531
|
-
const
|
|
532
|
-
const withRefresherScrollView = createElement(GestureDetector, { gesture: panGesture }, createElement(ScrollViewComponent, 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 }), {
|
|
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 }), {
|
|
533
522
|
hasVarDec,
|
|
534
523
|
varContext: varContextRef.current,
|
|
535
524
|
textStyle,
|
|
536
525
|
textProps
|
|
537
526
|
})))));
|
|
538
|
-
const commonScrollView = createElement(
|
|
527
|
+
const commonScrollView = createElement(ScrollView, extendObject(innerProps, {
|
|
539
528
|
refreshControl: refresherEnabled
|
|
540
529
|
? createElement(RefreshControl, extendObject({
|
|
541
530
|
progressBackgroundColor: refresherBackground,
|
|
@@ -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';
|
|
@@ -543,7 +543,7 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
|
|
|
543
543
|
}
|
|
544
544
|
const _View = forwardRef((viewProps, ref) => {
|
|
545
545
|
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;
|
|
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, catchtransitionend, bindtransitionend } = props;
|
|
547
547
|
// 默认样式
|
|
548
548
|
const defaultStyle = style.display === 'flex'
|
|
549
549
|
? {
|
|
@@ -575,10 +575,17 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
575
575
|
});
|
|
576
576
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
577
577
|
const viewStyle = extendObject({}, innerStyle, layoutStyle);
|
|
578
|
+
const transitionend = isFunction(catchtransitionend)
|
|
579
|
+
? catchtransitionend
|
|
580
|
+
: isFunction(bindtransitionend)
|
|
581
|
+
? bindtransitionend
|
|
582
|
+
: undefined;
|
|
578
583
|
const { enableStyleAnimation, animationStyle } = useAnimationHooks({
|
|
579
|
-
|
|
584
|
+
layoutRef,
|
|
580
585
|
animation,
|
|
581
|
-
|
|
586
|
+
enableAnimation,
|
|
587
|
+
style: viewStyle,
|
|
588
|
+
transitionend
|
|
582
589
|
});
|
|
583
590
|
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
584
591
|
ref: nodeRef,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useRef, useContext, useMemo, useState } from 'react';
|
|
1
|
+
import { forwardRef, useRef, useContext, useMemo, useState, useEffect } from 'react';
|
|
2
2
|
import { warn, isFunction } from '@mpxjs/utils';
|
|
3
3
|
import Portal from './mpx-portal/index';
|
|
4
4
|
import { getCustomEvent } from './getInnerListeners';
|
|
@@ -74,17 +74,17 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
74
74
|
isNavigateBack.current = false;
|
|
75
75
|
};
|
|
76
76
|
const navigation = useNavigation();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
let beforeRemoveSubscription;
|
|
79
|
+
if (__mpx_mode__ !== 'ios') {
|
|
80
|
+
beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle);
|
|
81
|
+
}
|
|
82
|
+
return () => {
|
|
83
|
+
if (isFunction(beforeRemoveSubscription)) {
|
|
84
|
+
beforeRemoveSubscription();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
88
88
|
useNodesRef(props, ref, webViewRef, {
|
|
89
89
|
style: defaultWebViewStyle
|
|
90
90
|
});
|
|
@@ -160,7 +160,7 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
160
160
|
{ // case下不允许直接声明,包个块解决该问题
|
|
161
161
|
const title = postData._documentTitle?.trim();
|
|
162
162
|
if (title !== undefined) {
|
|
163
|
-
navigation && navigation.
|
|
163
|
+
navigation && navigation.setOptions({ title });
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
break;
|
|
@@ -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
|
}
|
|
@@ -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
|
});
|
|
@@ -451,18 +441,7 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
|
|
|
451
441
|
if (enableOffset) {
|
|
452
442
|
nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
|
|
453
443
|
const { y: navigationY = 0 } = navigation?.layout || {};
|
|
454
|
-
layoutRef.current = {
|
|
455
|
-
x,
|
|
456
|
-
y: y - navigationY,
|
|
457
|
-
width,
|
|
458
|
-
height,
|
|
459
|
-
offsetLeft,
|
|
460
|
-
offsetTop: offsetTop - navigationY,
|
|
461
|
-
_x: x,
|
|
462
|
-
_y: y,
|
|
463
|
-
_offsetLeft: offsetLeft,
|
|
464
|
-
_offsetTop: offsetTop
|
|
465
|
-
};
|
|
444
|
+
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft, offsetTop: offsetTop - navigationY };
|
|
466
445
|
});
|
|
467
446
|
}
|
|
468
447
|
onLayout && onLayout(e);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react'
|
|
2
2
|
import { GestureResponderEvent, LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, ScrollView, StyleSheet, View } from 'react-native'
|
|
3
3
|
import Reanimated, { AnimatedRef, useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'
|
|
4
|
-
import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS } from '../utils'
|
|
4
|
+
import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS, isHarmony } from '../utils'
|
|
5
5
|
import useNodesRef, { HandlerRef } from '../useNodesRef'
|
|
6
6
|
import PickerIndicator from './pickerViewIndicator'
|
|
7
7
|
import PickerMask from './pickerViewMask'
|
|
@@ -209,9 +209,9 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
209
209
|
|
|
210
210
|
const onScrollEndDrag = useCallback((e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
211
211
|
dragging.current = false
|
|
212
|
-
if (
|
|
212
|
+
if (!isAndroid) {
|
|
213
213
|
const { y } = e.nativeEvent.contentOffset
|
|
214
|
-
if (y % itemRawH === 0) {
|
|
214
|
+
if (y % itemRawH === 0 || (isHarmony && y > snapToOffsets[maxIndex])) {
|
|
215
215
|
onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } })
|
|
216
216
|
} else if (y > 0 && y < snapToOffsets[maxIndex]) {
|
|
217
217
|
timerResetPosition.current = setTimeout(() => {
|