@mpxjs/webpack-plugin 2.9.69-beta.0 → 2.9.69-beta.2

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.
Files changed (50) hide show
  1. package/lib/index.js +17 -1
  2. package/lib/platform/style/wx/index.js +18 -18
  3. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  4. package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
  5. package/lib/resolver/AddEnvPlugin.js +1 -0
  6. package/lib/resolver/AddModePlugin.js +1 -0
  7. package/lib/runtime/components/react/context.ts +8 -0
  8. package/lib/runtime/components/react/dist/context.js +2 -0
  9. package/lib/runtime/components/react/dist/getInnerListeners.js +3 -4
  10. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
  11. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
  12. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +1 -1
  13. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +54 -52
  14. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +1 -1
  15. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
  16. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +21 -6
  17. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +25 -8
  18. package/lib/runtime/components/react/dist/mpx-swiper.jsx +150 -148
  19. package/lib/runtime/components/react/dist/mpx-view.jsx +9 -40
  20. package/lib/runtime/components/react/dist/mpx-web-view.jsx +50 -12
  21. package/lib/runtime/components/react/dist/pickerFaces.js +1 -1
  22. package/lib/runtime/components/react/dist/useAnimationHooks.js +1 -1
  23. package/lib/runtime/components/react/dist/utils.jsx +63 -4
  24. package/lib/runtime/components/react/getInnerListeners.ts +3 -5
  25. package/lib/runtime/components/react/mpx-input.tsx +1 -1
  26. package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
  27. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
  28. package/lib/runtime/components/react/mpx-picker-view-column.tsx +177 -159
  29. package/lib/runtime/components/react/mpx-picker-view.tsx +35 -37
  30. package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
  31. package/lib/runtime/components/react/mpx-scroll-view.tsx +30 -13
  32. package/lib/runtime/components/react/mpx-swiper-item.tsx +38 -10
  33. package/lib/runtime/components/react/mpx-swiper.tsx +690 -0
  34. package/lib/runtime/components/react/mpx-view.tsx +11 -51
  35. package/lib/runtime/components/react/mpx-web-view.tsx +57 -13
  36. package/lib/runtime/components/react/pickerFaces.ts +15 -7
  37. package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
  38. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  39. package/lib/runtime/components/react/{pickerOverlay.tsx → pickerViewOverlay.tsx} +5 -3
  40. package/lib/runtime/components/react/types/global.d.ts +3 -1
  41. package/lib/runtime/components/react/useAnimationHooks.ts +1 -1
  42. package/lib/runtime/components/react/utils.tsx +75 -5
  43. package/lib/style-compiler/index.js +3 -4
  44. package/lib/style-compiler/strip-conditional-loader.js +118 -0
  45. package/lib/template-compiler/compiler.js +9 -14
  46. package/lib/utils/pre-process-json.js +5 -9
  47. package/package.json +1 -1
  48. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
  49. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  50. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
@@ -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, useHoverStyle } from './utils'
16
16
  import { error } from '@mpxjs/utils'
17
17
  import LinearGradient from 'react-native-linear-gradient'
18
+ import { GestureDetector } from 'react-native-gesture-handler'
18
19
 
19
20
  export interface _ViewProps extends ViewProps {
20
21
  style?: ExtendedViewStyle
@@ -683,8 +684,6 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
683
684
  animation
684
685
  } = props
685
686
 
686
- const [isHover, setIsHover] = useState(false)
687
-
688
687
  // 默认样式
689
688
  const defaultStyle: ExtendedViewStyle = style.display === 'flex'
690
689
  ? {
@@ -695,6 +694,8 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
695
694
  }
696
695
  : {}
697
696
 
697
+ const { isHover, enableHoverStyle, gesture } = useHoverStyle({ hoverStyle, hoverStartTime, hoverStayTime })
698
+
698
699
  const styleObj: ExtendedViewStyle = extendObject({}, defaultStyle, style, isHover ? hoverStyle as ExtendedViewStyle : {})
699
700
 
700
701
  const {
@@ -725,45 +726,6 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
725
726
  style: normalStyle
726
727
  })
727
728
 
