@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.
Files changed (60) hide show
  1. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  2. package/lib/platform/template/wx/component-config/picker-view.js +1 -5
  3. package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
  4. package/lib/platform/template/wx/index.js +0 -4
  5. package/lib/runtime/components/react/context.ts +8 -0
  6. package/lib/runtime/components/react/dist/context.js +2 -0
  7. package/lib/runtime/components/react/dist/getInnerListeners.js +34 -31
  8. package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
  9. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +93 -58
  10. package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
  11. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +35 -0
  12. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +151 -127
  13. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +38 -34
  14. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
  15. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +11 -4
  16. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +31 -8
  17. package/lib/runtime/components/react/dist/mpx-swiper.jsx +670 -0
  18. package/lib/runtime/components/react/dist/mpx-view.jsx +15 -53
  19. package/lib/runtime/components/react/dist/pickerFaces.js +7 -6
  20. package/lib/runtime/components/react/dist/pickerVIewContext.js +14 -0
  21. package/lib/runtime/components/react/dist/pickerViewIndicator.jsx +23 -0
  22. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  23. package/lib/runtime/components/react/dist/useAnimationHooks.js +20 -2
  24. package/lib/runtime/components/react/dist/utils.jsx +74 -11
  25. package/lib/runtime/components/react/getInnerListeners.ts +43 -32
  26. package/lib/runtime/components/react/mpx-button.tsx +20 -57
  27. package/lib/runtime/components/react/mpx-movable-view.tsx +119 -74
  28. package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
  29. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +76 -0
  30. package/lib/runtime/components/react/mpx-picker-view-column.tsx +206 -183
  31. package/lib/runtime/components/react/mpx-picker-view.tsx +49 -48
  32. package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
  33. package/lib/runtime/components/react/mpx-scroll-view.tsx +21 -10
  34. package/lib/runtime/components/react/mpx-swiper-item.tsx +45 -11
  35. package/lib/runtime/components/react/mpx-swiper.tsx +742 -0
  36. package/lib/runtime/components/react/mpx-view.tsx +18 -65
  37. package/lib/runtime/components/react/pickerFaces.ts +10 -7
  38. package/lib/runtime/components/react/pickerVIewContext.ts +27 -0
  39. package/lib/runtime/components/react/pickerViewIndicator.tsx +34 -0
  40. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  41. package/lib/runtime/components/react/types/{getInnerListeners.ts → getInnerListeners.d.ts} +4 -5
  42. package/lib/runtime/components/react/types/global.d.ts +10 -0
  43. package/lib/runtime/components/react/useAnimationHooks.ts +24 -3
  44. package/lib/runtime/components/react/utils.tsx +85 -12
  45. package/lib/runtime/components/web/mpx-checkbox.vue +1 -1
  46. package/lib/runtime/components/web/mpx-picker-view-column.vue +9 -4
  47. package/lib/template-compiler/compiler.js +61 -13
  48. package/lib/wxss/loader.js +15 -2
  49. package/package.json +3 -3
  50. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -480
  51. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  52. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  53. package/lib/runtime/components/react/dist/pickerOverlay.jsx +0 -21
  54. package/lib/runtime/components/react/dist/types/common.js +0 -1
  55. package/lib/runtime/components/react/dist/types/getInnerListeners.js +0 -1
  56. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
  57. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  58. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
  59. package/lib/runtime/components/react/pickerOverlay.tsx +0 -32
  60. /package/lib/runtime/components/react/types/{common.ts → common.d.ts} +0 -0
@@ -2,6 +2,8 @@ const TAG_NAME = 'movable-view'
2
2
 
3
3
  module.exports = function ({ print }) {
4
4
  const aliEventLog = print({ platform: 'ali', tag: TAG_NAME, isError: false, type: 'event' })
5
+ const androidEventLog = print({ platform: 'android', tag: TAG_NAME, isError: false, type: 'event' })
6
+ const iosEventLog = print({ platform: 'ios', tag: TAG_NAME, isError: false, type: 'event' })
5
7
  const qaPropLog = print({ platform: 'qa', tag: TAG_NAME, isError: false })
6
8
  const androidPropLog = print({ platform: 'android', tag: TAG_NAME, isError: false })
7
9
  const iosPropLog = print({ platform: 'ios', tag: TAG_NAME, isError: false })
@@ -27,7 +29,7 @@ module.exports = function ({ print }) {
27
29
  android: androidPropLog
28
30
  },
29
31
  {
30
- test: /^(inertia|damping|animation)$/,
32
+ test: /^(damping|friction|scale|scale-min|scale-max|scale-value)$/,
31
33
  ios: iosPropLog,
32
34
  android: androidPropLog
33
35
  }
@@ -36,6 +38,11 @@ module.exports = function ({ print }) {
36
38
  {
37
39
  test: /^(htouchmove|vtouchmove)$/,
38
40
  ali: aliEventLog
41
+ },
42
+ {
43
+ test: /^(bindscale)$/,
44
+ ios: iosEventLog,
45
+ android: androidEventLog
39
46
  }
40
47
  ]
41
48
  }
