@mpxjs/webpack-plugin 2.9.70 → 2.9.71
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/template/wx/component-config/movable-view.js +8 -1
- package/lib/platform/template/wx/component-config/picker-view.js +1 -5
- package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
- package/lib/platform/template/wx/index.js +0 -4
- package/lib/runtime/components/react/context.ts +8 -0
- package/lib/runtime/components/react/dist/context.js +2 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +34 -31
- package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +93 -58
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +35 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +151 -127
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +38 -34
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +11 -4
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +31 -8
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +670 -0
- package/lib/runtime/components/react/dist/mpx-view.jsx +15 -53
- package/lib/runtime/components/react/dist/pickerFaces.js +7 -6
- package/lib/runtime/components/react/dist/pickerVIewContext.js +14 -0
- package/lib/runtime/components/react/dist/pickerViewIndicator.jsx +23 -0
- package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
- package/lib/runtime/components/react/dist/useAnimationHooks.js +20 -2
- package/lib/runtime/components/react/dist/utils.jsx +74 -11
- package/lib/runtime/components/react/getInnerListeners.ts +43 -32
- package/lib/runtime/components/react/mpx-button.tsx +20 -57
- package/lib/runtime/components/react/mpx-movable-view.tsx +119 -74
- package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +76 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +206 -183
- package/lib/runtime/components/react/mpx-picker-view.tsx +49 -48
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
- package/lib/runtime/components/react/mpx-scroll-view.tsx +21 -10
- package/lib/runtime/components/react/mpx-swiper-item.tsx +45 -11
- package/lib/runtime/components/react/mpx-swiper.tsx +742 -0
- package/lib/runtime/components/react/mpx-view.tsx +18 -65
- package/lib/runtime/components/react/pickerFaces.ts +10 -7
- package/lib/runtime/components/react/pickerVIewContext.ts +27 -0
- package/lib/runtime/components/react/pickerViewIndicator.tsx +34 -0
- package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
- package/lib/runtime/components/react/types/{getInnerListeners.ts → getInnerListeners.d.ts} +4 -5
- package/lib/runtime/components/react/types/global.d.ts +10 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +24 -3
- package/lib/runtime/components/react/utils.tsx +85 -12
- package/lib/runtime/components/web/mpx-checkbox.vue +1 -1
- package/lib/runtime/components/web/mpx-picker-view-column.vue +9 -4
- package/lib/template-compiler/compiler.js +61 -13
- package/lib/wxss/loader.js +15 -2
- package/package.json +3 -3
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -480
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
- package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
- package/lib/runtime/components/react/dist/pickerOverlay.jsx +0 -21
- package/lib/runtime/components/react/dist/types/common.js +0 -1
- package/lib/runtime/components/react/dist/types/getInnerListeners.js +0 -1
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
- package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
- package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
- package/lib/runtime/components/react/pickerOverlay.tsx +0 -32
- /package/lib/runtime/components/react/types/{common.ts → common.d.ts} +0 -0
|
@@ -12,9 +12,10 @@ import useAnimationHooks from './useAnimationHooks'
|
|
|
12
12
|
import type { AnimationProp } from './useAnimationHooks'
|
|
13
13
|
import { ExtendedViewStyle } from './types/common'
|
|
14
14
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
15
|
-
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject } from './utils'
|
|
15
|
+
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHover } from './utils'
|
|
16
16
|
import { error } from '@mpxjs/utils'
|
|
17
17
|
import LinearGradient from 'react-native-linear-gradient'
|
|
18
|
+
import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
|
|
18
19
|
|
|
19
20
|
export interface _ViewProps extends ViewProps {
|
|
20
21
|
style?: ExtendedViewStyle
|
|
@@ -642,7 +643,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
|
|
|
642
643
|
|
|
643
644
|
interface WrapChildrenConfig {
|
|
644
645
|
hasVarDec: boolean
|
|
645
|
-
enableBackground
|
|
646
|
+
enableBackground?: boolean
|
|
646
647
|
textStyle?: TextStyle
|
|
647
648
|
backgroundStyle?: ExtendedViewStyle
|
|
648
649
|
varContext?: Record<string, any>
|
|
@@ -684,8 +685,6 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
684
685
|
animation
|
|
685
686
|
} = props
|
|
686
687
|
|
|
687
|
-
const [isHover, setIsHover] = useState(false)
|
|
688
|
-
|
|
689
688
|
// 默认样式
|
|
690
689
|
const defaultStyle: ExtendedViewStyle = style.display === 'flex'
|
|
691
690
|
? {
|
|
@@ -696,6 +695,9 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
696
695
|
}
|
|
697
696
|
: {}
|
|
698
697
|
|
|
698
|
+
const enableHover = !!hoverStyle
|
|
699
|
+
const { isHover, gesture } = useHover({ enableHover, hoverStartTime, hoverStayTime })
|
|
700
|
+
|
|
699
701
|
const styleObj: ExtendedViewStyle = extendObject({}, defaultStyle, style, isHover ? hoverStyle as ExtendedViewStyle : {})
|
|
700
702
|
|
|
701
703
|
const {
|
|
@@ -726,45 +728,6 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
726
728
|
style: normalStyle
|
|
727
729
|
})
|
|
728
730
|
|
|
729
|
-
const dataRef = useRef<{
|
|
730
|
-
startTimer?: ReturnType<typeof setTimeout>
|
|
731
|
-
stayTimer?: ReturnType<typeof setTimeout>
|
|
732
|
-
}>({})
|
|
733
|
-
|
|
734
|
-
useEffect(() => {
|
|
735
|
-
return () => {
|
|
736
|
-
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
737
|
-
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
738
|
-
}
|
|
739
|
-
}, [])
|
|
740
|
-
|
|
741
|
-
const setStartTimer = () => {
|
|
742
|
-
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
743
|
-
dataRef.current.startTimer = setTimeout(() => {
|
|
744
|
-
setIsHover(true)
|
|
745
|
-
}, +hoverStartTime)
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
const setStayTimer = () => {
|
|
749
|
-
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
750
|
-
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
751
|
-
dataRef.current.stayTimer = setTimeout(() => {
|
|
752
|
-
setIsHover(false)
|
|
753
|
-
}, +hoverStayTime)
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
function onTouchStart (e: NativeSyntheticEvent<TouchEvent>) {
|
|
757
|
-
const { bindtouchstart } = props
|
|
758
|
-
bindtouchstart && bindtouchstart(e)
|
|
759
|
-
setStartTimer()
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
function onTouchEnd (e: NativeSyntheticEvent<TouchEvent>) {
|
|
763
|
-
const { bindtouchend } = props
|
|
764
|
-
bindtouchend && bindtouchend(e)
|
|
765
|
-
setStayTimer()
|
|
766
|
-
}
|
|
767
|
-
|
|
768
731
|
const {
|
|
769
732
|
layoutRef,
|
|
770
733
|
layoutStyle,
|
|
@@ -773,33 +736,19 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
773
736
|
|
|
774
737
|
const viewStyle = extendObject({}, innerStyle, layoutStyle)
|
|
775
738
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
}
|
|
739
|
+
const { enableStyleAnimation, animationStyle } = useAnimationHooks({
|
|
740
|
+
enableAnimation,
|
|
741
|
+
animation,
|
|
742
|
+
style: viewStyle
|
|
743
|
+
})
|
|
781
744
|
|
|
782
|
-
const finalStyle = enableAnimationRef.current
|
|
783
|
-
? [viewStyle,
|
|
784
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
785
|
-
useAnimationHooks({
|
|
786
|
-
animation,
|
|
787
|
-
style: viewStyle
|
|
788
|
-
})]
|
|
789
|
-
: viewStyle
|
|
790
745
|
const innerProps = useInnerProps(
|
|
791
746
|
props,
|
|
792
747
|
extendObject({
|
|
793
748
|
ref: nodeRef,
|
|
794
|
-
style:
|
|
749
|
+
style: enableStyleAnimation ? [viewStyle, animationStyle] : viewStyle
|
|
795
750
|
},
|
|
796
|
-
layoutProps
|
|
797
|
-
hoverStyle
|
|
798
|
-
? {
|
|
799
|
-
bindtouchstart: onTouchStart,
|
|
800
|
-
bindtouchend: onTouchEnd
|
|
801
|
-
}
|
|
802
|
-
: {}
|
|
751
|
+
layoutProps
|
|
803
752
|
), [
|
|
804
753
|
'hover-start-time',
|
|
805
754
|
'hover-stay-time',
|
|
@@ -820,9 +769,13 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
820
769
|
enableFastImage
|
|
821
770
|
})
|
|
822
771
|
|
|
823
|
-
|
|
772
|
+
const BaseComponent = enableStyleAnimation
|
|
824
773
|
? createElement(Animated.View, innerProps, childNode)
|
|
825
774
|
: createElement(View, innerProps, childNode)
|
|
775
|
+
|
|
776
|
+
return enableHover
|
|
777
|
+
? createElement(GestureDetector, { gesture: gesture as PanGesture }, BaseComponent)
|
|
778
|
+
: BaseComponent
|
|
826
779
|
})
|
|
827
780
|
|
|
828
781
|
_View.displayName = 'MpxView'
|
|
@@ -8,6 +8,7 @@ export type Faces = {
|
|
|
8
8
|
deg: number
|
|
9
9
|
offsetY: number
|
|
10
10
|
opacity: number
|
|
11
|
+
scale: number
|
|
11
12
|
screenHeight: number
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -33,7 +34,7 @@ export const createFaces = (
|
|
|
33
34
|
const maxStep = Math.trunc((visibleCount + 2) / 2) // + 2 because there are 2 more faces at 90 degrees
|
|
34
35
|
const stepDegree = 90 / maxStep
|
|
35
36
|
|
|
36
|
-
const result = []
|
|
37
|
+
const result: number[] = []
|
|
37
38
|
for (let i = 1; i <= maxStep; i++) {
|
|
38
39
|
result.push(i * stepDegree)
|
|
39
40
|
}
|
|
@@ -62,17 +63,17 @@ export const createFaces = (
|
|
|
62
63
|
const getOpacity = (index: number) => {
|
|
63
64
|
const map: Record<number, number> = {
|
|
64
65
|
0: 0,
|
|
65
|
-
1: 0.
|
|
66
|
-
2: 0.
|
|
67
|
-
3: 0.45,
|
|
68
|
-
4: 0.5
|
|
66
|
+
1: 0.8,
|
|
67
|
+
2: 0.9
|
|
69
68
|
}
|
|
70
|
-
return map[index] ?? Math.min(1, map[
|
|
69
|
+
return map[index] ?? Math.min(1, map[2] + index * 0.05)
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
const degrees = getDegreesRelativeCenter()
|
|
74
73
|
const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees)
|
|
75
74
|
|
|
75
|
+
const scales = [0.973, 0.9, 0.8]
|
|
76
|
+
|
|
76
77
|
return [
|
|
77
78
|
// top items
|
|
78
79
|
...degrees
|
|
@@ -82,13 +83,14 @@ export const createFaces = (
|
|
|
82
83
|
deg: degree,
|
|
83
84
|
opacity: getOpacity(degrees.length - 1 - index),
|
|
84
85
|
offsetY: -1 * offsets[index],
|
|
86
|
+
scale: scales[index],
|
|
85
87
|
screenHeight: screenHeight[index]
|
|
86
88
|
}
|
|
87
89
|
})
|
|
88
90
|
.reverse(),
|
|
89
91
|
|
|
90
92
|
// center item
|
|
91
|
-
{ index: 0, deg: 0, opacity: 1, offsetY: 0, screenHeight: itemHeight },
|
|
93
|
+
{ index: 0, deg: 0, opacity: 1, offsetY: 0, scale: 1, screenHeight: itemHeight },
|
|
92
94
|
|
|
93
95
|
// bottom items
|
|
94
96
|
...degrees.map<Faces>((degree, index) => {
|
|
@@ -97,6 +99,7 @@ export const createFaces = (
|
|
|
97
99
|
deg: -1 * degree,
|
|
98
100
|
opacity: getOpacity(degrees.length - 1 - index),
|
|
99
101
|
offsetY: offsets[index],
|
|
102
|
+
scale: scales[index],
|
|
100
103
|
screenHeight: screenHeight[index]
|
|
101
104
|
}
|
|
102
105
|
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react'
|
|
2
|
+
import { SharedValue } from 'react-native-reanimated'
|
|
3
|
+
|
|
4
|
+
type ContextValue = SharedValue<number>
|
|
5
|
+
|
|
6
|
+
export const PickerViewColumnAnimationContext = createContext<
|
|
7
|
+
ContextValue | undefined
|
|
8
|
+
>(undefined)
|
|
9
|
+
|
|
10
|
+
export const usePickerViewColumnAnimationContext = () => {
|
|
11
|
+
const value = useContext(PickerViewColumnAnimationContext)
|
|
12
|
+
if (value === undefined) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
'usePickerViewColumnAnimationContext must be called from within PickerViewColumnAnimationContext.Provider!'
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
return value
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const PickerViewStyleContext = createContext<
|
|
21
|
+
Record<string, any> | undefined
|
|
22
|
+
>(undefined)
|
|
23
|
+
|
|
24
|
+
export const usePickerViewStyleContext = () => {
|
|
25
|
+
const value = useContext(PickerViewStyleContext)
|
|
26
|
+
return value
|
|
27
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
|
|
3
|
+
|
|
4
|
+
type IndicatorProps = {
|
|
5
|
+
itemHeight: number
|
|
6
|
+
indicatorItemStyle?: StyleProp<ViewStyle>
|
|
7
|
+
indicatorContainerStyle?: StyleProp<ViewStyle>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const _PickerViewIndicator = ({ itemHeight, indicatorItemStyle, indicatorContainerStyle }: IndicatorProps) => {
|
|
11
|
+
return (
|
|
12
|
+
<View style={[styles.indicatorContainer, indicatorContainerStyle]} pointerEvents={'none'}>
|
|
13
|
+
<View style={[styles.selection, { height: itemHeight }, indicatorItemStyle]} />
|
|
14
|
+
</View>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const styles = StyleSheet.create({
|
|
19
|
+
indicatorContainer: {
|
|
20
|
+
...StyleSheet.absoluteFillObject,
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
zIndex: 200
|
|
24
|
+
},
|
|
25
|
+
selection: {
|
|
26
|
+
borderTopWidth: 1,
|
|
27
|
+
borderBottomWidth: 1,
|
|
28
|
+
borderColor: 'rgba(0, 0, 0, 0.05)',
|
|
29
|
+
alignSelf: 'stretch'
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
_PickerViewIndicator.displayName = 'MpxPickerViewIndicator'
|
|
34
|
+
export default _PickerViewIndicator
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
|
|
3
|
+
import LinearGradient from 'react-native-linear-gradient'
|
|
4
|
+
|
|
5
|
+
type MaskProps = {
|
|
6
|
+
itemHeight: number
|
|
7
|
+
maskContainerStyle?: StyleProp<ViewStyle>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const _PickerViewMask = ({
|
|
11
|
+
itemHeight,
|
|
12
|
+
maskContainerStyle
|
|
13
|
+
}: MaskProps) => {
|
|
14
|
+
return (
|
|
15
|
+
<View style={[styles.maskContainer, maskContainerStyle]} pointerEvents={'none'}>
|
|
16
|
+
<LinearGradient colors={['rgba(255,255,255,1)', 'rgba(255,255,255,0.5)']} style={{ flex: 1 }} />
|
|
17
|
+
<View style={{ height: itemHeight }} />
|
|
18
|
+
<LinearGradient colors={['rgba(255,255,255,0.5)', 'rgba(255,255,255,1)']} style={{ flex: 1 }} />
|
|
19
|
+
</View>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
const styles = StyleSheet.create({
|
|
23
|
+
maskContainer: {
|
|
24
|
+
...StyleSheet.absoluteFillObject,
|
|
25
|
+
zIndex: 100
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
_PickerViewMask.displayName = 'MpxPickerViewMask'
|
|
30
|
+
export default _PickerViewMask
|
|
@@ -13,6 +13,8 @@ type RemoveProps = string[];
|
|
|
13
13
|
|
|
14
14
|
type NativeTouchEvent = NativeSyntheticEvent<NativeEvent>
|
|
15
15
|
|
|
16
|
+
type Navigation = Record<string, any>
|
|
17
|
+
|
|
16
18
|
interface NativeEvent {
|
|
17
19
|
timestamp: number;
|
|
18
20
|
pageX: number;
|
|
@@ -36,10 +38,6 @@ interface InnerRef {
|
|
|
36
38
|
bubble: null | ReturnType<typeof setTimeout>;
|
|
37
39
|
capture: null | ReturnType<typeof setTimeout>;
|
|
38
40
|
};
|
|
39
|
-
needPress: {
|
|
40
|
-
bubble: boolean;
|
|
41
|
-
capture: boolean;
|
|
42
|
-
};
|
|
43
41
|
mpxPressInfo: {
|
|
44
42
|
detail: {
|
|
45
43
|
x: number;
|
|
@@ -65,5 +63,6 @@ export {
|
|
|
65
63
|
InnerRef,
|
|
66
64
|
LayoutRef,
|
|
67
65
|
SetTimeoutReturnType,
|
|
68
|
-
DataSetType
|
|
66
|
+
DataSetType,
|
|
67
|
+
Navigation
|
|
69
68
|
}
|
|
@@ -20,6 +20,12 @@ declare module '@mpxjs/utils' {
|
|
|
20
20
|
left: number
|
|
21
21
|
right: number
|
|
22
22
|
},
|
|
23
|
+
layout: {
|
|
24
|
+
x: number
|
|
25
|
+
y: number
|
|
26
|
+
width: number
|
|
27
|
+
height: number
|
|
28
|
+
},
|
|
23
29
|
setOptions: (params: Record<string, any>) => void
|
|
24
30
|
} | undefined
|
|
25
31
|
}
|
|
@@ -27,3 +33,7 @@ declare module '@mpxjs/utils' {
|
|
|
27
33
|
declare let global: {
|
|
28
34
|
__formatValue (value: string): string | number
|
|
29
35
|
} & Record<string, any>
|
|
36
|
+
|
|
37
|
+
declare module '@react-navigation/native' {
|
|
38
|
+
export function useNavigation (): Record<string, any>
|
|
39
|
+
}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
WithTimingConfig,
|
|
14
14
|
AnimationCallback
|
|
15
15
|
} from 'react-native-reanimated'
|
|
16
|
+
import { error } from '@mpxjs/utils'
|
|
16
17
|
import { ExtendedViewStyle } from './types/common'
|
|
17
18
|
import type { _ViewProps } from './mpx-view'
|
|
18
19
|
|
|
@@ -166,20 +167,32 @@ const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
|
|
|
166
167
|
})
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
170
|
-
const { style = {}, animation } = props
|
|
170
|
+
export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean }) {
|
|
171
|
+
const { style = {}, animation, enableAnimation } = props
|
|
172
|
+
|
|
173
|
+
const enableStyleAnimation = enableAnimation || !!animation
|
|
174
|
+
const enableAnimationRef = useRef(enableStyleAnimation)
|
|
175
|
+
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
176
|
+
error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!enableAnimationRef.current) return { enableStyleAnimation: false }
|
|
180
|
+
|
|
171
181
|
const originalStyle = formatStyle(style)
|
|
172
182
|
// id 标识
|
|
173
183
|
const id = animation?.id || -1
|
|
174
184
|
// 有动画样式的 style key
|
|
185
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
175
186
|
const animatedStyleKeys = useSharedValue([] as (string|string[])[])
|
|
176
187
|
// 记录动画key的style样式值 没有的话设置为false
|
|
188
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
177
189
|
const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean})
|
|
178
190
|
// const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
|
|
179
191
|
// ** 全量 style prop sharedValue
|
|
180
192
|
// 不能做增量的原因:
|
|
181
193
|
// 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
|
|
182
194
|
// 2 尝试用 useSharedValue,因为实际触发的 style prop 需要是 sharedValue 才能驱动动画,若外层 shareValMap 也是 sharedValue,动画无法驱动。
|
|
195
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
183
196
|
const shareValMap = useMemo(() => {
|
|
184
197
|
return Object.keys(InitialValue).reduce((valMap, key) => {
|
|
185
198
|
const defaultVal = getInitialVal(key, isTransform(key))
|
|
@@ -188,6 +201,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
188
201
|
}, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
|
|
189
202
|
}, [])
|
|
190
203
|
// ** 获取动画样式prop & 驱动动画
|
|
204
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
191
205
|
useEffect(() => {
|
|
192
206
|
if (id === -1) return
|
|
193
207
|
// 更新动画样式 key map
|
|
@@ -208,6 +222,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
208
222
|
// })
|
|
209
223
|
// }, [style])
|
|
210
224
|
// ** 清空动画
|
|
225
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
211
226
|
useEffect(() => {
|
|
212
227
|
return () => {
|
|
213
228
|
Object.values(shareValMap).forEach((value) => {
|
|
@@ -335,7 +350,8 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
335
350
|
}, {} as { [propName: string]: string | number })
|
|
336
351
|
}
|
|
337
352
|
// ** 生成动画样式
|
|
338
|
-
|
|
353
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
354
|
+
const animationStyle = useAnimatedStyle(() => {
|
|
339
355
|
// console.info(`useAnimatedStyle styles=`, originalStyle)
|
|
340
356
|
return animatedStyleKeys.value.reduce((styles, key) => {
|
|
341
357
|
// console.info('getAnimationStyles', key, shareValMap[key].value)
|
|
@@ -353,4 +369,9 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
353
369
|
return styles
|
|
354
370
|
}, {} as ExtendedViewStyle)
|
|
355
371
|
})
|
|
372
|
+
|
|
373
|
+
return {
|
|
374
|
+
enableStyleAnimation: enableAnimationRef.current,
|
|
375
|
+
animationStyle
|
|
376
|
+
}
|
|
356
377
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
|
|
2
|
-
import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
|
|
3
|
-
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn
|
|
4
|
-
import { VarContext } from './context'
|
|
2
|
+
import { LayoutChangeEvent, TextStyle, ImageProps, Image, Platform } from 'react-native'
|
|
3
|
+
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils'
|
|
4
|
+
import { VarContext, ScrollViewContext } from './context'
|
|
5
5
|
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
|
|
6
6
|
import { initialWindowMetrics } from 'react-native-safe-area-context'
|
|
7
|
+
import { useNavigation } from '@react-navigation/native'
|
|
7
8
|
import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
|
|
8
|
-
import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
|
|
9
|
+
import type { AnyFunc, ExtendedFunctionComponent, ExtendedViewStyle } from './types/common'
|
|
10
|
+
import { runOnJS } from 'react-native-reanimated'
|
|
11
|
+
import { Gesture } from 'react-native-gesture-handler'
|
|
9
12
|
|
|
10
13
|
export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
|
|
11
14
|
export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
|
|
@@ -18,6 +21,11 @@ export const HIDDEN_STYLE = {
|
|
|
18
21
|
opacity: 0
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
declare const __mpx_mode__: 'ios' | 'android'
|
|
25
|
+
|
|
26
|
+
export const isIOS = __mpx_mode__ === 'ios'
|
|
27
|
+
export const isAndroid = __mpx_mode__ === 'android'
|
|
28
|
+
|
|
21
29
|
const varDecRegExp = /^--/
|
|
22
30
|
const varUseRegExp = /var\(/
|
|
23
31
|
const unoVarDecRegExp = /^--un-/
|
|
@@ -32,8 +40,7 @@ const safeAreaInsetMap: Record<string, 'top' | 'right' | 'bottom' | 'left'> = {
|
|
|
32
40
|
'safe-area-inset-left': 'left'
|
|
33
41
|
}
|
|
34
42
|
|
|
35
|
-
function getSafeAreaInset (name: string) {
|
|
36
|
-
const navigation = getFocusedNavigation()
|
|
43
|
+
function getSafeAreaInset (name: string, navigation: Record<string, any>) {
|
|
37
44
|
const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets)
|
|
38
45
|
return insets[safeAreaInsetMap[name]]
|
|
39
46
|
}
|
|
@@ -232,7 +239,7 @@ function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<s
|
|
|
232
239
|
})
|
|
233
240
|
}
|
|
234
241
|
|
|
235
|
-
function transformEnv (styleObj: Record<string, any>, envKeyPaths: Array<Array<string
|
|
242
|
+
function transformEnv (styleObj: Record<string, any>, envKeyPaths: Array<Array<string>>, navigation: Record<string, any>) {
|
|
236
243
|
envKeyPaths.forEach((envKeyPath) => {
|
|
237
244
|
setStyle(styleObj, envKeyPath, ({ target, key, value }) => {
|
|
238
245
|
const parsed = parseFunc(value, 'env')
|
|
@@ -240,7 +247,7 @@ function transformEnv (styleObj: Record<string, any>, envKeyPaths: Array<Array<s
|
|
|
240
247
|
parsed.forEach(({ start, end, args }) => {
|
|
241
248
|
const name = args[0]
|
|
242
249
|
const fallback = args[1] || ''
|
|
243
|
-
const value = '' + (getSafeAreaInset(name) ?? global.__formatValue(fallback))
|
|
250
|
+
const value = '' + (getSafeAreaInset(name, navigation) ?? global.__formatValue(fallback))
|
|
244
251
|
replaced.replace(start, end - 1, value)
|
|
245
252
|
})
|
|
246
253
|
target[key] = global.__formatValue(replaced.source())
|
|
@@ -302,6 +309,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
|
|
|
302
309
|
const envKeyPaths: Array<Array<string>> = []
|
|
303
310
|
const [width, setWidth] = useState(0)
|
|
304
311
|
const [height, setHeight] = useState(0)
|
|
312
|
+
const navigation = useNavigation()
|
|
305
313
|
|
|
306
314
|
function varVisitor ({ key, value, keyPath }: VisitorArg) {
|
|
307
315
|
if (keyPath.length === 1) {
|
|
@@ -396,7 +404,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
|
|
|
396
404
|
}
|
|
397
405
|
|
|
398
406
|
// apply env
|
|
399
|
-
transformEnv(normalStyle, envKeyPaths)
|
|
407
|
+
transformEnv(normalStyle, envKeyPaths, navigation)
|
|
400
408
|
// apply percent
|
|
401
409
|
transformPercent(normalStyle, percentKeyPaths, percentConfig)
|
|
402
410
|
// apply calc
|
|
@@ -565,13 +573,14 @@ export const debounce = <T extends AnyFunc> (
|
|
|
565
573
|
): ((...args: Parameters<T>) => void) & { clear: () => void } => {
|
|
566
574
|
let timer: any
|
|
567
575
|
const wrapper = (...args: ReadonlyArray<any>) => {
|
|
568
|
-
clearTimeout(timer)
|
|
576
|
+
timer && clearTimeout(timer)
|
|
569
577
|
timer = setTimeout(() => {
|
|
570
578
|
func(...args)
|
|
571
579
|
}, delay)
|
|
572
580
|
}
|
|
573
581
|
wrapper.clear = () => {
|
|
574
|
-
clearTimeout(timer)
|
|
582
|
+
timer && clearTimeout(timer)
|
|
583
|
+
timer = null
|
|
575
584
|
}
|
|
576
585
|
return wrapper
|
|
577
586
|
}
|
|
@@ -595,7 +604,7 @@ export const useStableCallback = <T extends AnyFunc | null | undefined> (
|
|
|
595
604
|
)
|
|
596
605
|
}
|
|
597
606
|
|
|
598
|
-
export
|
|
607
|
+
export function usePrevious<T> (value: T): T | undefined {
|
|
599
608
|
const ref = useRef<T | undefined>()
|
|
600
609
|
const prev = ref.current
|
|
601
610
|
ref.current = value
|
|
@@ -641,3 +650,67 @@ export function pickStyle (styleObj: Record<string, any> = {}, pickedKeys: Array
|
|
|
641
650
|
return acc
|
|
642
651
|
}, {})
|
|
643
652
|
}
|
|
653
|
+
|
|
654
|
+
export function useHover ({ enableHover, hoverStartTime, hoverStayTime, disabled } : { enableHover: boolean, hoverStartTime: number, hoverStayTime: number, disabled?: boolean }) {
|
|
655
|
+
const enableHoverRef = useRef(enableHover)
|
|
656
|
+
if (enableHoverRef.current !== enableHover) {
|
|
657
|
+
error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.')
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
if (!enableHoverRef.current) return { isHover: false }
|
|
661
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
662
|
+
const gestureRef = useContext(ScrollViewContext).gestureRef
|
|
663
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
664
|
+
const [isHover, setIsHover] = useState(false)
|
|
665
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
666
|
+
const dataRef = useRef<{
|
|
667
|
+
startTimer?: ReturnType<typeof setTimeout>
|
|
668
|
+
stayTimer?: ReturnType<typeof setTimeout>
|
|
669
|
+
}>({})
|
|
670
|
+
|
|
671
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
672
|
+
useEffect(() => {
|
|
673
|
+
return () => {
|
|
674
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
675
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
676
|
+
}
|
|
677
|
+
}, [])
|
|
678
|
+
|
|
679
|
+
const setStartTimer = () => {
|
|
680
|
+
if (disabled) return
|
|
681
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
682
|
+
dataRef.current.startTimer = setTimeout(() => {
|
|
683
|
+
setIsHover(true)
|
|
684
|
+
}, +hoverStartTime)
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const setStayTimer = () => {
|
|
688
|
+
if (disabled) return
|
|
689
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
690
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
691
|
+
dataRef.current.stayTimer = setTimeout(() => {
|
|
692
|
+
setIsHover(false)
|
|
693
|
+
}, +hoverStayTime)
|
|
694
|
+
}
|
|
695
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
696
|
+
const gesture = useMemo(() => {
|
|
697
|
+
return Gesture.Pan()
|
|
698
|
+
.onTouchesDown(() => {
|
|
699
|
+
'worklet'
|
|
700
|
+
runOnJS(setStartTimer)()
|
|
701
|
+
})
|
|
702
|
+
.onTouchesUp(() => {
|
|
703
|
+
'worklet'
|
|
704
|
+
runOnJS(setStayTimer)()
|
|
705
|
+
})
|
|
706
|
+
}, [])
|
|
707
|
+
|
|
708
|
+
if (gestureRef) {
|
|
709
|
+
gesture.simultaneousWithExternalGesture(gestureRef)
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return {
|
|
713
|
+
isHover,
|
|
714
|
+
gesture
|
|
715
|
+
}
|
|
716
|
+
}
|
|
@@ -40,14 +40,14 @@ export default {
|
|
|
40
40
|
this.wheels[0].wheelTo(newVal[0])
|
|
41
41
|
})
|
|
42
42
|
}
|
|
43
|
-
}
|
|
43
|
+
},
|
|
44
44
|
},
|
|
45
45
|
mounted () {
|
|
46
46
|
this.wheels = []
|
|
47
47
|
this.refresh()
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
},
|
|
49
|
+
updated () {
|
|
50
|
+
this.refresh()
|
|
51
51
|
},
|
|
52
52
|
beforeDestroy () {
|
|
53
53
|
this.wheels.forEach((wheel) => {
|
|
@@ -58,11 +58,16 @@ export default {
|
|
|
58
58
|
methods: {
|
|
59
59
|
refresh () {
|
|
60
60
|
if (this.refreshing) return
|
|
61
|
+
|
|
61
62
|
this.refreshing = true
|
|
63
|
+
for (let i = 0; i < this.$refs.wheelScroll.children.length; i++) {
|
|
64
|
+
this.$refs.wheelScroll.children[i].style.height = `${this.$parent.$refs.indicatorMask.offsetHeight}px`
|
|
65
|
+
}
|
|
62
66
|
this.$nextTick(() => {
|
|
63
67
|
const wheelWrapper = this.$refs.wheelWrapper
|
|
64
68
|
if (this.wheels[0]) {
|
|
65
69
|
this.wheels[0].refresh()
|
|
70
|
+
this.refreshing = false
|
|
66
71
|
return
|
|
67
72
|
}
|
|
68
73
|
this.wheels[0] = new BScroll(wheelWrapper, extend({
|