@mpxjs/webpack-plugin 2.9.70-alpha.0 → 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 (126) hide show
  1. package/LICENSE +433 -0
  2. package/README.md +1 -1
  3. package/lib/config.js +0 -14
  4. package/lib/dependencies/ResolveDependency.js +0 -5
  5. package/lib/index.js +7 -38
  6. package/lib/json-compiler/helper.js +3 -3
  7. package/lib/loader.js +0 -53
  8. package/lib/parser.js +1 -1
  9. package/lib/platform/json/wx/index.js +21 -8
  10. package/lib/platform/style/wx/index.js +51 -54
  11. package/lib/platform/template/wx/component-config/button.js +2 -14
  12. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  13. package/lib/platform/template/wx/component-config/image.js +0 -4
  14. package/lib/platform/template/wx/component-config/index.js +1 -1
  15. package/lib/platform/template/wx/component-config/input.js +0 -4
  16. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  17. package/lib/platform/template/wx/component-config/picker-view.js +1 -5
  18. package/lib/platform/template/wx/component-config/rich-text.js +6 -2
  19. package/lib/platform/template/wx/component-config/scroll-view.js +1 -5
  20. package/lib/platform/template/wx/component-config/switch.js +0 -4
  21. package/lib/platform/template/wx/component-config/text.js +0 -4
  22. package/lib/platform/template/wx/component-config/textarea.js +0 -5
  23. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  24. package/lib/platform/template/wx/component-config/view.js +0 -4
  25. package/lib/platform/template/wx/index.js +1 -131
  26. package/lib/resolve-loader.js +1 -4
  27. package/lib/runtime/components/react/context.ts +8 -0
  28. package/lib/runtime/components/react/dist/context.js +2 -0
  29. package/lib/runtime/components/react/dist/getInnerListeners.js +39 -37
  30. package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
  31. package/lib/runtime/components/react/dist/mpx-canvas/html.js +2 -4
  32. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +5 -1
  33. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +93 -58
  34. package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
  35. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +10 -14
  36. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +94 -81
  37. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +19 -16
  38. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
  39. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +11 -4
  40. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +31 -8
  41. package/lib/runtime/components/react/dist/mpx-swiper.jsx +435 -371
  42. package/lib/runtime/components/react/dist/mpx-view.jsx +18 -53
  43. package/lib/runtime/components/react/dist/pickerFaces.js +3 -8
  44. package/lib/runtime/components/react/dist/pickerVIewContext.js +5 -0
  45. package/lib/runtime/components/react/dist/{pickerViewOverlay.jsx → pickerViewIndicator.jsx} +6 -6
  46. package/lib/runtime/components/react/dist/pickerViewMask.jsx +2 -2
  47. package/lib/runtime/components/react/dist/useAnimationHooks.js +27 -10
  48. package/lib/runtime/components/react/dist/utils.jsx +162 -70
  49. package/lib/runtime/components/react/event.config.ts +25 -26
  50. package/lib/runtime/components/react/getInnerListeners.ts +236 -182
  51. package/lib/runtime/components/react/mpx-button.tsx +27 -69
  52. package/lib/runtime/components/react/mpx-canvas/html.ts +2 -4
  53. package/lib/runtime/components/react/mpx-canvas/index.tsx +44 -46
  54. package/lib/runtime/components/react/mpx-checkbox-group.tsx +15 -13
  55. package/lib/runtime/components/react/mpx-checkbox.tsx +20 -21
  56. package/lib/runtime/components/react/mpx-form.tsx +15 -20
  57. package/lib/runtime/components/react/mpx-icon.tsx +2 -2
  58. package/lib/runtime/components/react/mpx-image.tsx +87 -47
  59. package/lib/runtime/components/react/mpx-input.tsx +24 -32
  60. package/lib/runtime/components/react/mpx-label.tsx +12 -14
  61. package/lib/runtime/components/react/mpx-movable-area.tsx +10 -16
  62. package/lib/runtime/components/react/mpx-movable-view.tsx +133 -92
  63. package/lib/runtime/components/react/mpx-navigator.tsx +3 -9
  64. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +76 -0
  65. package/lib/runtime/components/react/mpx-picker-view-column.tsx +206 -183
  66. package/lib/runtime/components/react/mpx-picker-view.tsx +49 -48
  67. package/lib/runtime/components/react/mpx-radio-group.tsx +13 -15
  68. package/lib/runtime/components/react/mpx-radio.tsx +19 -25
  69. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  70. package/lib/runtime/components/react/mpx-rich-text/index.tsx +115 -0
  71. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  72. package/lib/runtime/components/react/mpx-scroll-view.tsx +53 -43
  73. package/lib/runtime/components/react/mpx-swiper-item.tsx +45 -11
  74. package/lib/runtime/components/react/mpx-swiper.tsx +742 -0
  75. package/lib/runtime/components/react/mpx-switch.tsx +19 -15
  76. package/lib/runtime/components/react/mpx-text.tsx +8 -16
  77. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  78. package/lib/runtime/components/react/mpx-view.tsx +28 -77
  79. package/lib/runtime/components/react/mpx-web-view.tsx +94 -59
  80. package/lib/runtime/components/react/pickerFaces.ts +10 -7
  81. package/lib/runtime/components/react/pickerVIewContext.ts +27 -0
  82. package/lib/runtime/components/react/pickerViewIndicator.tsx +34 -0
  83. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  84. package/lib/runtime/components/react/types/{getInnerListeners.ts → getInnerListeners.d.ts} +4 -5
  85. package/lib/runtime/components/react/types/global.d.ts +12 -1
  86. package/lib/runtime/components/react/useAnimationHooks.ts +60 -15
  87. package/lib/runtime/components/react/utils.tsx +175 -71
  88. package/lib/runtime/components/web/mpx-checkbox.vue +1 -1
  89. package/lib/runtime/components/web/mpx-picker-view-column.vue +9 -4
  90. package/lib/runtime/components/web/mpx-web-view.vue +34 -20
  91. package/lib/runtime/optionProcessor.js +0 -22
  92. package/lib/style-compiler/index.js +1 -1
  93. package/lib/style-compiler/plugins/scope-id.js +30 -2
  94. package/lib/template-compiler/compiler.js +91 -39
  95. package/lib/utils/env.js +1 -6
  96. package/lib/utils/pre-process-json.js +9 -5
  97. package/lib/wxss/loader.js +15 -2
  98. package/package.json +4 -7
  99. package/lib/dependencies/AddEntryDependency.js +0 -24
  100. package/lib/runtime/components/react/dist/types/common.js +0 -1
  101. package/lib/runtime/components/react/dist/types/getInnerListeners.js +0 -1
  102. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
  103. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  104. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
  105. package/lib/runtime/components/react/pickerOverlay.tsx +0 -32
  106. package/lib/runtime/components/tenon/getInnerListeners.js +0 -334
  107. package/lib/runtime/components/tenon/tenon-button.vue +0 -309
  108. package/lib/runtime/components/tenon/tenon-image.vue +0 -66
  109. package/lib/runtime/components/tenon/tenon-input.vue +0 -171
  110. package/lib/runtime/components/tenon/tenon-rich-text.vue +0 -26
  111. package/lib/runtime/components/tenon/tenon-scroll-view.vue +0 -127
  112. package/lib/runtime/components/tenon/tenon-switch.vue +0 -96
  113. package/lib/runtime/components/tenon/tenon-text.vue +0 -70
  114. package/lib/runtime/components/tenon/tenon-textarea.vue +0 -86
  115. package/lib/runtime/components/tenon/tenon-view.vue +0 -93
  116. package/lib/runtime/components/web/event.js +0 -105
  117. package/lib/runtime/optionProcessor.tenon.js +0 -84
  118. package/lib/style-compiler/plugins/hm.js +0 -20
  119. package/lib/tenon/index.js +0 -117
  120. package/lib/tenon/processJSON.js +0 -352
  121. package/lib/tenon/processScript.js +0 -203
  122. package/lib/tenon/processStyles.js +0 -21
  123. package/lib/tenon/processTemplate.js +0 -126
  124. package/lib/tenon/script-helper.js +0 -223
  125. package/lib/utils/get-relative-path.js +0 -25
  126. /package/lib/runtime/components/react/types/{common.ts → common.d.ts} +0 -0