728
- const dataRef = useRef<{
729
- startTimer?: ReturnType<typeof setTimeout>
730
- stayTimer?: ReturnType<typeof setTimeout>
731
- }>({})
732
-
733
- useEffect(() => {
734
- return () => {
735
- dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
736
- dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
737
- }
738
- }, [])
739
-
740
- const setStartTimer = () => {
741
- dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
742
- dataRef.current.startTimer = setTimeout(() => {
743
- setIsHover(true)
744
- }, +hoverStartTime)
745
- }
746
-
747
- const setStayTimer = () => {
748
- dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
749
- dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
750
- dataRef.current.stayTimer = setTimeout(() => {
751
- setIsHover(false)
752
- }, +hoverStayTime)
753
- }
754
-
755
- function onTouchStart (e: NativeSyntheticEvent<TouchEvent>) {
756
- const { bindtouchstart } = props
757
- bindtouchstart && bindtouchstart(e)
758
- setStartTimer()
759
- }
760
-
761
- function onTouchEnd (e: NativeSyntheticEvent<TouchEvent>) {
762
- const { bindtouchend } = props
763
- bindtouchend && bindtouchend(e)
764
- setStayTimer()
765
- }
766
-
767
729
  const {
768
730
  layoutRef,
769
731
  layoutStyle,
@@ -789,13 +751,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
789
751
  ref: nodeRef,
790
752
  style: finalStyle
791
753
  },
792
- layoutProps,
793
- hoverStyle
794
- ? {
795
- bindtouchstart: onTouchStart,
796
- bindtouchend: onTouchEnd
797
- }
798
- : {}
754
+ layoutProps
799
755
  ), [
800
756
  'hover-start-time',
801
757
  'hover-stay-time',
@@ -816,9 +772,13 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
816
772
  enableFastImage
817
773
  })
818
774
 
819
- return enableAnimation
820
- ? createElement(Animated.View, innerProps, childNode)
775
+ const BaseComponent = enableAnimation
776
+ ? createElement(Animated.View, extendObject({}, innerProps, { style: finalStyle }), childNode)
821
777
  : createElement(View, innerProps, childNode)
778
+
779
+ return enableHoverStyle
780
+ ? createElement(GestureDetector, { gesture }, BaseComponent)
781
+ : BaseComponent
822
782
  })
823
783
 
824
784
  _View.displayName = 'MpxView'
@@ -1,4 +1,4 @@
1
- import { forwardRef, JSX, useRef, useContext, useMemo, createElement } from 'react'
1
+ import { forwardRef, JSX, useRef, useContext, useMemo, createElement, useCallback, useEffect } from 'react'
2
2
  import { warn, getFocusedNavigation, isFunction } from '@mpxjs/utils'
3
3
  import { Portal } from '@ant-design/react-native'
4
4
  import { getCustomEvent } from './getInnerListeners'
@@ -6,8 +6,9 @@ import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab }
6
6
  import { WebView } from 'react-native-webview'
7
7
  import useNodesRef, { HandlerRef } from './useNodesRef'
8
8
  import { getCurrentPage, extendObject } from './utils'
9
- import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent, WebViewNavigation } from 'react-native-webview/lib/WebViewTypes'
9
+ import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent, WebViewNavigation, WebViewProgressEvent } from 'react-native-webview/lib/WebViewTypes'
10
10
  import { RouteContext } from './context'
11
+ import { BackHandler } from 'react-native'
11
12
 
12
13
  type OnMessageCallbackEvent = {
13
14
  detail: {
@@ -56,6 +57,35 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
56
57
  top: 0 as number,
57
58
  bottom: 0 as number
58
59
  }
60
+ const canGoBack = useRef<boolean>(false)
61
+
62
+ const onAndroidBackPress = useCallback(() => {
63
+ if (canGoBack.current) {
64
+ webViewRef.current?.goBack()
65
+ return true
66
+ }
67
+ return false
68
+ }, [canGoBack])
69
+
70
+ const beforeRemoveHandle = useCallback((e: Event) => {
71
+ if (canGoBack.current) {
72
+ webViewRef.current?.goBack()
73
+ e.preventDefault()
74
+ }
75
+ }, [canGoBack])
76
+
77
+ const navigation = getFocusedNavigation()
78
+
79
+ navigation?.addListener('beforeRemove', beforeRemoveHandle)
80
+
81
+ useEffect(() => {
82
+ if (__mpx_mode__ === 'android') {
83
+ BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress)
84
+ return () => {
85
+ BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress)
86
+ }
87
+ }
88
+ }, [])
59
89
 
60
90
  useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
61
91
  style: defaultWebViewStyle
@@ -73,7 +103,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
73
103
  src: res.nativeEvent?.url
74
104
  }
75
105
  }
76
- bindload(result)
106
+ bindload?.(result)
77
107
  }
78
108
  const _error = function (res: WebViewErrorEvent) {
79
109
  const result = {
@@ -83,7 +113,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
83
113
  src: ''
84
114
  }
85
115
  }
86
- binderror(result)
116
+ binderror?.(result)
87
117
  }
