@mpxjs/webpack-plugin 2.10.3-beta.16 → 2.10.3-beta.18

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 (68) hide show
  1. package/lib/runtime/components/react/dist/context.js +5 -1
  2. package/lib/runtime/components/react/dist/event.config.js +0 -1
  3. package/lib/runtime/components/react/dist/getInnerListeners.js +148 -149
  4. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +145 -0
  5. package/lib/runtime/components/react/dist/mpx-button.jsx +11 -7
  6. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
  7. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +23 -21
  8. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +9 -4
  9. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +9 -5
  10. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
  11. package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
  12. package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
  13. package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
  14. package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
  15. package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
  16. package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
  17. package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
  18. package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
  19. package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
  20. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +9 -4
  21. package/lib/runtime/components/react/dist/mpx-image.jsx +92 -41
  22. package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
  23. package/lib/runtime/components/react/dist/mpx-input.jsx +14 -13
  24. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +22 -7
  25. package/lib/runtime/components/react/dist/mpx-label.jsx +9 -5
  26. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -5
  27. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +206 -80
  28. package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
  29. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
  30. package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
  31. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +178 -98
  32. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
  33. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
  34. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
  35. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
  36. package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +16 -15
  37. package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +95 -26
  38. package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +16 -16
  39. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +20 -0
  40. package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
  41. package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
  42. package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
  43. package/lib/runtime/components/react/dist/mpx-portal/index.jsx +5 -1
  44. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +3 -5
  45. package/lib/runtime/components/react/dist/mpx-progress.jsx +163 -0
  46. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -4
  47. package/lib/runtime/components/react/dist/mpx-radio.jsx +9 -5
  48. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +12 -4
  49. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +317 -89
  50. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +7 -5
  51. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
  52. package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
  53. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +117 -0
  54. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +15 -14
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +245 -121
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +10 -7
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +43 -13
  59. package/lib/runtime/components/react/dist/mpx-video.jsx +12 -7
  60. package/lib/runtime/components/react/dist/mpx-view.jsx +34 -18
  61. package/lib/runtime/components/react/dist/mpx-web-view.jsx +40 -35
  62. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -90
  63. package/lib/runtime/components/react/dist/utils.jsx +215 -109
  64. package/lib/runtime/components/web/mpx-titlebar.vue +25 -29
  65. package/package.json +1 -1
  66. /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
  67. /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
  68. /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
@@ -1,4 +1,6 @@
1
1
  import { createContext } from 'react';
2
+ import { Animated } from 'react-native';
3
+ import { noop } from '@mpxjs/utils';
2
4
  export const MovableAreaContext = createContext({ width: 0, height: 0 });
3
5
  export const FormContext = createContext(null);
4
6
  export const CheckboxGroupContext = createContext(null);
@@ -10,5 +12,7 @@ export const IntersectionObserverContext = createContext(null);
10
12
  export const RouteContext = createContext(null);
11
13
  export const SwiperContext = createContext({});
12
14
  export const KeyboardAvoidContext = createContext(null);
13
- export const ScrollViewContext = createContext({ gestureRef: null });
15
+ export const ScrollViewContext = createContext({ gestureRef: null, scrollOffset: new Animated.Value(0) });
14
16
  export const PortalContext = createContext(null);