@@ -1,5 +1,6 @@
1
- import { useRef } from 'react'
1
+ import { useRef, useMemo, RefObject } 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
6
  import {
@@ -10,34 +11,42 @@ import {
10
11
  InnerRef,
11
12
  SetTimeoutReturnType,
12
13
  LayoutRef,
13
- NativeTouchEvent
14
+ NativeTouchEvent,
15
+ Navigation
14
16
  } from './types/getInnerListeners'
15
17
 
18
+ const globalEventState = {
19
+ needPress: true
20
+ }
21
+
16
22
  const getTouchEvent = (
17
23
  type: string,
18
24
  event: NativeTouchEvent,
19
25
  props: Props,
20
- config: UseInnerPropsConfig
26
+ config: UseInnerPropsConfig,
27
+ navigation: Navigation
21
28
  ) => {
29
+ const { y: navigationY = 0 } = navigation?.layout || {}
22
30
  const nativeEvent = event.nativeEvent
23
- const {
24
- timestamp,
25
- pageX,
26
- pageY,
27
- touches,
28
- changedTouches
29
- } = nativeEvent
31
+ const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent
30
32
  const { id } = props
31
33
  const { layoutRef } = config
32
34
 
33
- const currentTarget = extendObject(
35
+ const currentTarget = extendObject({}, event.currentTarget, {
36
+ id: id || '',
37
+ dataset: collectDataset(props),
38
+ offsetLeft: layoutRef?.current?.offsetLeft || 0,
39
+ offsetTop: layoutRef?.current?.offsetTop || 0
40
+ })
41
+
42
+ const pendingProps = (event as any)._targetInst?.pendingProps || {}
43
+
44
+ const target = extendObject(
34
45
  {},
35
- event.currentTarget,
46
+ event.target,
36
47
  {
37
- id: id || '',
38
- dataset: collectDataset(props),
39
- offsetLeft: layoutRef?.current?.offsetLeft || 0,
40
- offsetTop: layoutRef?.current?.offsetTop || 0
48
+ id: pendingProps.parentId || pendingProps.nativeID || '',
49
+ dataset: collectDataset(pendingProps)
41
50
  }
42
51
  )
43
52
 
@@ -45,26 +54,27 @@ const getTouchEvent = (
45
54
  type,
46
55
  timeStamp: timestamp,
47
56
  currentTarget,
57
+ target,
48
58
  detail: {
49
59
  x: pageX,
50
- y: pageY
60
+ y: pageY - navigationY
51
61
  },
52
- touches: touches.map(item => {
62
+ touches: touches.map((item) => {
53
63
  return {
54
64
  identifier: item.identifier,
55
65
  pageX: item.pageX,
56
- pageY: item.pageY,
57
- clientX: item.locationX,
58
- clientY: item.locationY
66
+ pageY: item.pageY - navigationY,
67
+ clientX: item.pageX,
68
+ clientY: item.pageY - navigationY
59
69
  }
60
70
  }),
61
- changedTouches: changedTouches.map(item => {
71
+ changedTouches: changedTouches.map((item) => {
62
72
  return {
63
73
  identifier: item.identifier,
64
74
  pageX: item.pageX,
65
- pageY: item.pageY,
66
- clientX: item.locationX,
67
- clientY: item.locationY
75
+ pageY: item.pageY - navigationY,
76
+ clientX: item.pageX,
77
+ clientY: item.pageY - navigationY
68
78
  }
69
79
  }),
70
80
  persist: event.persist,
@@ -76,7 +86,10 @@ const getTouchEvent = (
76
86
  export const getCustomEvent = (
77
87
  type = '',
78
88
  oe: any = {},
79
- { detail = {}, layoutRef }: { detail?: Record<string, unknown>; layoutRef: LayoutRef },
89
+ {
90
+ detail = {},
91
+ layoutRef
92
+ }: { detail?: Record<string, unknown>; layoutRef?: LayoutRef },
80
93
  props: Props = {}
81
94
  ) => {
82
95
  const targetInfo = extendObject({}, oe.target, {
@@ -95,6 +108,173 @@ export const getCustomEvent = (
95
108
  })
96
109
  }
97
110
 
111
+ function handleEmitEvent (
112
+ events: string[],
113
+ type: string,
114
+ oe: NativeTouchEvent,
115
+ propsRef: Record<string, any>,
116
+ config: UseInnerPropsConfig,
117
+ navigation: Navigation
118
+ ) {
119
+ events.forEach((event) => {
120
+ if (propsRef.current[event]) {
121
+ const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event)
122
+ if (match) {
123
+ oe.stopPropagation()
124
+ }
125
+ propsRef.current[event](
126
+ getTouchEvent(type, oe, propsRef.current, config, navigation)
127
+ )
128
+ }
129
+ })
130
+ }
131
+
132
+ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>) {
133
+ const tapDetailInfo = ref.current!.mpxPressInfo.detail || { x: 0, y: 0 }
134
+ const nativeEvent = e.nativeEvent
135
+ const currentPageX = nativeEvent.changedTouches[0].pageX
136
+ const currentPageY = nativeEvent.changedTouches[0].pageY
137
+ if (
138
+ Math.abs(currentPageX - tapDetailInfo.x) > 3 ||
139
+ Math.abs(currentPageY - tapDetailInfo.y) > 3
140
+ ) {
141
+ globalEventState.needPress = false
142
+ ref.current!.startTimer[type] &&
143
+ clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType)
144
+ ref.current!.startTimer[type] = null
145
+ }
146
+ }
147
+
148
+ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) {
149
+ e.persist()
150
+ const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart']
151
+ const bubblePressEvent = ['catchlongpress', 'bindlongpress']
152
+ const captureTouchEvent = [
153
+ 'capture-catchtouchstart',
154
+ 'capture-bindtouchstart'
155
+ ]
156
+ const capturePressEvent = [
157
+ 'capture-catchlongpress',
158
+ 'capture-bindlongpress'
159
+ ]
160
+ ref.current!.startTimer[type] = null
161
+ globalEventState.needPress = true
162
+ const nativeEvent = e.nativeEvent
163
+ ref.current!.mpxPressInfo.detail = {
164
+ x: nativeEvent.changedTouches[0].pageX,
165
+ y: nativeEvent.changedTouches[0].pageY
166
+ }
167
+ const currentTouchEvent =
168
+ type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
169
+ const currentPressEvent =
170
+ type === 'bubble' ? bubblePressEvent : capturePressEvent
171
+ handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigation)
172
+ const {
173
+ catchlongpress,
174
+ bindlongpress,
175
+ 'capture-catchlongpress': captureCatchlongpress,
176
+ 'capture-bindlongpress': captureBindlongpress
177
+ } = propsRef.current
178
+ if (
179
+ catchlongpress ||
180
+ bindlongpress ||
181
+ captureCatchlongpress ||
182
+ captureBindlongpress
183
+ ) {
184
+ ref.current!.startTimer[type] = setTimeout(() => {
185
+ // 只要触发过longpress, 全局就不再触发tap
186
+ globalEventState.needPress = false
187
+ handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigation)
188
+ }, 350)
189
+ }
190
+ }
191
+
192
+ function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) {
193
+ const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove']
194
+ const captureTouchEvent = [
195
+ 'capture-catchtouchmove',
196
+ 'capture-bindtouchmove'
197
+ ]
198
+ const currentTouchEvent =
199
+ type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
200
+ handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigation)
201
+ checkIsNeedPress(e, type, ref)
202
+ }
203
+
204
+ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) {
205
+ // move event may not be triggered
206
+ checkIsNeedPress(e, type, ref)
207
+ const bubbleTouchEvent = ['catchtouchend', 'bindtouchend']
208
+ const bubbleTapEvent = ['catchtap', 'bindtap']
209
+ const captureTouchEvent = [
210
+ 'capture-catchtouchend',
211
+ 'capture-bindtouchend'
212
+ ]
213
+ const captureTapEvent = ['capture-catchtap', 'capture-bindtap']
214
+ const currentTouchEvent =
215
+ type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
216
+ const currentTapEvent =
217
+ type === 'bubble' ? bubbleTapEvent : captureTapEvent
218
+ ref.current!.startTimer[type] &&
219
+ clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType)
220
+ ref.current!.startTimer[type] = null
221
+ handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation)
222
+ if (globalEventState.needPress) {
223
+ if (type === 'bubble' && config.disableTap) {
224
+ return
225
+ }
226
+ handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation)
227
+ }
228
+ }
229
+
230
+ function handleTouchcancel (
231
+ e: NativeTouchEvent,
232
+ type: 'bubble' | 'capture',
233
+ ref: RefObject<InnerRef>,
234
+ propsRef: Record<string, any>,
235
+ config: UseInnerPropsConfig,
236
+ navigation: Navigation
237
+ ) {
238
+ const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel']
239
+ const captureTouchEvent = [
240
+ 'capture-catchtouchcancel',
241
+ 'capture-bindtouchcancel'
242
+ ]
243
+ const currentTouchEvent =
244
+ type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
245
+ ref.current!.startTimer[type] &&
246
+ clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType)
247
+ ref.current!.startTimer[type] = null
248
+ handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation)
249
+ }
250
+
251
+ function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTouchEnd'|'onTouchCancel', type: 'bubble' | 'capture') {
252
+ return (e: NativeTouchEvent, ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) => {
253
+ const handlerMap = {
254
+ onTouchStart: handleTouchstart,
255
+ onTouchMove: handleTouchmove,
256
+ onTouchEnd: handleTouchend,
257
+ onTouchCancel: handleTouchcancel
258
+ }
259
+
260
+ const handler = handlerMap[eventName]
261
+ if (handler) {
262
+ handler(e, type, ref, propsRef, config, navigation)
263
+ }
264
+ }
265
+ }
266
+
267
+ const touchEventList = [
268
+ { eventName: 'onTouchStart', handler: createTouchEventHandler('onTouchStart', 'bubble') },
269
+ { eventName: 'onTouchMove', handler: createTouchEventHandler('onTouchMove', 'bubble') },
270
+ { eventName: 'onTouchEnd', handler: createTouchEventHandler('onTouchEnd', 'bubble') },
271
+ { eventName: 'onTouchCancel', handler: createTouchEventHandler('onTouchCancel', 'bubble') },
272
+ { eventName: 'onTouchStartCapture', handler: createTouchEventHandler('onTouchStart', 'capture') },
273
+ { eventName: 'onTouchMoveCapture', handler: createTouchEventHandler('onTouchMove', 'capture') },
274
+ { eventName: 'onTouchEndCapture', handler: createTouchEventHandler('onTouchEnd', 'capture') },
275
+ { eventName: 'onTouchCancelCapture', handler: createTouchEventHandler('onTouchCancel', 'capture') }
276
+ ]
277
+
98
278
  const useInnerProps = (
99
279
  props: Props = {},
100
280
  additionalProps: AdditionalProps = {},
@@ -106,10 +286,6 @@ const useInnerProps = (
106
286
  bubble: null,
107
287
  capture: null
108
288
  },
109
- needPress: {
110
- bubble: false,
111
- capture: false
112
- },
113
289
  mpxPressInfo: {
114
290
  detail: {
115
291
  x: 0,
@@ -120,7 +296,12 @@ const useInnerProps = (
120
296
 
121
297
  const propsRef = useRef<Record<string, any>>({})
122
298
  const eventConfig: { [key: string]: string[] } = {}
123
- const config = rawConfig || { layoutRef: { current: {} }, disableTouch: false, disableTap: false }
299
+ const config = rawConfig || {
300
+ layoutRef: { current: {} },
301
+ disableTap: false
302
+ }
303
+ const navigation = useNavigation()
304
+
124
305
  const removeProps = [
125
306
  'children',
126
307
  'enable-background',
@@ -135,166 +316,39 @@ const useInnerProps = (
135
316
 
136
317
  propsRef.current = extendObject({}, props, additionalProps)
137
318
 
319
+ let hashEventKey = ''
320
+ const rawEventKeys: Array<string> = []
321
+
138
322
  for (const key in eventConfigMap) {
139
323
  if (hasOwn(propsRef.current, key)) {
140
- eventConfig[key] = eventConfigMap[key]
141
- }
142
- }
143
-
144
- if (!(Object.keys(eventConfig).length) || config.disableTouch) {
145
- return omit(propsRef.current, removeProps)
146
- }
147
-
148
- function handleEmitEvent (
149
- events: string[],
150
- type: string,
151
- oe: NativeTouchEvent
152
- ) {
153
- events.forEach(event => {
154
- if (propsRef.current[event]) {
155
- const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event)
156
- if (match) {
157
- oe.stopPropagation()
158
- }
159
- propsRef.current[event](getTouchEvent(type, oe, propsRef.current, config))
160
- }
161
- })
162
- }
163
-
164
- function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture') {
165
- const tapDetailInfo = ref.current.mpxPressInfo.detail || { x: 0, y: 0 }
166
- const nativeEvent = e.nativeEvent
167
- const currentPageX = nativeEvent.changedTouches[0].pageX
168
- const currentPageY = nativeEvent.changedTouches[0].pageY
169
- if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) {
170
- ref.current.needPress[type] = false
171
- ref.current.startTimer[type] && clearTimeout(ref.current.startTimer[type] as SetTimeoutReturnType)
172
- ref.current.startTimer[type] = null
324
+ eventConfig[key] = eventConfigMap[key].events
325
+ hashEventKey = hashEventKey + eventConfigMap[key].bitFlag
326
+ rawEventKeys.push(key)
173
327
  }
174
328
  }
175
329
 
176
- function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture') {
177
- e.persist()
178
- const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart']
179
- const bubblePressEvent = ['catchlongpress', 'bindlongpress']
180
- const captureTouchEvent = ['capture-catchtouchstart', 'capture-bindtouchstart']
181
- const capturePressEvent = ['capture-catchlongpress', 'capture-bindlongpress']
182
- ref.current.startTimer[type] = null
183
- ref.current.needPress[type] = true
184
- const nativeEvent = e.nativeEvent
185
- ref.current.mpxPressInfo.detail = {
186
- x: nativeEvent.changedTouches[0].pageX,
187
- y: nativeEvent.changedTouches[0].pageY
188
- }
189
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
190
- const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent
191
- handleEmitEvent(currentTouchEvent, 'touchstart', e)
192
- const { catchlongpress, bindlongpress, 'capture-catchlongpress': captureCatchlongpress, 'capture-bindlongpress': captureBindlongpress } = propsRef.current
193
- if (catchlongpress || bindlongpress || captureCatchlongpress || captureBindlongpress) {
194
- ref.current.startTimer[type] = setTimeout(() => {
195
- ref.current.needPress[type] = false
196
- handleEmitEvent(currentPressEvent, 'longpress', e)
197
- }, 350)
330
+ const events = useMemo(() => {
331
+ if (!rawEventKeys.length) {
332
+ return {}
198
333
  }
199
- }
200
-
201
- function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture') {
202
- const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove']
203
- const captureTouchEvent = ['capture-catchtouchmove', 'capture-bindtouchmove']
204
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
205
- handleEmitEvent(currentTouchEvent, 'touchmove', e)
206
- checkIsNeedPress(e, type)
207
- }
208
-
209
- function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture') {
210
- // move event may not be triggered
211
- checkIsNeedPress(e, type)
212
- const bubbleTouchEvent = ['catchtouchend', 'bindtouchend']
213
- const bubbleTapEvent = ['catchtap', 'bindtap']
214
- const captureTouchEvent = ['capture-catchtouchend', 'capture-bindtouchend']
215
- const captureTapEvent = ['capture-catchtap', 'capture-bindtap']
216
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
217
- const currentTapEvent = type === 'bubble' ? bubbleTapEvent : captureTapEvent
218
- ref.current.startTimer[type] && clearTimeout(ref.current.startTimer[type] as SetTimeoutReturnType)
219
- ref.current.startTimer[type] = null
220
- handleEmitEvent(currentTouchEvent, 'touchend', e)
221
- if (ref.current.needPress[type]) {
222
- if (type === 'bubble' && config.disableTap) {
223
- return
334
+ const transformedEventKeys = rawEventKeys.reduce((acc: string[], key) => {
335
+ if (propsRef.current[key]) {
336
+ return acc.concat(eventConfig[key])
224
337
  }
225
- handleEmitEvent(currentTapEvent, 'tap', e)
226
- }
227
- }
228
-
229
- function handleTouchcancel (e: NativeTouchEvent, type: 'bubble' | 'capture') {
230
- const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel']
231
- const captureTouchEvent = ['capture-catchtouchcancel', 'capture-bindtouchcancel']
232
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
233
- ref.current.startTimer[type] && clearTimeout(ref.current.startTimer[type] as SetTimeoutReturnType)
234
- ref.current.startTimer[type] = null
235
- handleEmitEvent(currentTouchEvent, 'touchcancel', e)
236
- }
338
+ return acc
339
+ }, [])
340
+ const finalEventKeys = [...new Set(transformedEventKeys)]
341
+ const events: Record<string, (e: NativeTouchEvent) => void> = {}
237
342
 
238
- const touchEventList = [{
239
- eventName: 'onTouchStart',
240
- handler: (e: NativeTouchEvent) => {
241
- handleTouchstart(e, 'bubble')
242
- }
243
- }, {
244
- eventName: 'onTouchMove',
245
- handler: (e: NativeTouchEvent) => {
246
- handleTouchmove(e, 'bubble')
247
- }
248
- }, {
249
- eventName: 'onTouchEnd',
250
- handler: (e: NativeTouchEvent) => {
251
- handleTouchend(e, 'bubble')
252
- }
253
- }, {
254
- eventName: 'onTouchCancel',
255
- handler: (e: NativeTouchEvent) => {
256
- handleTouchcancel(e, 'bubble')
257
- }
258
- }, {
259
- eventName: 'onTouchStartCapture',
260
- handler: (e: NativeTouchEvent) => {
261
- handleTouchstart(e, 'capture')
262
- }
263
- }, {
264
- eventName: 'onTouchMoveCapture',
265
- handler: (e: NativeTouchEvent) => {
266
- handleTouchmove(e, 'capture')
267
- }
268
- }, {
269
- eventName: 'onTouchEndCapture',
270
- handler: (e: NativeTouchEvent) => {
271
- handleTouchend(e, 'capture')
272
- }
273
- }, {
274
- eventName: 'onTouchCancelCapture',
275
- handler: (e: NativeTouchEvent) => {
276
- handleTouchcancel(e, 'capture')
277
- }
278
- }]
279
-
280
- const events: Record<string, (e: NativeTouchEvent) => void> = {}
281
-
282
- let transformedEventKeys: string[] = []
283
- for (const key in eventConfig) {
284
- if (propsRef.current[key]) {
285
- transformedEventKeys = transformedEventKeys.concat(eventConfig[key])
286
- }
287
- }
288
-
289
- const finalEventKeys = [...new Set(transformedEventKeys)]
290
-
291
- touchEventList.forEach(item => {
292
- if (finalEventKeys.includes(item.eventName)) {
293
- events[item.eventName] = item.handler
294
- }
295
- })
343
+ touchEventList.forEach((item) => {
344
+ if (finalEventKeys.includes(item.eventName)) {
345
+ events[item.eventName] = (e: NativeTouchEvent) =>
346
+ item.handler(e, ref, propsRef, config, navigation)
347
+ }
348
+ })
296
349
 
297
- const rawEventKeys = Object.keys(eventConfig)
350
+ return events
351
+ }, [hashEventKey])
298
352
 
299
353
  return extendObject(
300
354
  {},
@@ -34,7 +34,7 @@
34
34
  * ✘ bindagreeprivacyauthorization
35
35
  * ✔ bindtap
36
36
  */
37
- import { useEffect, useRef, useState, ReactNode, forwardRef, useContext, JSX } from 'react'
37
+ import { createElement, useEffect, useRef, ReactNode, forwardRef, useContext, JSX } from 'react'
38
38
  import {
39
39
  View,
40
40
  StyleSheet,
@@ -45,10 +45,12 @@ import {
45
45
  NativeSyntheticEvent
46
46
  } from 'react-native'
47
47
  import { warn } from '@mpxjs/utils'
48
- import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils'
48
+ import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
49
+ import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover } from './utils'
49
50
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
50
51
  import useNodesRef, { HandlerRef } from './useNodesRef'
51
52
  import { RouteContext, FormContext } from './context'
53
+ import type { ExtendedViewStyle } from './types/common'
52
54
 
53
55
  export type Type = 'default' | 'primary' | 'warn'
54
56
 
@@ -68,7 +70,7 @@ export interface ButtonProps {
68
70
  disabled?: boolean
69
71
  loading?: boolean
70
72
  'hover-class'?: string
71
- 'hover-style'?: ViewStyle & TextStyle & Record<string, any>
73
+ 'hover-style'?: ExtendedViewStyle
72
74
  'hover-start-time'?: number
73
75
  'hover-stay-time'?: number
74
76
  'open-type'?: OpenType
@@ -83,8 +85,6 @@ export interface ButtonProps {
83
85
  children: ReactNode
84
86
  bindgetuserinfo?: (userInfo: any) => void
85
87
  bindtap?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
86
- bindtouchstart?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
87
- bindtouchend?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
88
88
  }
89
89
 
90
90
  const LOADING_IMAGE_URI =
@@ -216,15 +216,16 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
216
216
  style = {},
217
217
  children,
218
218
  bindgetuserinfo,
219
- bindtap,
220
- bindtouchstart,
221
- bindtouchend
219
+ bindtap
222
220
  } = props
223
221
 
224
222
  const pageId = useContext(RouteContext)
225
223
 
226
224
  const formContext = useContext(FormContext)
227
225
 
226
+ const enableHover = hoverClass !== 'none'
227
+ const { isHover, gesture } = useHover({ enableHover, hoverStartTime, hoverStayTime, disabled })
228
+
228
229
  let submitFn: () => void | undefined
229
230
  let resetFn: () => void | undefined
230
231
 
@@ -233,27 +234,15 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
233
234
  resetFn = formContext.reset
234
235
  }
235
236
 
236
- const refs = useRef<{
237
- hoverStartTimer: ReturnType<typeof setTimeout> | undefined
238
- hoverStayTimer: ReturnType<typeof setTimeout> | undefined
239
- }>({
240
- hoverStartTimer: undefined,
241
- hoverStayTimer: undefined
242
- })
243
-
244
- const [isHover, setIsHover] = useState(false)
245
-
246
237
  const isMiniSize = size === 'mini'
247
238
 
248
- const applyHoverEffect = isHover && hoverClass !== 'none'
249
-
250
239
  const [color, hoverColor, plainColor, disabledColor] = TypeColorMap[type]
251
240
 
252
- const normalBackgroundColor = disabled ? disabledColor : applyHoverEffect || loading ? hoverColor : color
241
+ const normalBackgroundColor = disabled ? disabledColor : isHover || loading ? hoverColor : color
253
242
 
254
243
  const plainBorderColor = disabled
255
244
  ? 'rgba(0, 0, 0, .2)'
256
- : applyHoverEffect
245
+ : isHover
257
246
  ? `rgba(${plainColor},.6)`
258
247
  : `rgb(${plainColor})`
259
248
 
@@ -261,14 +250,14 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
261
250
 
262
251
  const plainTextColor = disabled
263
252
  ? 'rgba(0, 0, 0, .2)'
264
- : applyHoverEffect
253
+ : isHover
265
254
  ? `rgba(${plainColor}, .6)`
266
255
  : `rgb(${plainColor})`
267
256
 
268
257
  const normalTextColor =
269
258
  type === 'default'
270
- ? `rgba(0, 0, 0, ${disabled ? 0.3 : applyHoverEffect || loading ? 0.6 : 1})`
271
- : `rgba(255 ,255 ,255 , ${disabled || applyHoverEffect || loading ? 0.6 : 1})`
259
+ ? `rgba(0, 0, 0, ${disabled ? 0.3 : isHover || loading ? 0.6 : 1})`
260
+ : `rgba(255 ,255 ,255 , ${disabled || isHover || loading ? 0.6 : 1})`
272
261
 
273
262
  const viewStyle = {
274
263
  borderWidth: 1,
@@ -297,7 +286,7 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
297
286
  {},
298
287
  defaultStyle,
299
288
  style,
300
- applyHoverEffect ? hoverStyle : {}
289
+ isHover ? hoverStyle : {}
301
290
  )
302
291
 
303
292
  const {
@@ -366,34 +355,6 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
366
355
  }
367
356
  }
368
357
 
369
- const setStayTimer = () => {
370
- clearTimeout(refs.current.hoverStayTimer)
371
- refs.current.hoverStayTimer = setTimeout(() => {
372
- setIsHover(false)
373
- clearTimeout(refs.current.hoverStayTimer)
374
- }, hoverStayTime)
375
- }
376
-
377
- const setStartTimer = () => {
378
- clearTimeout(refs.current.hoverStartTimer)
379
- refs.current.hoverStartTimer = setTimeout(() => {
380
- setIsHover(true)
381
- clearTimeout(refs.current.hoverStartTimer)
382
- }, hoverStartTime)
383
- }
384
-
385
- const onTouchStart = (evt: NativeSyntheticEvent<TouchEvent>) => {
386
- bindtouchstart && bindtouchstart(evt)
387
- if (disabled) return
388
- setStartTimer()
389
- }
390
-
391
- const onTouchEnd = (evt: NativeSyntheticEvent<TouchEvent>) => {
392
- bindtouchend && bindtouchend(evt)
393
- if (disabled) return
394
- setStayTimer()
395
- }
396
-
397
358
  const handleFormTypeFn = () => {
398
359
  if (formType === 'submit') {
399
360
  submitFn && submitFn()
@@ -418,8 +379,6 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
418
379
  },
419
380
  layoutProps,
420
381
  {
421
- bindtouchstart: (bindtouchstart || !disabled) && onTouchStart,
422
- bindtouchend: (bindtouchend || !disabled) && onTouchEnd,
423
382
  bindtap: !disabled && onTap
424
383
  }
425
384
  ),
@@ -442,22 +401,21 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
442
401
  }
443
402
  )
444
403
 
445
- return (
446
- <View {...innerProps}>
447
- {loading && <Loading alone={!children} />}
404
+ const baseButton = createElement(View, innerProps, loading && createElement(Loading, { alone: !children }),
405
+ wrapChildren(
406
+ props,
448
407
  {
449
- wrapChildren(
450
- props,
451
- {
452
- hasVarDec,
453
- varContext: varContextRef.current,
454
- textStyle,
455
- textProps
456
- }
457
- )
408
+ hasVarDec,
409
+ varContext: varContextRef.current,
410
+ textStyle,
411
+ textProps
458
412
  }
459
- </View>
413
+ )
460
414
  )
415
+
416
+ return enableHover
417
+ ? createElement(GestureDetector, { gesture: gesture as PanGesture }, baseButton)
418
+ : baseButton
461
419
  })
462
420
 
463
421
  Button.displayName = 'MpxButton'