88
118
  const injectedJavaScript = `
89
119
  if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
@@ -109,12 +139,26 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
109
139
  }
110
140
  });
111
141
  }
142
+ true;
112
143
  `
144
+ const sendMessage = function (params: string) {
145
+ return `
146
+ window.mpxWebviewMessageCallback(${params})
147
+ true;
148
+ `
149
+ }
113
150
  const _changeUrl = function (navState: WebViewNavigation) {
114
151
  if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
152
+ canGoBack.current = navState.canGoBack
115
153
  currentPage.__webViewUrl = navState.url
116
154
  }
117
155
  }
156
+
157
+ const _onLoadProgress = function (event: WebViewProgressEvent) {
158
+ if (__mpx_mode__ === 'android') {
159
+ canGoBack.current = event.nativeEvent.canGoBack
160
+ }
161
+ }
118
162
  const _message = function (res: WebViewMessageEvent) {
119
163
  let data: MessageData = {}
120
164
  let asyncCallback
@@ -134,7 +178,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
134
178
  { // case下不允许直接声明,包个块解决该问题
135
179
  const title = postData._documentTitle
136
180
  if (title) {
137
- const navigation = getFocusedNavigation()
138
181
  navigation && navigation.setOptions({ title })
139
182
  }
140
183
  }
@@ -181,21 +224,21 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
181
224
 
182
225
  asyncCallback && asyncCallback.then((res: any) => {
183
226
  if (webViewRef.current?.postMessage) {
184
- const test = JSON.stringify({
227
+ const result = JSON.stringify({
185
228
  type,
186
229
  callbackId: data.callbackId,
187
230
  result: res
188
231
  })
189
- webViewRef.current.postMessage(test)
232
+ webViewRef.current.injectJavaScript(sendMessage(result))
190
233
  }
191
234
  }).catch((error: any) => {
192
235
  if (webViewRef.current?.postMessage) {
193
- const test = JSON.stringify({
236
+ const result = JSON.stringify({
194
237
  type,
195
238
  callbackId: data.callbackId,
196
239
  error
197
240
  })
198
- webViewRef.current.postMessage(test)
241
+ webViewRef.current.injectJavaScript(sendMessage(result))
199
242
  }
200
243
  })
201
244
  }
@@ -211,16 +254,17 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
211
254
  onError: _error
212
255
  })
213
256
  }
214
- extendObject(events, {
215
- onMessage: _message
216
- })
217
257
 
218
258
  return createElement(Portal, null, createElement(WebView, extendObject({
219
259
  style: defaultWebViewStyle,
220
260
  source: { uri: src },
221
261
  ref: webViewRef,
222
262
  javaScriptEnabled: true,
223
- onNavigationStateChange: _changeUrl
263
+ onNavigationStateChange: _changeUrl,
264
+ onMessage: _message,
265
+ injectedJavaScript: injectedJavaScript,
266
+ onLoadProgress: _onLoadProgress,
267
+ allowsBackForwardNavigationGestures: true
224
268
  }, events)))
225
269
  })
226
270
 
@@ -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
  }
@@ -54,6 +55,9 @@ export const createFaces = (
54
55
  for (let i = 0; i < index; i++) {
55
56
  offset += freeSpaces[i]
56
57
  }
58
+ if (index === 0) {
59
+ offset *= 0.6
60
+ }
57
61
  return offset
58
62
  }) as unknown as T
59
63
  return [screenHeights, offsets]
@@ -62,17 +66,19 @@ export const createFaces = (
62
66
  const getOpacity = (index: number) => {
63
67
  const map: Record<number, number> = {
64
68
  0: 0,
65
- 1: 0.2,
66
- 2: 0.35,
67
- 3: 0.45,
68
- 4: 0.5
69
+ 1: 0.8,
70
+ 2: 0.9 // 0.35
71
+ // 3: 0.45, // 0.45
72
+ // 4: 0.5 // 0.5
69
73
  }
70
- return map[index] ?? Math.min(1, map[4] + index * 0.5)
74
+ return map[index] ?? Math.min(1, map[2] + index * 0.05)
71
75
  }
72
76
 
73
77
  const degrees = getDegreesRelativeCenter()
74
78
  const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees)
75
79
 
80
+ const scales = [1, 0.925, 0.8]
81
+
76
82
  return [
77
83
  // top items
78
84
  ...degrees
@@ -82,13 +88,14 @@ export const createFaces = (
82
88
  deg: degree,
83
89
  opacity: getOpacity(degrees.length - 1 - index),
84
90
  offsetY: -1 * offsets[index],
91
+ scale: scales[index],
85
92
  screenHeight: screenHeight[index]
86
93
  }
87
94
  })