17
+ export const StickyContext = createContext({ registerStickyHeader: noop, unregisterStickyHeader: noop });
18
+ export const ProviderContext = createContext(null);
@@ -1,4 +1,3 @@
1
- export const TAP_EVENTS = ['bindtap', 'catchtap', 'capture-bindtap', 'capture-catchtap'];
2
1
  const eventConfigMap = {
3
2
  bindtap: { bitFlag: '0', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd'] },
4
3
  bindlongpress: { bitFlag: '1', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'] },
@@ -1,21 +1,23 @@
1
1
  import { useRef, useMemo } from 'react';
2
- import { hasOwn, collectDataset } from '@mpxjs/utils';
2
+ import { collectDataset } from '@mpxjs/utils';
3
3
  import { omit, extendObject, useNavigation } from './utils';
4
- import eventConfigMap, { TAP_EVENTS } from './event.config';
4
+ import eventConfigMap from './event.config';
5
5
  const globalEventState = {
6
- needPress: true
6
+ needPress: true,
7
+ identifier: null
7
8
  };
8
- const getTouchEvent = (type, event, props, config, navigation) => {
9
- const { y: navigationY = 0 } = navigation?.layout || {};
9
+ const getTouchEvent = (type, event, config) => {
10
+ const { navigation, propsRef, layoutRef } = config;
11
+ const props = propsRef.current;
12
+ const { top: navigationY = 0 } = navigation?.layout || {};
10
13
  const nativeEvent = event.nativeEvent;
11
14
  const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent;
12
15
  const { id } = props;
13
- const { layoutRef } = config;
14
16
  const currentTarget = extendObject({}, event.currentTarget, {
15
17
  id: id || '',
16
18
  dataset: collectDataset(props),
17
- offsetLeft: layoutRef?.current?.offsetLeft || 0,
18
- offsetTop: layoutRef?.current?.offsetTop || 0
19
+ offsetLeft: layoutRef.current?.offsetLeft || 0,
20
+ offsetTop: layoutRef.current?.offsetTop || 0
19
21
  });
20
22
  const pendingProps = event._targetInst?.pendingProps || {};
21
23
  const target = extendObject({}, event.target, {
@@ -70,139 +72,120 @@ export const getCustomEvent = (type = '', oe = {}, { detail = {}, layoutRef }, p
70
72
  preventDefault: oe.preventDefault
71
73
  });
72
74
  };
73
- function handleEmitEvent(events, type, oe, propsRef, config, navigation) {
74
- events.forEach((event) => {
75
- if (propsRef.current[event]) {
76
- const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event);
77
- if (match) {
78
- oe.stopPropagation();
79
- }
80
- propsRef.current[event](getTouchEvent(type, oe, propsRef.current, config, navigation));
75
+ function handleEmitEvent(name, e, type, eventConfig) {
76
+ const { propsRef } = eventConfig;
77
+ const eventCfg = eventConfig[name];
78
+ if (eventCfg) {
79
+ if (eventCfg.hasCatch && name !== 'tap' && name !== 'longpress') {
80
+ e.stopPropagation();
81
81
  }
82
- });
82
+ eventCfg[type].forEach((event) => {
83
+ propsRef.current[event]?.(getTouchEvent(name, e, eventConfig));
84
+ });
85
+ }
83
86
  }
84
87
  function checkIsNeedPress(e, type, ref) {
85
88
  const tapDetailInfo = ref.current.mpxPressInfo.detail || { x: 0, y: 0 };
86
- const nativeEvent = e.nativeEvent;
87
- const currentPageX = nativeEvent.changedTouches[0].pageX;
88
- const currentPageY = nativeEvent.changedTouches[0].pageY;
89
+ const currentPageX = e.nativeEvent.changedTouches[0].pageX;
90
+ const currentPageY = e.nativeEvent.changedTouches[0].pageY;
89
91
  if (Math.abs(currentPageX - tapDetailInfo.x) > 3 ||
90
92
  Math.abs(currentPageY - tapDetailInfo.y) > 3) {
91
93
  globalEventState.needPress = false;
92
- ref.current.startTimer[type] &&
93
- clearTimeout(ref.current.startTimer[type]);
94
+ ref.current.startTimer[type] && clearTimeout(ref.current.startTimer[type]);
94
95
  ref.current.startTimer[type] = null;
95
96
  }
96
97
  }
97
- function handleTouchstart(e, type, ref, propsRef, config, navigation) {
98
+ function shouldHandleTapEvent(e, eventConfig) {
99
+ const { identifier } = e.nativeEvent.changedTouches[0];
100
+ return eventConfig.tap && globalEventState.identifier === identifier;
101
+ }
102
+ function handleTouchstart(e, type, eventConfig) {
98
103
  e.persist();
99
- const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart'];
100
- const bubblePressEvent = ['catchlongpress', 'bindlongpress'];
101
- const captureTouchEvent = [
102
- 'capture-catchtouchstart',
103
- 'capture-bindtouchstart'
104
- ];
105
- const capturePressEvent = [
106
- 'capture-catchlongpress',
107
- 'capture-bindlongpress'
108
- ];
109
- ref.current.startTimer[type] = null;
110
- globalEventState.needPress = true;
111
- const nativeEvent = e.nativeEvent;
112
- ref.current.mpxPressInfo.detail = {
113
- x: nativeEvent.changedTouches[0].pageX,
114
- y: nativeEvent.changedTouches[0].pageY
115
- };
116
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
117
- const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent;
118
- handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigation);
119
- const { catchlongpress, bindlongpress, 'capture-catchlongpress': captureCatchlongpress, 'capture-bindlongpress': captureBindlongpress } = propsRef.current;
120
- if (catchlongpress ||
121
- bindlongpress ||
122
- captureCatchlongpress ||
123
- captureBindlongpress) {
124
- ref.current.startTimer[type] = setTimeout(() => {
125
- // 只要触发过longpress, 全局就不再触发tap
126
- globalEventState.needPress = false;
127
- handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigation);
128
- }, 350);
104
+ const { innerRef } = eventConfig;
105
+ const touch = e.nativeEvent.changedTouches[0];
106
+ const { identifier } = touch;
107
+ const isSingle = e.nativeEvent.touches.length <= 1;
108
+ if (isSingle) {
109
+ // 仅在 touchstart 记录第一个单指触摸点
110
+ globalEventState.identifier = identifier;
111
+ globalEventState.needPress = true;
112
+ innerRef.current.mpxPressInfo.detail = {
113
+ x: touch.pageX,
114
+ y: touch.pageY
115
+ };
129
116
  }
130
- }
131
- function handleTouchmove(e, type, ref, propsRef, config, navigation) {
132
- const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove'];
133
- const captureTouchEvent = [
134
- 'capture-catchtouchmove',
135
- 'capture-bindtouchmove'
136
- ];
137
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
138
- handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigation);
139
- if (TAP_EVENTS.some(eventName => propsRef.current[eventName])) {
140
- checkIsNeedPress(e, type, ref);
117
+ handleEmitEvent('touchstart', e, type, eventConfig);
118
+ if (eventConfig.longpress) {
119
+ // 只有单指触摸时才启动长按定时器
120
+ if (isSingle) {
121
+ if (e._stoppedEventTypes?.has('longpress')) {
122
+ return;
123
+ }
124
+ if (eventConfig.longpress.hasCatch) {
125
+ e._stoppedEventTypes = e._stoppedEventTypes || new Set();
126
+ e._stoppedEventTypes.add('longpress');
127
+ }
128
+ innerRef.current.startTimer[type] && clearTimeout(innerRef.current.startTimer[type]);
129
+ innerRef.current.startTimer[type] = setTimeout(() => {
130
+ globalEventState.needPress = false;
131
+ handleEmitEvent('longpress', e, type, eventConfig);
132
+ }, 350);
133
+ }
141
134
  }
142
135
  }
143
- function handleTouchend(e, type, ref, propsRef, config, navigation) {
144
- // move event may not be triggered
145
- if (TAP_EVENTS.some(eventName => propsRef.current[eventName])) {
146
- checkIsNeedPress(e, type, ref);
136
+ function handleTouchmove(e, type, eventConfig) {
137
+ const { innerRef } = eventConfig;
138
+ handleEmitEvent('touchmove', e, type, eventConfig);
139
+ if (shouldHandleTapEvent(e, eventConfig)) {
140
+ checkIsNeedPress(e, type, innerRef);
147
141
  }
148
- const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'];
149
- const bubbleTapEvent = ['catchtap', 'bindtap'];
150
- const captureTouchEvent = [
151
- 'capture-catchtouchend',
152
- 'capture-bindtouchend'
153
- ];
154
- const captureTapEvent = ['capture-catchtap', 'capture-bindtap'];
155
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
156
- const currentTapEvent = type === 'bubble' ? bubbleTapEvent : captureTapEvent;
157
- ref.current.startTimer[type] &&
158
- clearTimeout(ref.current.startTimer[type]);
159
- ref.current.startTimer[type] = null;
160
- handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation);
161
- if (globalEventState.needPress) {
162
- if (type === 'bubble' && config.disableTap) {
142
+ }
143
+ function handleTouchend(e, type, eventConfig) {
144
+ const { innerRef, disableTap } = eventConfig;
145
+ handleEmitEvent('touchend', e, type, eventConfig);
146
+ innerRef.current.startTimer[type] && clearTimeout(innerRef.current.startTimer[type]);
147
+ // 只有单指触摸结束时才触发 tap
148
+ if (shouldHandleTapEvent(e, eventConfig)) {
149
+ checkIsNeedPress(e, type, innerRef);
150
+ if (!globalEventState.needPress || (type === 'bubble' && disableTap) || e._stoppedEventTypes?.has('tap')) {
163
151
  return;
164
152
  }
165
- handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation);
153
+ if (eventConfig.tap.hasCatch) {
154
+ e._stoppedEventTypes = e._stoppedEventTypes || new Set();
155
+ e._stoppedEventTypes.add('tap');
156
+ }
157
+ handleEmitEvent('tap', e, type, eventConfig);
166
158
  }
167
159
  }
168
- function handleTouchcancel(e, type, ref, propsRef, config, navigation) {
169
- const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'];
170
- const captureTouchEvent = [
171
- 'capture-catchtouchcancel',
172
- 'capture-bindtouchcancel'
173
- ];
174
- const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
175
- ref.current.startTimer[type] &&
176
- clearTimeout(ref.current.startTimer[type]);
177
- ref.current.startTimer[type] = null;
178
- handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation);
160
+ function handleTouchcancel(e, type, eventConfig) {
161
+ const { innerRef } = eventConfig;
162
+ handleEmitEvent('touchcancel', e, type, eventConfig);
163
+ innerRef.current.startTimer[type] && clearTimeout(innerRef.current.startTimer[type]);
179
164
  }
180
- function createTouchEventHandler(eventName, type) {
181
- return (e, ref, propsRef, config, navigation) => {
182
- const handlerMap = {
165
+ function createTouchEventHandler(eventName, eventConfig) {
166
+ return (e) => {
167
+ const bubbleHandlerMap = {
183
168
  onTouchStart: handleTouchstart,
184
169
  onTouchMove: handleTouchmove,
185
170
  onTouchEnd: handleTouchend,
186
171
  onTouchCancel: handleTouchcancel
187
172
  };
188
- const handler = handlerMap[eventName];
189
- if (handler) {
190
- handler(e, type, ref, propsRef, config, navigation);
173
+ const captureHandlerMap = {
174
+ onTouchStartCapture: handleTouchstart,
175
+ onTouchMoveCapture: handleTouchmove,
176
+ onTouchEndCapture: handleTouchend,
177
+ onTouchCancelCapture: handleTouchcancel
178
+ };
179
+ if (bubbleHandlerMap[eventName]) {
180
+ bubbleHandlerMap[eventName](e, 'bubble', eventConfig);
181
+ }
182
+ if (captureHandlerMap[eventName]) {
183
+ captureHandlerMap[eventName](e, 'capture', eventConfig);
191
184
  }
192
185
  };
193
186
  }
194
- const touchEventList = [
195
- { eventName: 'onTouchStart', handler: createTouchEventHandler('onTouchStart', 'bubble') },
196
- { eventName: 'onTouchMove', handler: createTouchEventHandler('onTouchMove', 'bubble') },
197
- { eventName: 'onTouchEnd', handler: createTouchEventHandler('onTouchEnd', 'bubble') },
198
- { eventName: 'onTouchCancel', handler: createTouchEventHandler('onTouchCancel', 'bubble') },
199
- { eventName: 'onTouchStartCapture', handler: createTouchEventHandler('onTouchStart', 'capture') },
200
- { eventName: 'onTouchMoveCapture', handler: createTouchEventHandler('onTouchMove', 'capture') },
201
- { eventName: 'onTouchEndCapture', handler: createTouchEventHandler('onTouchEnd', 'capture') },
202
- { eventName: 'onTouchCancelCapture', handler: createTouchEventHandler('onTouchCancel', 'capture') }
203
- ];
204
- const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], rawConfig) => {
205
- const ref = useRef({
187
+ const useInnerProps = (props = {}, userRemoveProps = [], rawConfig) => {
188
+ const innerRef = useRef({
206
189
  startTimer: {
207
190
  bubble: null,
208
191
  capture: null
@@ -215,52 +198,68 @@ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], r
215
198
  }
216
199
  });
217
200
  const propsRef = useRef({});
218
- const eventConfig = {};
219
- const config = rawConfig || {
220
- layoutRef: { current: {} },
221
- disableTap: false
222
- };
201
+ propsRef.current = props;
223
202
  const navigation = useNavigation();
224
- const removeProps = [
225
- 'children',
226
- 'enable-background',
227
- 'enable-offset',
228
- 'enable-var',
229
- 'external-var-context',
230
- 'parent-font-size',
231
- 'parent-width',
232
- 'parent-height',
233
- ...userRemoveProps
234
- ];
235
- propsRef.current = extendObject({}, props, additionalProps);
203
+ const eventConfig = extendObject({
204
+ layoutRef: {
205
+ current: null
206
+ },
207
+ propsRef,
208
+ innerRef,
209
+ disableTap: false,
210
+ navigation
211
+ }, rawConfig);
236
212
  let hashEventKey = '';
237
213
  const rawEventKeys = [];
238
- for (const key in eventConfigMap) {
239
- if (hasOwn(propsRef.current, key)) {
240
- eventConfig[key] = eventConfigMap[key].events;
241
- hashEventKey = hashEventKey + eventConfigMap[key].bitFlag;
214
+ const transformedEventSet = new Set();
215
+ Object.keys(props).forEach((key) => {
216
+ if (eventConfigMap[key]) {
217
+ hashEventKey += eventConfigMap[key].bitFlag;
242
218
  rawEventKeys.push(key);
219
+ eventConfigMap[key].events.forEach((event) => {
220
+ transformedEventSet.add(event);
221
+ });
222
+ const match = /^(bind|catch|capture-bind|capture-catch)(.*)$/.exec(key);
223
+ const prefix = match[1];
224
+ const eventName = match[2];
225
+ eventConfig[eventName] = eventConfig[eventName] || {
226
+ bubble: [],
227
+ capture: [],
228
+ hasCatch: false
229
+ };
230
+ if (prefix === 'bind' || prefix === 'catch') {
231
+ eventConfig[eventName].bubble.push(key);
232
+ }
233
+ else {
234
+ eventConfig[eventName].capture.push(key);
235
+ }
236
+ if (prefix === 'catch' || prefix === 'capture-catch') {
237
+ eventConfig[eventName].hasCatch = true;
238
+ }
243
239
  }
244
- }
240
+ });
245
241
  const events = useMemo(() => {
246
- if (!rawEventKeys.length) {
242
+ if (!hashEventKey) {
247
243
  return {};
248
244
  }
249
- const transformedEventKeys = rawEventKeys.reduce((acc, key) => {
250
- if (propsRef.current[key]) {
251
- return acc.concat(eventConfig[key]);
252
- }
253
- return acc;
254
- }, []);
255
- const finalEventKeys = [...new Set(transformedEventKeys)];
256
245
  const events = {};
257
- touchEventList.forEach((item) => {
258
- if (finalEventKeys.includes(item.eventName)) {
259
- events[item.eventName] = (e) => item.handler(e, ref, propsRef, config, navigation);
260
- }
261
- });
246
+ for (const eventName of transformedEventSet) {
247
+ events[eventName] = createTouchEventHandler(eventName, eventConfig);
248
+ }
262
249
  return events;
263
250
  }, [hashEventKey]);
264
- return extendObject({}, events, omit(propsRef.current, [...rawEventKeys, ...removeProps]));
251
+ const removeProps = [
252
+ 'children',
253
+ 'enable-background',
254
+ 'enable-offset',
255
+ 'enable-var',
256
+ 'external-var-context',
257
+ 'parent-font-size',
258
+ 'parent-width',
259
+ 'parent-height',
260
+ ...userRemoveProps,
261
+ ...rawEventKeys
262
+ ];
263
+ return extendObject({}, events, omit(props, removeProps));
265
264
  };
266
265
  export default useInnerProps;
@@ -0,0 +1,145 @@
1
+ import { useState, useEffect, useCallback, useRef, createElement } from 'react';
2
+ import { View, Image, StyleSheet, Text, TouchableOpacity } from 'react-native';
3
+ import FastImage from '@d11/react-native-fast-image';
4
+ const asyncChunkMap = new Map();
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ flex: 1,
8
+ padding: 20,
9
+ backgroundColor: '#fff'
10
+ },
11
+ loadingImage: {
12
+ width: 100,
13
+ height: 100,
14
+ marginTop: 220,
15
+ alignSelf: 'center'
16
+ },
17
+ buttonText: {
18
+ color: '#fff',
19
+ fontSize: 16,
20
+ fontWeight: '500',
21
+ textAlign: 'center'
22
+ },
23
+ errorImage: {
24
+ marginTop: 80,
25
+ width: 220,
26
+ aspectRatio: 1,
27
+ alignSelf: 'center'
28
+ },
29
+ errorText: {
30
+ fontSize: 16,
31
+ textAlign: 'center',
32
+ color: '#333',
33
+ marginBottom: 20
34
+ },
35
+ retryButton: {
36
+ position: 'absolute',
37
+ bottom: 54,
38
+ left: 20,
39
+ right: 20,
40
+ backgroundColor: '#fff',
41
+ paddingVertical: 15,
42
+ borderRadius: 30,
43
+ marginTop: 40,
44
+ borderWidth: 1,
45
+ borderColor: '#FF5F00'
46
+ },
47
+ retryButtonText: {
48
+ color: '#FF5F00',
49
+ fontSize: 16,
50
+ fontWeight: '500',
51
+ textAlign: 'center'
52
+ }
53
+ });
54
+ const DefaultFallback = ({ onReload }) => {
55
+ return (<View style={styles.container}>
56
+ <Image source={{
57
+ uri: 'https://dpubstatic.udache.com/static/dpubimg/Vak5mZvezPpKV5ZJI6P9b_drn-fallbak.png'
58
+ }} style={styles.errorImage} resizeMode="contain"/>
59
+ <Text style={styles.errorText}>网络出了点问题,请查看网络环境</Text>
60
+ <TouchableOpacity style={styles.retryButton} onPress={onReload} activeOpacity={0.7}>
61
+ <Text style={styles.retryButtonText}>点击重试</Text>
62
+ </TouchableOpacity>
63
+ </View>);
64
+ };
65
+ const DefaultLoading = () => {
66
+ return (<View style={styles.container}>
67
+ <FastImage style={styles.loadingImage} source={{
68
+ uri: 'https://dpubstatic.udache.com/static/dpubimg/439jiCVOtNOnEv9F2LaDs_loading.gif'
69
+ }} resizeMode={FastImage.resizeMode.contain}></FastImage>
70
+ </View>);
71
+ };
72
+ const AsyncSuspense = ({ type, chunkName, moduleId, innerProps, getLoading, getFallback, getChildren }) => {
73
+ const [status, setStatus] = useState('pending');
74
+ const chunkLoaded = asyncChunkMap.has(moduleId);
75
+ const loadChunkPromise = useRef(null);
76
+ const reloadPage = useCallback(() => {
77
+ setStatus('pending');
78
+ }, []);
79
+ useEffect(() => {
80
+ let cancelled = false;
81
+ if (!chunkLoaded && status === 'pending') {
82
+ if (loadChunkPromise.current) {
83
+ loadChunkPromise
84
+ .current.then((res) => {
85
+ if (cancelled)
86
+ return;
87
+ asyncChunkMap.set(moduleId, res);
88
+ setStatus('loaded');
89
+ })
90
+ .catch((e) => {
91
+ if (cancelled)
92
+ return;
93
+ if (type === 'component') {
94
+ global.__mpxAppCbs.lazyLoad.forEach((cb) => {
95
+ // eslint-disable-next-line node/no-callback-literal
96
+ cb({
97
+ type: 'subpackage',
98
+ subpackage: [chunkName],
99
+ errMsg: `loadSubpackage: ${e.type}`
100
+ });
101
+ });
102
+ }
103
+ if (type === 'page' && typeof mpxGlobal.__mpx.config?.rnConfig?.onLazyLoadPageError === 'function') {
104
+ mpxGlobal.__mpx.config.rnConfig.onLazyLoadPageError({
105
+ subpackage: chunkName,
106
+ errType: e.type
107
+ });
108
+ }
109
+ loadChunkPromise.current = null;
110
+ setStatus('error');
111
+ });
112
+ }
113
+ }
114
+ return () => {
115
+ cancelled = true;
116
+ };
117
+ }, [status]);
118
+ if (chunkLoaded) {
119
+ const Comp = asyncChunkMap.get(moduleId);
120
+ return createElement(Comp, innerProps);
121
+ }
122
+ else if (status === 'error') {
123
+ if (type === 'page') {
124
+ const fallback = getFallback ? getFallback() : DefaultFallback;
125
+ return createElement(fallback, { onReload: reloadPage });
126
+ }
127
+ else {
128
+ return getFallback ? createElement(getFallback(), innerProps) : null;
129
+ }
130
+ }
131
+ else {
132
+ if (!loadChunkPromise.current) {
133
+ loadChunkPromise.current = getChildren();
134
+ }
135
+ if (type === 'page') {
136
+ const loading = getLoading ? getLoading() : DefaultLoading;
137
+ return createElement(loading);
138
+ }
139
+ else {
140
+ return getFallback ? createElement(getFallback(), innerProps) : null;
141
+ }
142
+ }
143
+ };
144
+ AsyncSuspense.displayName = 'MpxAsyncSuspense';
145
+ export default AsyncSuspense;
@@ -35,13 +35,14 @@
35
35
  * ✔ bindtap
36
36
  */
37
37
  import { createElement, useEffect, useRef, forwardRef, useContext } from 'react';
38
- import { View, StyleSheet, Animated, Easing } from 'react-native';
38
+ import { View, StyleSheet, Animated, Easing, useAnimatedValue } from 'react-native';
39
39
  import { warn } from '@mpxjs/utils';
40
40
  import { GestureDetector } from 'react-native-gesture-handler';
41
41
  import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover } from './utils';
42
42
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
43
43
  import useNodesRef from './useNodesRef';
44
44
  import { RouteContext, FormContext } from './context';
45
+ import Portal from './mpx-portal';
45
46
  const LOADING_IMAGE_URI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAB8hJREFUeJztnVtsFFUch6ltUYrEAi0Qo40xChGM+oAGI0EEKl4QfDVI9AkqqQZ4IVA1RSIvJlwUWwqJUokGKMVYwHJTq4mGuA+SxpJYggJSSgMpVFOtvbh+J84mk+3smXN2znZm2fNLvoQH5uQ/v4+Z2Z3dHUaNsrGxsbGxsbGxsbGxsbGxsTGSrq6uUqiHqw7iz6Vhz5WzofwYxJP4Mey5cjIUX+4hI0F52PPlXCi9WiKkOuz5ci5WiMFcvHhxOXRCHPpgLdyis4ZJITtqagtgPfRBHH6HV3XWyNpQ/DxHRDJbddYxLKTGEZHMLK2dy8ZQ/O4UQgQzVdcxJYTSZ6aQIfggrZ3MplD6CYmQmOo6BoXEJEK+TGsnsymUXicRIlimso4JIRS+TCJDsD3QzmZDKHwqDEmEdECR3zpBhVB2EVyWyBiC+4zsdNRD4Vt8jpJ3/dYwIGSTz9Gx2cjOZkMofBx0S4SIl8JlsjWCCKHsMuiXyOiGcUZ3Ouqh8BU+R0mjbPuAQg76HB3Lje5sNoTC86DNR8qcVNunK4Sy5/jIaIO8jOx01CMK9xEihHmWk44Qis53CpcJSfmPICdC4Q0+Ul7z2i5NISt9ZOzP6M5mQ8TF27mIpxIiLv7DLrC6t9/FRdq5WKeSIe5jSV9IZEXa29sfgC+gBXbBJN01KPwdn6PkLa/tKP6Uh4xvvP4uZW/wOTo26M69q27nZPgIWqARpumuYTSU/zT0Q9xFL6yFQtV1KHyM6+6vF4e9tuvS+AiXwo9JZIg3iGNU56X4QlgPvRB30QdPqa5jNBSeBxeSZLg5B0tU16P0pRIhnwadl8L3SoS8pLoOhS+Bc0ki3JwNOmtaoeyJEhluTojTmsqaFP99CiGzg85L6QtTyGhR2Z6ip8PXEhFuioPOqx1Kvg3+VZQyBLUwXrYmxU+Bky4Rl+BlUzNTfgV0umSI01iJbBvKnQC1MKQoY0Cc0kzNrBUK3qMoJEE3VEK+bF0kPA4PZmpuJDwCj8n+DqXmQyX0KIpIUJepuX1DsXfAPk0pgp8hnIufQih1AZzRFCH4DHzvVGc8lDsbWtMQ0yikhj1/IuLc77x81RXRCoGvc0ZDsbdAhXNa0pGyO+zZE6HUfZoirkEFaH1BY0TjnMa2wKCikL9hdNhzU+pYjQv3ILwH2XOLnpKnQrOilDvDnpdy71KU0QT3hz1v2qHsRXBWIuOSON2FPafzqqpD9oYPFoY9p5FQeAGsgRtJMgbgubDnS4TCFzmnI7eI6/AGFIQ9n/FQfimsgsNwEGaEPVNyKP5h57R0GF6HiWHPZGNjY2NjYzytra2FsBiqoFqTKmfbcO6EppE99Z8UwmKogmpNqpxtM7O/FFkMpyEeELHGyH9eoBmKLIbTEA+IWMP8/lLiNgMyEmwxPqDhUOI2AzISmN9fSrxiUMh54wMaDiVeMSjkvPEBrZDoCanNsVNWbdRPWSUGL+q3Gx/QcCixxOBFPTP722pf9kbnZa+NjY2NjU2YicViJbADWqAJpoc9U3Ia9u1/CA5BC+wA6TcbszIUXwCr4QbEXQzAM2HPlwjlvwCDEHdxHVbDzfERLoU/D+1JItxchtC/5EDh+XA5SYabXyB7n8NFyVOhWSLCTehfA6LsuyUy3ByB7PkaEOUWw/swqChDEPoXzii5WFFI3DmtbYbIfA12WMRpByrgmoYIwZ6wZ0+Eghs1pAiuQQVE62fUlPoktGqKEDRE4ehIhGLHw0FNKYKf4Imw5xcixsHeNES0wfyw508Vyl0AZ9IQsxfGhjY4pX6sKaIbKkH6g53vWr6dBXNB+xe9fmlqapoEc0H6tDjnVVcl9GhKqTE9s1IodbTzPkJFxBBsB+lFEAFT4CTEHXrgFVMzI2E59ELc4ShI3/hR8ATYDkOKQnpMzasVyp2oKONETPEdOeX/4JLhJvCzDyl+vkuEmxaV7Sl6BnylKEX6W8qMhJLz4DeJiF9B+WfRlL40hQzBh0Hnpfj6FEIES1XXoewX4YJERjg/ixah8HKP09YfsAaUP5ih8CLokAg55LXd8aPHSqEerjqIP3s+OIDSmyVCOkD5t4GUfiusg94kGf0wT3WdjEScjuBzOAKrQPtCTOEbJTIEb3ttR/kxiCfh+ex3Ct8gESLYqDs35U9u+P8+l3j3fgDCfbSGiVB2GfRJZHTDsPcqFF/uISPBsHtOFD4euiVC+iD7Hz4TNJR9wOfo8Hw8E6VXS4RUe21D4St9jpKGjO5s1EPZc3xktIHnbYk0heRDm4+U3HyAmSjaKVwmJGU56QgREYX7CBHConVvaiRC2RU+MqQPwUxXiAiFH/SRssLozkY94iLtXKxTyRAXeekFNqCQMuiXCBEX/8jc9Mx4KHurz9Hh+yDlIEJEKHyTz1GSGw9SpuxpMCCR0SneKPqtY0BIEXRKhIgj6F4jOx3lUHadz9Gh9DD+oEJEKHyZz1Fy8z+Mn8KPS2Qo/3cVJoSIUHpMIqQ5rZ3MplD6TokQ5f/QxaCQRyVCAt/UjHyca4jXrRKt/83GlBARiq/xkPEn3KOzTtaG8p+FLkfEX7AOtL6bZVhIAbwJ/zgyLkFkP2KOZEwKsTEQKyRi0b39bjMCofhTHjI8n/1uMwI5rvERro2NjY2NjY2NjY2NjY2NjY1+/gNWA2LIOT/TRAAAAABJRU5ErkJggg==';
46
47
  const TypeColorMap = {
47
48
  default: ['#F8F8F8', '#DEDEDE', '35,35,35', '#F7F7F7'],
@@ -103,7 +104,7 @@ const timer = (data, time = 3000) => new Promise((resolve) => {
103
104
  }, time);
104
105
  });
105
106
  const Loading = ({ alone = false }) => {
106
- const image = useRef(new Animated.Value(0)).current;
107
+ const image = useAnimatedValue(0);
107
108
  const rotate = image.interpolate({
108
109
  inputRange: [0, 1],
109
110
  outputRange: ['0deg', '360deg']
@@ -167,7 +168,7 @@ const Button = forwardRef((buttonProps, ref) => {
167
168
  const defaultTextStyle = extendObject({}, styles.text, isMiniSize ? styles.textMini : {}, { color: plain ? plainTextColor : normalTextColor });
168
169
  const defaultStyle = extendObject({}, defaultViewStyle, defaultTextStyle);
169
170
  const styleObj = extendObject({}, defaultStyle, style, isHover ? hoverStyle : {});
170
- const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
171
+ const { hasPositionFixed, hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
171
172
  const nodeRef = useRef(null);
172
173
  useNodesRef(props, ref, nodeRef, { style: normalStyle });
173
174
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
@@ -236,10 +237,9 @@ const Button = forwardRef((buttonProps, ref) => {
236
237
  handleOpenTypeEvent(evt);
237
238
  handleFormTypeFn();
238
239
  };
239
- const innerProps = useInnerProps(props, extendObject({
240
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
240
241
  ref: nodeRef,
241
- style: extendObject({}, innerStyle, layoutStyle)
242
- }, layoutProps, {
242
+ style: extendObject({}, innerStyle, layoutStyle),
243
243
  bindtap: !disabled && onTap
244
244
  }), [
245
245
  'disabled',
@@ -263,9 +263,13 @@ const Button = forwardRef((buttonProps, ref) => {
263
263
  textStyle,
264
264
  textProps
265
265
  }));
266
- return enableHover
266
+ const finalComponent = enableHover
267
267
  ? createElement(GestureDetector, { gesture: gesture }, baseButton)
268
268
  : baseButton;
269
+ if (hasPositionFixed) {
270
+ return createElement(Portal, null, finalComponent);
271
+ }
272
+ return finalComponent;
269
273
  });
270
274
  Button.displayName = 'MpxButton';
271
275
  export default Button;
@@ -1,4 +1,5 @@
1
1
  import { WEBVIEW_TARGET, registerWebviewProperties } from './utils';
2
+ import { extendObject } from '../utils';
2
3
  const PROPERTIES = {
3
4
  crossOrigin: undefined,
4
5
  height: undefined,
@@ -50,10 +51,7 @@ export class Image {
50
51
  this[key] = value;
51
52
  }
52
53
  }
53
- callbackFn({
54
- ...message.payload,
55
- target: this
56
- });
54
+ callbackFn(extendObject({}, message.payload, { target: this }));
57
55
  }
58
56
  });
59
57
  }