@@ -6,9 +6,7 @@ module.exports = function ({ print }) {
6
6
  const ttPropLog = print({ platform: 'bytedance', tag: TAG_NAME, isError: false })
7
7
  const ttEventLog = print({ platform: 'bytedance', tag: TAG_NAME, isError: false, type: 'event' })
8
8
  const jdEventLog = print({ platform: 'jd', tag: TAG_NAME, isError: false, type: 'event' })
9
- const iosPropLog = print({ platform: 'ios', tag: TAG_NAME, isError: false })
10
9
  const iosEventLog = print({ platform: 'ios', tag: TAG_NAME, isError: false, type: 'event' })
11
- const androidPropLog = print({ platform: 'android', tag: TAG_NAME, isError: false })
12
10
  const androidEventLog = print({ platform: 'android', tag: TAG_NAME, isError: false, type: 'event' })
13
11
 
14
12
  return {
@@ -28,9 +26,7 @@ module.exports = function ({ print }) {
28
26
  props: [
29
27
  {
30
28
  test: /^(indicator-class|mask-class)$/,
31
- tt: ttPropLog,
32
- ios: iosPropLog,
33
- android: androidPropLog
29
+ tt: ttPropLog
34
30
  }
35
31
  ],
36
32
  event: [
@@ -53,7 +53,7 @@ module.exports = function ({ print }) {
53
53
  qa: qaPropLog
54
54
  },
55
55
  {
56
- test: /^(scroll-into-view|refresher-threshold|enable-passive|scroll-anchoring|using-sticky|fast-deceleration|enable-flex)$/,
56
+ test: /^(refresher-threshold|enable-passive|scroll-anchoring|using-sticky|fast-deceleration|enable-flex)$/,
57
57
  android: androidPropLog,
58
58
  ios: iosPropLog
59
59
  },
@@ -384,10 +384,6 @@ module.exports = function getSpec ({ warn, error }) {
384
384
  }
385
385
  },
386
386
  web ({ name, value }, { eventRules, el, usingComponents }) {
387
- const parsed = parseMustacheWithContext(value)
388
- if (parsed.hasBinding) {
389
- value = '__invokeHandler(' + parsed.result + ', $event)'
390
- }
391
387
  const match = this.test.exec(name)
392
388
  const prefix = match[1]
393
389
  const eventName = match[2]
@@ -33,6 +33,10 @@ export interface IntersectionObserver {
33
33
  }
34
34
  }
35
35
 
36
+ export interface ScrollViewContextValue {
37
+ gestureRef: React.RefObject<any> | null
38
+ }
39
+
36
40
  export const MovableAreaContext = createContext({ width: 0, height: 0 })
37
41
 
38
42
  export const FormContext = createContext<FormContextValue | null>(null)
@@ -51,4 +55,8 @@ export const IntersectionObserverContext = createContext<IntersectionObserver |
51
55
 
52
56
  export const RouteContext = createContext<number | null>(null)
53
57
 
58
+ export const SwiperContext = createContext({})
59
+
54
60
  export const KeyboardAvoidContext = createContext<KeyboardAvoidContextValue | null>(null)
61
+
62
+ export const ScrollViewContext = createContext<ScrollViewContextValue>({ gestureRef: null })
@@ -8,4 +8,6 @@ export const PickerContext = createContext(null);
8
8
  export const VarContext = createContext({});
9
9
  export const IntersectionObserverContext = createContext(null);
10
10
  export const RouteContext = createContext(null);
11
+ export const SwiperContext = createContext({});
11
12
  export const KeyboardAvoidContext = createContext(null);
13
+ export const ScrollViewContext = createContext({ gestureRef: null });
@@ -1,8 +1,13 @@
1
1
  import { useRef, useMemo } from 'react';
2
2
  import { hasOwn, collectDataset } from '@mpxjs/utils';
3
+ import { useNavigation } from '@react-navigation/native';
3
4
  import { omit, extendObject } from './utils';
4
5
  import eventConfigMap from './event.config';
5
- const getTouchEvent = (type, event, props, config) => {
6
+ const globalEventState = {
7
+ needPress: true
8
+ };
9
+ const getTouchEvent = (type, event, props, config, navigation) => {
10
+ const { y: navigationY = 0 } = navigation?.layout || {};
6
11
  const nativeEvent = event.nativeEvent;
7
12
  const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent;
8
13
  const { id } = props;
@@ -25,24 +30,24 @@ const getTouchEvent = (type, event, props, config) => {
25
30
  target,
26
31
  detail: {
27
32
  x: pageX,
28
- y: pageY
33
+ y: pageY - navigationY
29
34
  },
30
35
  touches: touches.map((item) => {
31
36
  return {
32
37
  identifier: item.identifier,
33
38
  pageX: item.pageX,
34
- pageY: item.pageY,
35
- clientX: item.locationX,
36
- clientY: item.locationY
39
+ pageY: item.pageY - navigationY,
40
+ clientX: item.pageX,
41
+ clientY: item.pageY - navigationY
37
42
  };
38
43
  }),
39
44
  changedTouches: changedTouches.map((item) => {
40
45
  return {
41
46
  identifier: item.identifier,
42
47
  pageX: item.pageX,
43
- pageY: item.pageY,
44
- clientX: item.locationX,
45
- clientY: item.locationY
48
+ pageY: item.pageY - navigationY,
49
+ clientX: item.pageX,
50
+ clientY: item.pageY - navigationY
46
51
  };
47
52
  }),
48
53
  persist: event.persist,
@@ -66,14 +71,14 @@ export const getCustomEvent = (type = '', oe = {}, { detail = {}, layoutRef }, p
66
71
  preventDefault: oe.preventDefault
67
72
  });
68
73
  };
69
- function handleEmitEvent(events, type, oe, propsRef, config) {
74
+ function handleEmitEvent(events, type, oe, propsRef, config, navigation) {
70
75
  events.forEach((event) => {
71
76
  if (propsRef.current[event]) {
72
77
  const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event);
73
78
  if (match) {
74
79
  oe.stopPropagation();
75
80
  }
76
- propsRef.current[event](getTouchEvent(type, oe, propsRef.current, config));
81
+ propsRef.current[event](getTouchEvent(type, oe, propsRef.current, config, navigation));
77
82
  }
78
83
  });
79
84
  }
@@ -84,13 +89,13 @@ function checkIsNeedPress(e, type, ref) {
84
89
  const currentPageY = nativeEvent.changedTouches[0].pageY;
85
90
  if (Math.abs(currentPageX - tapDetailInfo.x) > 3 ||
86
91
  Math.abs(currentPageY - tapDetailInfo.y) > 3) {
87
- ref.current.needPress[type] = false;
92
+ globalEventState.needPress = false;
88
93
  ref.current.startTimer[type] &&
89
94
  clearTimeout(ref.current.startTimer[type]);
90
95
  ref.current.startTimer[type] = null;
91
96
  }
92
97
  }
93
- function handleTouchstart(e, type, ref, propsRef, config) {
98
+ function handleTouchstart(e, type, ref, propsRef, config, navigation) {
94
99
  e.persist();
95
100
  const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart'];
96
101
  const bubblePressEvent = ['catchlongpress', 'bindlongpress'];
@@ -103,7 +108,7 @@ function handleTouchstart(e, type, ref, propsRef, config) {
103
108
  'capture-bindlongpress'
104
109
  ];
105
110
  ref.current.startTimer[type] = null;
106
- ref.current.needPress[type] = true;
111
+ globalEventState.needPress = true;
107
112
  const nativeEvent = e.nativeEvent;
108
113
  ref.current.mpxPressInfo.detail = {
109
114
  x: nativeEvent.changedTouches[0].pageX,
@@ -111,29 +116,30 @@ function handleTouchstart(e, type, ref, propsRef, config) {
111
116
  };
112
117
  const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
113
118
  const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent;
114
- handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config);
119
+ handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigation);
115
120
  const { catchlongpress, bindlongpress, 'capture-catchlongpress': captureCatchlongpress, 'capture-bindlongpress': captureBindlongpress } = propsRef.current;
116
121
  if (catchlongpress ||
117
122
  bindlongpress ||
118
123
  captureCatchlongpress ||
119
124
  captureBindlongpress) {
120
125
  ref.current.startTimer[type] = setTimeout(() => {
121
- ref.current.needPress[type] = false;
122
- handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config);
126
+ // 只要触发过longpress, 全局就不再触发tap
127
+ globalEventState.needPress = false;
128
+ handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigation);
123
129
  }, 350);
124
130
  }
125
131
  }
126
- function handleTouchmove(e, type, ref, propsRef, config) {
132
+ function handleTouchmove(e, type, ref, propsRef, config, navigation) {
127
133
  const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove'];
128
134
  const captureTouchEvent = [
129
135
  'capture-catchtouchmove',
130
136
  'capture-bindtouchmove'
131
137
  ];
132
138
  const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
133
- handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config);
139
+ handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigation);
134
140
  checkIsNeedPress(e, type, ref);
135
141
  }
136
- function handleTouchend(e, type, ref, propsRef, config) {
142
+ function handleTouchend(e, type, ref, propsRef, config, navigation) {
137
143
  // move event may not be triggered
138
144
  checkIsNeedPress(e, type, ref);
139
145
  const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'];
@@ -148,15 +154,15 @@ function handleTouchend(e, type, ref, propsRef, config) {
148
154
  ref.current.startTimer[type] &&
149
155
  clearTimeout(ref.current.startTimer[type]);
150
156
  ref.current.startTimer[type] = null;
151
- handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config);
152
- if (ref.current.needPress[type]) {
157
+ handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation);
158
+ if (globalEventState.needPress) {
153
159
  if (type === 'bubble' && config.disableTap) {
154
160
  return;
155
161
  }
156
- handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config);
162
+ handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation);
157
163
  }
158
164
  }