88
95
  .reverse(),
89
96
 
90
97
  // center item
91
- { index: 0, deg: 0, opacity: 1, offsetY: 0, screenHeight: itemHeight },
98
+ { index: 0, deg: 0, opacity: 1, offsetY: 0, scale: 1, screenHeight: itemHeight },
92
99
 
93
100
  // bottom items
94
101
  ...degrees.map<Faces>((degree, index) => {
@@ -97,6 +104,7 @@ export const createFaces = (
97
104
  deg: -1 * degree,
98
105
  opacity: getOpacity(degrees.length - 1 - index),
99
106
  offsetY: offsets[index],
107
+ scale: scales[index],
100
108
  screenHeight: screenHeight[index]
101
109
  }
102
110
  })
@@ -0,0 +1,18 @@
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
+ }
@@ -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 OverlayProps = {
6
+ itemHeight: number
7
+ maskContainerStyle?: StyleProp<ViewStyle>
8
+ }
9
+
10
+ const _PickerViewMask = ({
11
+ itemHeight,
12
+ maskContainerStyle
13
+ }: OverlayProps) => {
14
+ return (
15
+ <View style={[styles.overlayContainer, 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
+ overlayContainer: {
24
+ ...StyleSheet.absoluteFillObject,
25
+ zIndex: 100
26
+ }
27
+ })
28
+
29
+ _PickerViewMask.displayName = 'MpxPickerViewMask'
30
+ export default _PickerViewMask
@@ -7,7 +7,7 @@ type OverlayProps = {
7
7
  overlayContainerStyle?: StyleProp<ViewStyle>
8
8
  }
9
9
 
10
- const Overlay = ({ itemHeight, overlayItemStyle, overlayContainerStyle }: OverlayProps) => {
10
+ const _PickerViewOverlay = ({ itemHeight, overlayItemStyle, overlayContainerStyle }: OverlayProps) => {
11
11
  return (
12
12
  <View style={[styles.overlayContainer, overlayContainerStyle]} pointerEvents={'none'}>
13
13
  <View style={[styles.selection, { height: itemHeight }, overlayItemStyle]} />
@@ -19,7 +19,8 @@ const styles = StyleSheet.create({
19
19
  overlayContainer: {
20
20
  ...StyleSheet.absoluteFillObject,
21
21
  justifyContent: 'center',
22
- alignItems: 'center'
22
+ alignItems: 'center',
23
+ zIndex: 200
23
24
  },
24
25
  selection: {
25
26
  borderTopWidth: 1,
@@ -29,4 +30,5 @@ const styles = StyleSheet.create({
29
30
  }
30
31
  })
31
32
 
32
- export default React.memo(Overlay)
33
+ _PickerViewOverlay.displayName = 'MpxPickerViewOverlay'
34
+ export default _PickerViewOverlay
@@ -1,3 +1,4 @@
1
+ declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | 'qa' | 'jd' | 'android' | 'ios'
1
2
  declare module '@mpxjs/utils' {
2
3
  export function isEmptyObject (obj: Object): boolean
3
4
  export function isFunction (fn: unknown): boolean
@@ -20,7 +21,8 @@ declare module '@mpxjs/utils' {
20
21
  left: number
21
22
  right: number
22
23
  },
23
- setOptions: (params: Record<string, any>) => void
24
+ setOptions: (params: Record<string, any>) => void,
25
+ addListener: (eventName: string, callback: (e: Event) => void) => void
24
26
  } | undefined
25
27
  }
26
28
 
@@ -110,7 +110,7 @@ const parseTransform = (transformStr: string) => {
110
110
  const values = parseValues(transformStr)
111
111
  const transform: {[propName: string]: string|number|number[]}[] = []
112
112
  values.forEach(item => {
113
- const match = item.match(/([/\w]+)\(([^)]+)\)/)
113
+ const match = item.match(/([/\w]+)\((.+)\)/)
114
114
  if (match && match.length >= 3) {
115
115
  let key = match[1]
116
116
  const val = match[2]
@@ -1,11 +1,13 @@
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'
2
+ import { LayoutChangeEvent, TextStyle, ImageProps, Image, Platform } from 'react-native'
3
3
  import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
4
- import { VarContext } from './context'
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
7
  import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
8
- import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
8
+ import type { AnyFunc, ExtendedFunctionComponent, ExtendedViewStyle } from './types/common'
9
+ import { runOnJS } from 'react-native-reanimated'
10
+ import { Gesture } from 'react-native-gesture-handler'
9
11
 
10
12
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
11
13
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
@@ -18,6 +20,9 @@ export const HIDDEN_STYLE = {
18
20
  opacity: 0
19
21
  }
20
22
 
23
+ export const isIOS = Platform.OS === 'ios'
24
+ export const isAndroid = Platform.OS === 'android'
25
+
21
26
  const varDecRegExp = /^--.*/
22
27
  const varUseRegExp = /var\(/
23
28
  const calcUseRegExp = /calc\(/
@@ -497,6 +502,7 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
497
502
  props.onLayout && props.onLayout(e)
498
503
  }
499
504
  }
505
+
500
506
  return {
501
507
  layoutRef,
502
508
  layoutStyle,
@@ -534,13 +540,14 @@ export const debounce = <T extends AnyFunc> (
534
540
  ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
535
541
  let timer: any
536
542
  const wrapper = (...args: ReadonlyArray<any>) => {
537
- clearTimeout(timer)
543
+ timer && clearTimeout(timer)
538
544
  timer = setTimeout(() => {
539
545
  func(...args)
540
546
  }, delay)
541
547
  }
542
548
  wrapper.clear = () => {
543
- clearTimeout(timer)
549
+ timer && clearTimeout(timer)
550
+ timer = null
544
551
  }
545
552
  return wrapper
546
553
  }
@@ -610,3 +617,66 @@ export function pickStyle (styleObj: Record<string, any> = {}, pickedKeys: Array
610
617
  return acc
611
618
  }, {})
612
619
  }
620
+
621
+ export function useHoverStyle ({ hoverStyle, hoverStartTime, hoverStayTime, disabled } : { hoverStyle?: ExtendedViewStyle, hoverStartTime: number, hoverStayTime: number, disabled?: boolean }) {
622
+ const enableHoverStyle = !!hoverStyle
623
+ const enableHoverStyleRef = useRef(enableHoverStyle)
624
+ if (enableHoverStyleRef.current !== enableHoverStyle) {
625
+ throw new Error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.')
626
+ }
627
+
628
+ if (!enableHoverStyle) return { enableHoverStyle }
629
+
630
+ const gestureRef = useContext(ScrollViewContext).gestureRef
631
+ const [isHover, setIsHover] = useState(false)
632
+ const dataRef = useRef<{
633
+ startTimer?: ReturnType<typeof setTimeout>
634
+ stayTimer?: ReturnType<typeof setTimeout>
635
+ }>({})
636
+
637
+ useEffect(() => {
638
+ return () => {
639
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
640
+ dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
641
+ }
642
+ }, [])
643
+
644
+ const setStartTimer = () => {
645
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
646
+ dataRef.current.startTimer = setTimeout(() => {
647
+ setIsHover(true)
648
+ }, +hoverStartTime)
649
+ }
650
+
651
+ const setStayTimer = () => {
652
+ dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
653
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
654
+ dataRef.current.stayTimer = setTimeout(() => {
655
+ setIsHover(false)
656
+ }, +hoverStayTime)
657
+ }
658
+
659
+ const gesture = useMemo(() => {
660
+ return Gesture.Pan()
661
+ .onTouchesDown(() => {
662
+ 'worklet'
663
+ if (disabled) return
664
+ runOnJS(setStartTimer)()
665
+ })
666
+ .onTouchesUp(() => {
667
+ 'worklet'
668
+ if (disabled) return
669
+ runOnJS(setStayTimer)()
670
+ })
671
+ }, [disabled])
672
+
673
+ if (gestureRef) {
674
+ gesture.simultaneousWithExternalGesture(gestureRef)
675
+ }
676
+
677
+ return {
678
+ isHover,
679
+ gesture,
680
+ enableHoverStyle
681
+ }
682
+ }
@@ -4,7 +4,6 @@ const loadPostcssConfig = require('./load-postcss-config')
4
4
  const { MPX_ROOT_VIEW, MPX_DISABLE_EXTRACTOR_CACHE } = require('../utils/const')
5
5
  const rpx = require('./plugins/rpx')
6
6
  const vw = require('./plugins/vw')
7
- const pluginCondStrip = require('./plugins/conditional-strip')
8
7
  const scopeId = require('./plugins/scope-id')
9
8
  const transSpecial = require('./plugins/trans-special')
10
9
  const cssArrayList = require('./plugins/css-array-list')
@@ -58,9 +57,9 @@ module.exports = function (css, map) {
58
57
  plugins.push(transSpecial({ id }))
59
58
  }
60
59
 
61
- plugins.push(pluginCondStrip({
62
- defs
63
- }))
60
+ // plugins.push(pluginCondStrip({
61
+ // defs
62
+ // }))
64
63
 
65
64
  for (const item of transRpxRules) {
66
65
  const {