159
- function handleTouchcancel(e, type, ref, propsRef, config) {
165
+ function handleTouchcancel(e, type, ref, propsRef, config, navigation) {
160
166
  const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'];
161
167
  const captureTouchEvent = [
162
168
  'capture-catchtouchcancel',
@@ -166,10 +172,10 @@ function handleTouchcancel(e, type, ref, propsRef, config) {
166
172
  ref.current.startTimer[type] &&
167
173
  clearTimeout(ref.current.startTimer[type]);
168
174
  ref.current.startTimer[type] = null;
169
- handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config);
175
+ handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation);
170
176
  }
171
177
  function createTouchEventHandler(eventName, type) {
172
- return (e, ref, propsRef, config) => {
178
+ return (e, ref, propsRef, config, navigation) => {
173
179
  const handlerMap = {
174
180
  onTouchStart: handleTouchstart,
175
181
  onTouchMove: handleTouchmove,
@@ -178,7 +184,7 @@ function createTouchEventHandler(eventName, type) {
178
184
  };
179
185
  const handler = handlerMap[eventName];
180
186
  if (handler) {
181
- handler(e, type, ref, propsRef, config);
187
+ handler(e, type, ref, propsRef, config, navigation);
182
188
  }
183
189
  };
184
190
  }
@@ -198,10 +204,6 @@ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], r
198
204
  bubble: null,
199
205
  capture: null
200
206
  },
201
- needPress: {
202
- bubble: false,
203
- capture: false
204
- },
205
207
  mpxPressInfo: {
206
208
  detail: {
207
209
  x: 0,
@@ -215,6 +217,7 @@ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], r
215
217
  layoutRef: { current: {} },
216
218
  disableTap: false
217
219
  };
220
+ const navigation = useNavigation();
218
221
  const removeProps = [
219
222
  'children',
220
223
  'enable-background',
@@ -250,7 +253,7 @@ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], r
250
253
  const events = {};
251
254
  touchEventList.forEach((item) => {
252
255
  if (finalEventKeys.includes(item.eventName)) {
253
- events[item.eventName] = (e) => item.handler(e, ref, propsRef, config);
256
+ events[item.eventName] = (e) => item.handler(e, ref, propsRef, config, navigation);
254
257
  }
255
258
  });
256
259
  return events;
@@ -34,10 +34,11 @@
34
34
  * ✘ bindagreeprivacyauthorization
35
35
  * ✔ bindtap
36
36
  */
37
- import { createElement, useEffect, useRef, useState, forwardRef, useContext } from 'react';
37
+ import { createElement, useEffect, useRef, forwardRef, useContext } from 'react';
38
38
  import { View, StyleSheet, Animated, Easing } from 'react-native';
39
39
  import { warn } from '@mpxjs/utils';
40
- import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
40
+ import { GestureDetector } from 'react-native-gesture-handler';
41
+ import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover } from './utils';
41
42
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
42
43
  import useNodesRef from './useNodesRef';
43
44
  import { RouteContext, FormContext } from './context';
@@ -128,38 +129,34 @@ const Loading = ({ alone = false }) => {
128
129
  };
129
130
  const Button = forwardRef((buttonProps, ref) => {
130
131
  const { textProps, innerProps: props = {} } = splitProps(buttonProps);
131
- const { size = 'default', type = 'default', plain = false, disabled = false, loading = false, 'hover-class': hoverClass, 'hover-style': hoverStyle = {}, 'hover-start-time': hoverStartTime = 20, 'hover-stay-time': hoverStayTime = 70, 'open-type': openType, 'form-type': formType, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, style = {}, children, bindgetuserinfo, bindtap, bindtouchstart, bindtouchend } = props;
132
+ const { size = 'default', type = 'default', plain = false, disabled = false, loading = false, 'hover-class': hoverClass, 'hover-style': hoverStyle = {}, 'hover-start-time': hoverStartTime = 20, 'hover-stay-time': hoverStayTime = 70, 'open-type': openType, 'form-type': formType, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, style = {}, children, bindgetuserinfo, bindtap } = props;
132
133
  const pageId = useContext(RouteContext);
133
134
  const formContext = useContext(FormContext);
135
+ const enableHover = hoverClass !== 'none';
136
+ const { isHover, gesture } = useHover({ enableHover, hoverStartTime, hoverStayTime, disabled });
134
137
  let submitFn;
135
138
  let resetFn;
136
139
  if (formContext) {
137
140
  submitFn = formContext.submit;
138
141
  resetFn = formContext.reset;
139
142
  }
140
- const refs = useRef({
141
- hoverStartTimer: undefined,
142
- hoverStayTimer: undefined
143
- });
144
- const [isHover, setIsHover] = useState(false);
145
143
  const isMiniSize = size === 'mini';
146
- const applyHoverEffect = isHover && hoverClass !== 'none';
147
144
  const [color, hoverColor, plainColor, disabledColor] = TypeColorMap[type];
148
- const normalBackgroundColor = disabled ? disabledColor : applyHoverEffect || loading ? hoverColor : color;
145
+ const normalBackgroundColor = disabled ? disabledColor : isHover || loading ? hoverColor : color;
149
146
  const plainBorderColor = disabled
150
147
  ? 'rgba(0, 0, 0, .2)'
151
- : applyHoverEffect
148
+ : isHover
152
149
  ? `rgba(${plainColor},.6)`
153
150
  : `rgb(${plainColor})`;
154
151
  const normalBorderColor = type === 'default' ? 'rgba(0, 0, 0, .2)' : normalBackgroundColor;
155
152
  const plainTextColor = disabled
156
153
  ? 'rgba(0, 0, 0, .2)'
157
- : applyHoverEffect
154
+ : isHover
158
155
  ? `rgba(${plainColor}, .6)`
159
156
  : `rgb(${plainColor})`;
160
157
  const normalTextColor = type === 'default'
161
- ? `rgba(0, 0, 0, ${disabled ? 0.3 : applyHoverEffect || loading ? 0.6 : 1})`
162
- : `rgba(255 ,255 ,255 , ${disabled || applyHoverEffect || loading ? 0.6 : 1})`;
158
+ ? `rgba(0, 0, 0, ${disabled ? 0.3 : isHover || loading ? 0.6 : 1})`
159
+ : `rgba(255 ,255 ,255 , ${disabled || isHover || loading ? 0.6 : 1})`;
163
160
  const viewStyle = {
164
161
  borderWidth: 1,
165
162
  borderStyle: 'solid',
@@ -169,7 +166,7 @@ const Button = forwardRef((buttonProps, ref) => {
169
166
  const defaultViewStyle = extendObject({}, styles.button, isMiniSize ? styles.buttonMini : null, viewStyle);
170
167
  const defaultTextStyle = extendObject({}, styles.text, isMiniSize ? styles.textMini : {}, { color: plain ? plainTextColor : normalTextColor });
171
168
  const defaultStyle = extendObject({}, defaultViewStyle, defaultTextStyle);
172
- const styleObj = extendObject({}, defaultStyle, style, applyHoverEffect ? hoverStyle : {});
169
+ const styleObj = extendObject({}, defaultStyle, style, isHover ? hoverStyle : {});
173
170
  const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
174
171
  const nodeRef = useRef(null);
175
172
  useNodesRef(props, ref, nodeRef, { style: normalStyle });
@@ -224,32 +221,6 @@ const Button = forwardRef((buttonProps, ref) => {
224
221
  });
225
222
  }
226
223
  };
227
- const setStayTimer = () => {
228
- clearTimeout(refs.current.hoverStayTimer);
229
- refs.current.hoverStayTimer = setTimeout(() => {
230
- setIsHover(false);
231
- clearTimeout(refs.current.hoverStayTimer);
232
- }, hoverStayTime);
233
- };
234
- const setStartTimer = () => {
235
- clearTimeout(refs.current.hoverStartTimer);
236
- refs.current.hoverStartTimer = setTimeout(() => {
237
- setIsHover(true);
238
- clearTimeout(refs.current.hoverStartTimer);
239
- }, hoverStartTime);
240
- };
241
- const onTouchStart = (evt) => {
242
- bindtouchstart && bindtouchstart(evt);
243
- if (disabled)
244
- return;
245
- setStartTimer();
246
- };
247
- const onTouchEnd = (evt) => {
248
- bindtouchend && bindtouchend(evt);
249
- if (disabled)
250
- return;
251
- setStayTimer();
252
- };
253
224
  const handleFormTypeFn = () => {
254
225
  if (formType === 'submit') {
255
226
  submitFn && submitFn();
@@ -269,8 +240,6 @@ const Button = forwardRef((buttonProps, ref) => {
269
240
  ref: nodeRef,
270
241
  style: extendObject({}, innerStyle, layoutStyle)
271
242
  }, layoutProps, {
272
- bindtouchstart: (bindtouchstart || !disabled) && onTouchStart,
273
- bindtouchend: (bindtouchend || !disabled) && onTouchEnd,
274
243
  bindtap: !disabled && onTap
275
244
  }), [
276
245
  'disabled',
@@ -288,12 +257,15 @@ const Button = forwardRef((buttonProps, ref) => {
288
257
  layoutRef,
289
258
  disableTap: disabled
290
259
  });
291
- return createElement(View, innerProps, loading && createElement(Loading, { alone: !children }), wrapChildren(props, {
260
+ const baseButton = createElement(View, innerProps, loading && createElement(Loading, { alone: !children }), wrapChildren(props, {
292
261
  hasVarDec,
293
262
  varContext: varContextRef.current,
294
263
  textStyle,
295
264
  textProps
296
265
  }));
266
+ return enableHover
267
+ ? createElement(GestureDetector, { gesture: gesture }, baseButton)
268
+ : baseButton;
297
269
  });
298
270
  Button.displayName = 'MpxButton';
299
271
  export default Button;
@@ -11,7 +11,7 @@
11
11
  * ✘ scale-min
12
12
  * ✘ scale-max
13
13
  * ✘ scale-value
14
- * animation
14
+ * animation
15
15
  * ✔ bindchange
16
16
  * ✘ bindscale
17
17
  * ✔ htouchmove
@@ -19,12 +19,13 @@
19
19
  */
20
20
  import { useEffect, forwardRef, useContext, useCallback, useRef, useMemo, createElement } from 'react';
21
21
  import { StyleSheet } from 'react-native';
22
- import { getCustomEvent } from './getInnerListeners';
22
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
23
23
  import useNodesRef from './useNodesRef';
24
24
  import { MovableAreaContext } from './context';
25
- import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject } from './utils';
25
+ import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject, omit } from './utils';
26
26
  import { GestureDetector, Gesture } from 'react-native-gesture-handler';
27
27
  import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, useAnimatedReaction, withSpring } from 'react-native-reanimated';
28
+ import { collectDataset, noop } from '@mpxjs/utils';
28
29
  const styles = StyleSheet.create({
29
30
  container: {
30
31
  position: 'absolute',
@@ -233,8 +234,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
233
234
  });
234
235
  props.onLayout && props.onLayout(e);
235
236
  };
236
- const extendEvent = useCallback((e) => {
237
- 'worklet';
237
+ const extendEvent = useCallback((e, obj) => {
238
238
  const touchArr = [e.changedTouches, e.allTouches];
239
239
  touchArr.forEach(touches => {
240
240
  touches && touches.forEach((item) => {
@@ -242,45 +242,65 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
242
242
  item.pageY = item.absoluteY;
243
243
  });
244
244
  });
245
- e.touches = e.allTouches;
245
+ Object.assign(e, {
246
+ touches: e.allTouches,
247
+ detail: {
248
+ x: e.changedTouches[0].absoluteX,
249
+ y: e.changedTouches[0].absoluteY
250
+ },
251
+ currentTarget: {
252
+ id: props.id || '',
253
+ dataset: collectDataset(props),
254
+ offsetLeft: 0,
255
+ offsetTop: 0
256
+ }
257
+ }, obj);
246
258
  }, []);
259
+ const triggerStartOnJS = ({ e }) => {
260
+ extendEvent(e);
261
+ bindtouchstart && bindtouchstart(e);
262
+ catchtouchstart && catchtouchstart(e);
263
+ };
264
+ const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }) => {
265
+ extendEvent(e);
266
+ if (hasTouchmove) {
267
+ if (touchEvent === 'htouchmove') {
268
+ bindhtouchmove && bindhtouchmove(e);
269
+ }
270
+ else if (touchEvent === 'vtouchmove') {
271
+ bindvtouchmove && bindvtouchmove(e);
272
+ }
273
+ bindtouchmove && bindtouchmove(e);
274
+ }
275
+ if (hasCatchTouchmove) {
276
+ if (touchEvent === 'htouchmove') {
277
+ catchhtouchmove && catchhtouchmove(e);
278
+ }
279
+ else if (touchEvent === 'vtouchmove') {
280
+ catchvtouchmove && catchvtouchmove(e);
281
+ }
282
+ catchtouchmove && catchtouchmove(e);
283
+ }
284
+ };
285
+ const triggerEndOnJS = ({ e }) => {
286
+ extendEvent(e);
287
+ bindtouchend && bindtouchend(e);
288
+ catchtouchend && catchtouchend(e);
289
+ };
247
290
  const gesture = useMemo(() => {
248
- const handleTriggerStart = (e) => {
249
- 'worklet';
250
- extendEvent(e);
251
- bindtouchstart && runOnJS(bindtouchstart)(e);
252
- catchtouchstart && runOnJS(catchtouchstart)(e);
253
- };
254
291
  const handleTriggerMove = (e) => {
255
292
  'worklet';
256
- extendEvent(e);
257
293
  const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove;
258
294
  const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove;
259
- if (hasTouchmove) {
260
- if (touchEvent.value === 'htouchmove') {
261
- bindhtouchmove && runOnJS(bindhtouchmove)(e);
262
- }
263
- else if (touchEvent.value === 'vtouchmove') {
264
- bindvtouchmove && runOnJS(bindvtouchmove)(e);
265
- }
266
- bindtouchmove && runOnJS(bindtouchmove)(e);
267
- }
268
- if (hasCatchTouchmove) {
269
- if (touchEvent.value === 'htouchmove') {
270
- catchhtouchmove && runOnJS(catchhtouchmove)(e);
271
- }
272
- else if (touchEvent.value === 'vtouchmove') {
273
- catchvtouchmove && runOnJS(catchvtouchmove)(e);
274
- }
275
- catchtouchmove && runOnJS(catchtouchmove)(e);
295
+ if (hasTouchmove || hasCatchTouchmove) {
296
+ runOnJS(triggerMoveOnJS)({
297
+ e,
298
+ touchEvent: touchEvent.value,
299
+ hasTouchmove,
300
+ hasCatchTouchmove
301
+ });
276
302
  }
277
303
  };
278
- const handleTriggerEnd = (e) => {
279
- 'worklet';
280
- extendEvent(e);
281
- bindtouchend && runOnJS(bindtouchend)(e);
282
- catchtouchend && runOnJS(catchtouchend)(e);
283
- };
284
304
  const gesturePan = Gesture.Pan()
285
305
  .onTouchesDown((e) => {
286
306
  'worklet';
@@ -290,12 +310,14 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
290
310
  x: changedTouches.x,
291
311
  y: changedTouches.y
292
312
  };
293
- handleTriggerStart(e);
313
+ if (bindtouchstart || catchtouchstart) {
314
+ runOnJS(triggerStartOnJS)({ e });
315
+ }
294
316
  })
295
317
  .onTouchesMove((e) => {
296
318
  'worklet';
297
- isMoving.value = true;
298
319
  const changedTouches = e.changedTouches[0] || { x: 0, y: 0 };
320
+ isMoving.value = true;
299
321
  if (isFirstTouch.value) {
300
322
  touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove';
301
323
  isFirstTouch.value = false;
@@ -330,7 +352,9 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
330
352
  'worklet';
331
353
  isFirstTouch.value = true;
332
354
  isMoving.value = false;
333
- handleTriggerEnd(e);
355
+ if (bindtouchend || catchtouchend) {
356
+ runOnJS(triggerEndOnJS)({ e });
357
+ }
334
358
  if (disabled)
335
359
  return;
336
360
  if (!inertia) {
@@ -355,9 +379,9 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
355
379
  })
356
380
  .onFinalize((e) => {
357
381
  'worklet';
382
+ isMoving.value = false;
358
383
  if (!inertia || disabled || !animation)
359
384
  return;
360
- isMoving.value = false;
361
385
  if (direction === 'horizontal' || direction === 'all') {
362
386
  xInertialMotion.value = true;
363
387
  offsetX.value = withDecay({
@@ -396,31 +420,42 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
396
420
  ]
397
421
  };
398
422
  });
399
- const injectCatchEvent = (props) => {
400
- const eventHandlers = {};
401
- const catchEventList = [
402
- { name: 'onTouchStart', value: ['catchtouchstart'] },
403
- { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] },
404
- { name: 'onTouchEnd', value: ['catchtouchend'] }
423
+ const rewriteCatchEvent = () => {
424
+ const handlers = {};
425
+ const events = [
426
+ { type: 'touchstart' },
427
+ { type: 'touchmove', alias: ['vtouchmove', 'htouchmove'] },
428
+ { type: 'touchend' }
405
429
  ];
406
- catchEventList.forEach(event => {
407
- event.value.forEach(name => {
408
- if (props[name] && !eventHandlers[event.name]) {
409
- eventHandlers[event.name] = (e) => {
410
- e.stopPropagation();
411
- };
412
- }
413
- });
430
+ events.forEach(({ type, alias = [] }) => {
431
+ const hasCatchEvent = props[`catch${type}`] ||
432
+ alias.some(name => props[`catch${name}`]);
433
+ if (hasCatchEvent)
434
+ handlers[`catch${type}`] = noop;
414
435
  });
415
- return eventHandlers;
436
+ return handlers;
416
437
  };
417
- const catchEventHandlers = injectCatchEvent(props);
418
438
  const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {};
419
- return createElement(GestureDetector, { gesture: gesture }, createElement(Animated.View, extendObject({
439
+ // bind 相关 touch 事件直接由 gesture 触发,无须重复挂载
440
+ // catch 相关 touch 事件需要重写并通过 useInnerProps 注入阻止冒泡逻辑
441
+ const filterProps = omit(props, [
442
+ 'bindtouchstart',
443
+ 'bindtouchmove',
444
+ 'bindvtouchmove',
445
+ 'bindhtouchmove',
446
+ 'bindtouchend',
447
+ 'catchtouchstart',
448
+ 'catchtouchmove',
449
+ 'catchvtouchmove',
450
+ 'catchhtouchmove',
451
+ 'catchtouchend'
452
+ ]);
453
+ const innerProps = useInnerProps(filterProps, extendObject({
420
454
  ref: nodeRef,
421
455
  onLayout: onLayout,
422
456
  style: [innerStyle, animatedStyles, layoutStyle]
423
- }, catchEventHandlers), wrapChildren(props, {
457
+ }, rewriteCatchEvent()));
458
+ return createElement(GestureDetector, { gesture: gesture }, createElement(Animated.View, innerProps, wrapChildren(props, {
424
459
  hasVarDec,
425
460
  varContext: varContextRef.current,
426
461
  textStyle,
@@ -3,7 +3,7 @@ import useInnerProps from './getInnerListeners';
3
3
  import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
4
4
  import MpxView from './mpx-view';
5
5
  const _Navigator = forwardRef((props, ref) => {
6
- const { children, 'open-type': openType, url, delta } = props;
6
+ const { children, 'open-type': openType, url = '', delta } = props;
7
7
  const handleClick = useCallback(() => {
8
8
  switch (openType) {
9
9
  case 'navigateBack':