@mpxjs/webpack-plugin 2.8.25-alpha.21 → 2.8.25-alpha.22

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 (72) hide show
  1. package/lib/runtime/components/react/dist/KeyboardAvoidingView.jsx +89 -0
  2. package/lib/runtime/components/react/dist/context.js +14 -0
  3. package/lib/runtime/components/react/dist/event.config.js +27 -0
  4. package/lib/runtime/components/react/dist/getInnerListeners.js +262 -0
  5. package/lib/runtime/components/react/dist/mpx-button.jsx +271 -0
  6. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  7. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  8. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  9. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  10. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  11. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  12. package/lib/runtime/components/react/dist/mpx-canvas/html.js +341 -0
  13. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +236 -0
  14. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  15. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +90 -0
  16. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +131 -0
  17. package/lib/runtime/components/react/dist/mpx-form.jsx +68 -0
  18. package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
  19. package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
  20. package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
  21. package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
  22. package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
  23. package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
  24. package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
  25. package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
  26. package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
  27. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +50 -0
  28. package/lib/runtime/components/react/dist/mpx-image.jsx +292 -0
  29. package/lib/runtime/components/react/dist/mpx-input.jsx +292 -0
  30. package/lib/runtime/components/react/dist/mpx-label.jsx +52 -0
  31. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +32 -0
  32. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +468 -0
  33. package/lib/runtime/components/react/dist/mpx-navigator.jsx +33 -0
  34. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +74 -0
  35. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +141 -0
  36. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +147 -0
  37. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +99 -0
  38. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +81 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +242 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  42. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +35 -0
  43. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +193 -0
  44. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +125 -0
  45. package/lib/runtime/components/react/dist/mpx-portal/index.jsx +30 -0
  46. package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +112 -0
  47. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +41 -0
  48. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +86 -0
  49. package/lib/runtime/components/react/dist/mpx-radio.jsx +140 -0
  50. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  51. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +62 -0
  52. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +17 -0
  53. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +372 -0
  54. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +59 -0
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +671 -0
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +97 -0
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +41 -0
  59. package/lib/runtime/components/react/dist/mpx-textarea.jsx +40 -0
  60. package/lib/runtime/components/react/dist/mpx-video.jsx +248 -0
  61. package/lib/runtime/components/react/dist/mpx-view.jsx +611 -0
  62. package/lib/runtime/components/react/dist/mpx-web-view.jsx +289 -0
  63. package/lib/runtime/components/react/dist/parser.js +218 -0
  64. package/lib/runtime/components/react/dist/pickerFaces.js +76 -0
  65. package/lib/runtime/components/react/dist/pickerVIewContext.js +14 -0
  66. package/lib/runtime/components/react/dist/pickerViewIndicator.jsx +23 -0
  67. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  68. package/lib/runtime/components/react/dist/useAnimationHooks.js +346 -0
  69. package/lib/runtime/components/react/dist/useNodesRef.js +16 -0
  70. package/lib/runtime/components/react/dist/utils.jsx +599 -0
  71. package/package.json +6 -3
  72. package/LICENSE +0 -433
@@ -0,0 +1,89 @@
1
+ import React, { useContext, useEffect } from 'react';
2
+ import { Keyboard, Platform, View } from 'react-native';
3
+ import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
4
+ import { KeyboardAvoidContext } from './context';
5
+ import { extendObject } from './utils';
6
+ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
7
+ const isIOS = Platform.OS === 'ios';
8
+ const duration = isIOS ? 250 : 300;
9
+ const easing = isIOS ? Easing.inOut(Easing.ease) : Easing.out(Easing.quad);
10
+ const offset = useSharedValue(0);
11
+ const basic = useSharedValue('auto');
12
+ const keyboardAvoid = useContext(KeyboardAvoidContext);
13
+ const animatedStyle = useAnimatedStyle(() => {
14
+ return Object.assign({
15
+ transform: [{ translateY: -offset.value }]
16
+ }, isIOS ? {} : { flexBasis: basic.value });
17
+ });
18
+ const resetKeyboard = () => {
19
+ keyboardAvoid?.current && extendObject(keyboardAvoid.current, {
20
+ cursorSpacing: 0,
21
+ ref: null
22
+ });
23
+ offset.value = withTiming(0, { duration, easing });
24
+ basic.value = 'auto';
25
+ };
26
+ useEffect(() => {
27
+ let subscriptions = [];
28
+ if (isIOS) {
29
+ subscriptions = [
30
+ Keyboard.addListener('keyboardWillShow', (evt) => {
31
+ if (!keyboardAvoid?.current)
32
+ return;
33
+ const { endCoordinates } = evt;
34
+ const { ref, cursorSpacing = 0 } = keyboardAvoid.current;
35
+ setTimeout(() => {
36
+ ref?.current?.measure((x, y, width, height, pageX, pageY) => {
37
+ const aboveOffset = offset.value + pageY + height - endCoordinates.screenY;
38
+ const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
39
+ const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
40
+ const value = aboveOffset > 0 ? belowValue : aboveValue;
41
+ offset.value = withTiming(value, { duration, easing });
42
+ });
43
+ });
44
+ }),
45
+ Keyboard.addListener('keyboardWillHide', resetKeyboard)
46
+ ];
47
+ }
48
+ else {
49
+ subscriptions = [
50
+ Keyboard.addListener('keyboardDidShow', (evt) => {
51
+ if (!keyboardAvoid?.current)
52
+ return;
53
+ const { endCoordinates } = evt;
54
+ const { ref, cursorSpacing = 0 } = keyboardAvoid.current;
55
+ ref?.current?.measure((x, y, width, height, pageX, pageY) => {
56
+ const aboveOffset = pageY + height - endCoordinates.screenY;
57
+ const belowOffset = endCoordinates.height - aboveOffset;
58
+ const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
59
+ const belowValue = Math.min(belowOffset, cursorSpacing);
60
+ const value = aboveOffset > 0 ? belowValue : aboveValue;
61
+ offset.value = withTiming(value, { duration, easing }, (finished) => {
62
+ if (finished) {
63
+ /**
64
+ * In the Android environment, the layout information is not synchronized after the animation,
65
+ * which results in the inability to correctly trigger element events.
66
+ * Here, we utilize flexBasic to proactively trigger a re-layout
67
+ */
68
+ basic.value = '99.99%';
69
+ }
70
+ });
71
+ });
72
+ }),
73
+ Keyboard.addListener('keyboardDidHide', resetKeyboard)
74
+ ];
75
+ }
76
+ return () => {
77
+ subscriptions.forEach(subscription => subscription.remove());
78
+ };
79
+ }, [keyboardAvoid]);
80
+ return (<View style={style}>
81
+ <Animated.View style={[
82
+ contentContainerStyle,
83
+ animatedStyle
84
+ ]}>
85
+ {children}
86
+ </Animated.View>
87
+ </View>);
88
+ };
89
+ export default KeyboardAvoidingView;
@@ -0,0 +1,14 @@
1
+ import { createContext } from 'react';
2
+ export const MovableAreaContext = createContext({ width: 0, height: 0 });
3
+ export const FormContext = createContext(null);
4
+ export const CheckboxGroupContext = createContext(null);
5
+ export const RadioGroupContext = createContext(null);
6
+ export const LabelContext = createContext(null);
7
+ export const PickerContext = createContext(null);
8
+ export const VarContext = createContext({});
9
+ export const IntersectionObserverContext = createContext(null);
10
+ export const RouteContext = createContext(null);
11
+ export const SwiperContext = createContext({});
12
+ export const KeyboardAvoidContext = createContext(null);
13
+ export const ScrollViewContext = createContext({ gestureRef: null });
14
+ export const PortalContext = createContext(null);
@@ -0,0 +1,27 @@
1
+ const eventConfigMap = {
2
+ bindtap: { bitFlag: '0', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd'] },
3
+ bindlongpress: { bitFlag: '1', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'] },
4
+ bindtouchstart: { bitFlag: '2', events: ['onTouchStart'] },
5
+ bindtouchmove: { bitFlag: '3', events: ['onTouchMove'] },
6
+ bindtouchend: { bitFlag: '4', events: ['onTouchEnd'] },
7
+ bindtouchcancel: { bitFlag: '5', events: ['onTouchCancel'] },
8
+ catchtap: { bitFlag: '6', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd'] },
9
+ catchlongpress: { bitFlag: '7', events: ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'] },
10
+ catchtouchstart: { bitFlag: '8', events: ['onTouchStart'] },
11
+ catchtouchmove: { bitFlag: '9', events: ['onTouchMove'] },
12
+ catchtouchend: { bitFlag: 'a', events: ['onTouchEnd'] },
13
+ catchtouchcancel: { bitFlag: 'b', events: ['onTouchCancel'] },
14
+ 'capture-bindtap': { bitFlag: 'c', events: ['onTouchStartCapture', 'onTouchMoveCapture', 'onTouchEndCapture'] },
15
+ 'capture-bindlongpress': { bitFlag: 'd', events: ['onTouchStartCapture', 'onTouchMoveCapture', 'onTouchEndCapture', 'onTouchCancelCapture'] },
16
+ 'capture-bindtouchstart': { bitFlag: 'e', events: ['onTouchStartCapture'] },
17
+ 'capture-bindtouchmove': { bitFlag: 'f', events: ['onTouchMoveCapture'] },
18
+ 'capture-bindtouchend': { bitFlag: 'g', events: ['onTouchEndCapture'] },
19
+ 'capture-bindtouchcancel': { bitFlag: 'h', events: ['onTouchCancelCapture'] },
20
+ 'capture-catchtap': { bitFlag: 'i', events: ['onTouchStartCapture', 'onTouchMoveCapture', 'onTouchEndCapture'] },
21
+ 'capture-catchlongpress': { bitFlag: 'j', events: ['onTouchStartCapture', 'onTouchMoveCapture', 'onTouchEndCapture', 'onTouchCancelCapture'] },
22
+ 'capture-catchtouchstart': { bitFlag: 'k', events: ['onTouchStartCapture'] },
23
+ 'capture-catchtouchmove': { bitFlag: 'l', events: ['onTouchMoveCapture'] },
24
+ 'capture-catchtouchend': { bitFlag: 'm', events: ['onTouchEndCapture'] },
25
+ 'capture-catchtouchcancel': { bitFlag: 'n', events: ['onTouchCancelCapture'] }
26
+ };
27
+ export default eventConfigMap;
@@ -0,0 +1,262 @@
1
+ import { useRef, useMemo } from 'react';
2
+ import { hasOwn, collectDataset } from '@mpxjs/utils';
3
+ import { omit, extendObject, useNavigation } from './utils';
4
+ import eventConfigMap from './event.config';
5
+ const globalEventState = {
6
+ needPress: true
7
+ };
8
+ const getTouchEvent = (type, event, props, config, navigation) => {
9
+ const { y: navigationY = 0 } = navigation?.layout || {};
10
+ const nativeEvent = event.nativeEvent;
11
+ const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent;
12
+ const { id } = props;
13
+ const { layoutRef } = config;
14
+ const currentTarget = extendObject({}, event.currentTarget, {
15
+ id: id || '',
16
+ dataset: collectDataset(props),
17
+ offsetLeft: layoutRef?.current?.offsetLeft || 0,
18
+ offsetTop: layoutRef?.current?.offsetTop || 0
19
+ });
20
+ const pendingProps = event._targetInst?.pendingProps || {};
21
+ const target = extendObject({}, event.target, {
22
+ id: pendingProps.parentId || pendingProps.nativeID || '',
23
+ dataset: collectDataset(pendingProps)
24
+ });
25
+ return extendObject({}, event, {
26
+ type,
27
+ timeStamp: timestamp,
28
+ currentTarget,
29
+ target,
30
+ detail: {
31
+ x: pageX,
32
+ y: pageY - navigationY
33
+ },
34
+ touches: touches.map((item) => {
35
+ return {
36
+ identifier: item.identifier,
37
+ pageX: item.pageX,
38
+ pageY: item.pageY - navigationY,
39
+ clientX: item.pageX,
40
+ clientY: item.pageY - navigationY
41
+ };
42
+ }),
43
+ changedTouches: changedTouches.map((item) => {
44
+ return {
45
+ identifier: item.identifier,
46
+ pageX: item.pageX,
47
+ pageY: item.pageY - navigationY,
48
+ clientX: item.pageX,
49
+ clientY: item.pageY - navigationY
50
+ };
51
+ }),
52
+ persist: event.persist,
53
+ stopPropagation: event.stopPropagation,
54
+ preventDefault: event.preventDefault
55
+ });
56
+ };
57
+ export const getCustomEvent = (type = '', oe = {}, { detail = {}, layoutRef }, props = {}) => {
58
+ const targetInfo = extendObject({}, oe.target, {
59
+ id: props.id || '',
60
+ dataset: collectDataset(props),
61
+ offsetLeft: layoutRef?.current?.offsetLeft || 0,
62
+ offsetTop: layoutRef?.current?.offsetTop || 0
63
+ });
64
+ return extendObject({}, oe, {
65
+ type,
66
+ detail,
67
+ target: targetInfo,
68
+ persist: oe.persist,
69
+ stopPropagation: oe.stopPropagation,
70
+ preventDefault: oe.preventDefault
71
+ });
72
+ };
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));
81
+ }
82
+ });
83
+ }
84
+ function checkIsNeedPress(e, type, ref) {
85
+ 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
+ if (Math.abs(currentPageX - tapDetailInfo.x) > 3 ||
90
+ Math.abs(currentPageY - tapDetailInfo.y) > 3) {
91
+ globalEventState.needPress = false;
92
+ ref.current.startTimer[type] &&
93
+ clearTimeout(ref.current.startTimer[type]);
94
+ ref.current.startTimer[type] = null;
95
+ }
96
+ }
97
+ function handleTouchstart(e, type, ref, propsRef, config, navigation) {
98
+ 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);
129
+ }
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
+ checkIsNeedPress(e, type, ref);
140
+ }
141
+ function handleTouchend(e, type, ref, propsRef, config, navigation) {
142
+ // move event may not be triggered
143
+ checkIsNeedPress(e, type, ref);
144
+ const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'];
145
+ const bubbleTapEvent = ['catchtap', 'bindtap'];
146
+ const captureTouchEvent = [
147
+ 'capture-catchtouchend',
148
+ 'capture-bindtouchend'
149
+ ];
150
+ const captureTapEvent = ['capture-catchtap', 'capture-bindtap'];
151
+ const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
152
+ const currentTapEvent = type === 'bubble' ? bubbleTapEvent : captureTapEvent;
153
+ ref.current.startTimer[type] &&
154
+ clearTimeout(ref.current.startTimer[type]);
155
+ ref.current.startTimer[type] = null;
156
+ handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation);
157
+ if (globalEventState.needPress) {
158
+ if (type === 'bubble' && config.disableTap) {
159
+ return;
160
+ }
161
+ handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation);
162
+ }
163
+ }
164
+ function handleTouchcancel(e, type, ref, propsRef, config, navigation) {
165
+ const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'];
166
+ const captureTouchEvent = [
167
+ 'capture-catchtouchcancel',
168
+ 'capture-bindtouchcancel'
169
+ ];
170
+ const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent;
171
+ ref.current.startTimer[type] &&
172
+ clearTimeout(ref.current.startTimer[type]);
173
+ ref.current.startTimer[type] = null;
174
+ handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation);
175
+ }
176
+ function createTouchEventHandler(eventName, type) {
177
+ return (e, ref, propsRef, config, navigation) => {
178
+ const handlerMap = {
179
+ onTouchStart: handleTouchstart,
180
+ onTouchMove: handleTouchmove,
181
+ onTouchEnd: handleTouchend,
182
+ onTouchCancel: handleTouchcancel
183
+ };
184
+ const handler = handlerMap[eventName];
185
+ if (handler) {
186
+ handler(e, type, ref, propsRef, config, navigation);
187
+ }
188
+ };
189
+ }
190
+ const touchEventList = [
191
+ { eventName: 'onTouchStart', handler: createTouchEventHandler('onTouchStart', 'bubble') },
192
+ { eventName: 'onTouchMove', handler: createTouchEventHandler('onTouchMove', 'bubble') },
193
+ { eventName: 'onTouchEnd', handler: createTouchEventHandler('onTouchEnd', 'bubble') },
194
+ { eventName: 'onTouchCancel', handler: createTouchEventHandler('onTouchCancel', 'bubble') },
195
+ { eventName: 'onTouchStartCapture', handler: createTouchEventHandler('onTouchStart', 'capture') },
196
+ { eventName: 'onTouchMoveCapture', handler: createTouchEventHandler('onTouchMove', 'capture') },
197
+ { eventName: 'onTouchEndCapture', handler: createTouchEventHandler('onTouchEnd', 'capture') },
198
+ { eventName: 'onTouchCancelCapture', handler: createTouchEventHandler('onTouchCancel', 'capture') }
199
+ ];
200
+ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], rawConfig) => {
201
+ const ref = useRef({
202
+ startTimer: {
203
+ bubble: null,
204
+ capture: null
205
+ },
206
+ mpxPressInfo: {
207
+ detail: {
208
+ x: 0,
209
+ y: 0
210
+ }
211
+ }
212
+ });
213
+ const propsRef = useRef({});
214
+ const eventConfig = {};
215
+ const config = rawConfig || {
216
+ layoutRef: { current: {} },
217
+ disableTap: false
218
+ };
219
+ const navigation = useNavigation();
220
+ const removeProps = [
221
+ 'children',
222
+ 'enable-background',
223
+ 'enable-offset',
224
+ 'enable-var',
225
+ 'external-var-context',
226
+ 'parent-font-size',
227
+ 'parent-width',
228
+ 'parent-height',
229
+ ...userRemoveProps
230
+ ];
231
+ propsRef.current = extendObject({}, props, additionalProps);
232
+ let hashEventKey = '';
233
+ const rawEventKeys = [];
234
+ for (const key in eventConfigMap) {
235
+ if (hasOwn(propsRef.current, key)) {
236
+ eventConfig[key] = eventConfigMap[key].events;
237
+ hashEventKey = hashEventKey + eventConfigMap[key].bitFlag;
238
+ rawEventKeys.push(key);
239
+ }
240
+ }
241
+ const events = useMemo(() => {
242
+ if (!rawEventKeys.length) {
243
+ return {};
244
+ }
245
+ const transformedEventKeys = rawEventKeys.reduce((acc, key) => {
246
+ if (propsRef.current[key]) {
247
+ return acc.concat(eventConfig[key]);
248
+ }
249
+ return acc;
250
+ }, []);
251
+ const finalEventKeys = [...new Set(transformedEventKeys)];
252
+ const events = {};
253
+ touchEventList.forEach((item) => {
254
+ if (finalEventKeys.includes(item.eventName)) {
255
+ events[item.eventName] = (e) => item.handler(e, ref, propsRef, config, navigation);
256
+ }
257
+ });
258
+ return events;
259
+ }, [hashEventKey]);
260
+ return extendObject({}, events, omit(propsRef.current, [...rawEventKeys, ...removeProps]));
261
+ };
262
+ export default useInnerProps;
@@ -0,0 +1,271 @@
1
+ /**
2
+ * ✔ size
3
+ * ✔ type
4
+ * ✔ plain
5
+ * ✔ disabled
6
+ * ✔ loading
7
+ * ✔ form-type
8
+ * - open-type: Partially. Only support `share`、`getUserInfo`
9
+ * ✔ hover-class: Convert hoverClass to hoverStyle.
10
+ * ✔ hover-style
11
+ * ✘ hover-stop-propagation
12
+ * ✔ hover-start-time
13
+ * ✔ hover-stay-time
14
+ * ✘ lang
15
+ * ✘ session-from
16
+ * ✘ send-message-title
17
+ * ✘ send-message-path
18
+ * ✘ send-message-img
19
+ * ✘ app-parameter
20
+ * ✘ show-message-card
21
+ * ✘ phone-number-no-quota-toast
22
+ * ✘ bindgetuserinfo
23
+ * ✘ bindcontact
24
+ * ✘ createliveactivity
25
+ * ✘ bindgetphonenumber
26
+ * ✘ bindgetphonenumber
27
+ * ✘ bindgetrealtimephonenumber
28
+ * ✘ binderror
29
+ * ✘ bindopensetting
30
+ * ✘ bindlaunchapp
31
+ * ✘ bindlaunchapp
32
+ * ✘ bindchooseavatar
33
+ * ✘ bindchooseavatar
34
+ * ✘ bindagreeprivacyauthorization
35
+ * ✔ bindtap
36
+ */
37
+ import { createElement, useEffect, useRef, forwardRef, useContext } from 'react';
38
+ import { View, StyleSheet, Animated, Easing } from 'react-native';
39
+ import { warn } from '@mpxjs/utils';
40
+ import { GestureDetector } from 'react-native-gesture-handler';
41
+ import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover } from './utils';
42
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
43
+ import useNodesRef from './useNodesRef';
44
+ import { RouteContext, FormContext } from './context';
45
+ const LOADING_IMAGE_URI = 'data:image/png;base64,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';
46
+ const TypeColorMap = {
47
+ default: ['#F8F8F8', '#DEDEDE', '35,35,35', '#F7F7F7'],
48
+ primary: ['#1AAD19', '#179B16', '26,173,25', '#9ED99D'],
49
+ warn: ['#E64340', '#CE3C39', '230,67,64', '#EC8B89']
50
+ };
51
+ const OpenTypeEventsMap = new Map([
52
+ ['share', 'onShareAppMessage'],
53
+ ['getUserInfo', 'onUserInfo']
54
+ ]);
55
+ const styles = StyleSheet.create({
56
+ button: {
57
+ width: '100%',
58
+ flexDirection: 'row',
59
+ justifyContent: 'center',
60
+ alignItems: 'center',
61
+ height: 46,
62
+ borderRadius: 5,
63
+ backgroundColor: '#F8F8F8',
64
+ marginHorizontal: 'auto' // 按钮默认居中
65
+ },
66
+ buttonMini: {
67
+ height: 30
68
+ },
69
+ text: {
70
+ fontSize: 18,
71
+ color: '#000000'
72
+ },
73
+ textMini: {
74
+ fontSize: 13
75
+ },
76
+ loading: {
77
+ width: 20,
78
+ height: 20
79
+ }
80
+ });
81
+ const getOpenTypeEvent = (openType) => {
82
+ if (!openType)
83
+ return;
84
+ if (!global.__mpx?.config?.rnConfig) {
85
+ warn('Environment not supported');
86
+ return;
87
+ }
88
+ const eventName = OpenTypeEventsMap.get(openType);
89
+ if (!eventName) {
90
+ warn(`open-type not support ${openType}`);
91
+ return;
92
+ }
93
+ const event = global.__mpx.config.rnConfig.openTypeHandler?.[eventName];
94
+ if (!event) {
95
+ warn(`Unregistered ${eventName} event`);
96
+ return;
97
+ }
98
+ return event;
99
+ };
100
+ const timer = (data, time = 3000) => new Promise((resolve) => {
101
+ setTimeout(() => {
102
+ resolve(data);
103
+ }, time);
104
+ });
105
+ const Loading = ({ alone = false }) => {
106
+ const image = useRef(new Animated.Value(0)).current;
107
+ const rotate = image.interpolate({
108
+ inputRange: [0, 1],
109
+ outputRange: ['0deg', '360deg']
110
+ });
111
+ useEffect(() => {
112
+ const animation = Animated.loop(Animated.timing(image, {
113
+ toValue: 1,
114
+ duration: 1000,
115
+ easing: Easing.linear,
116
+ useNativeDriver: true,
117
+ isInteraction: false
118
+ }));
119
+ animation.start();
120
+ return () => {
121
+ animation.stop();
122
+ };
123
+ }, []);
124
+ const loadingStyle = extendObject({}, styles.loading, {
125
+ transform: [{ rotate }],
126
+ marginRight: alone ? 0 : 5
127
+ });
128
+ return <Animated.Image testID="loading" style={loadingStyle} source={{ uri: LOADING_IMAGE_URI }}/>;
129
+ };
130
+ const Button = forwardRef((buttonProps, ref) => {
131
+ const { textProps, innerProps: props = {} } = splitProps(buttonProps);
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;
133
+ const { pageId } = useContext(RouteContext) || {};
134
+ const formContext = useContext(FormContext);
135
+ const enableHover = hoverClass !== 'none';
136
+ const { isHover, gesture } = useHover({ enableHover, hoverStartTime, hoverStayTime, disabled });
137
+ let submitFn;
138
+ let resetFn;
139
+ if (formContext) {
140
+ submitFn = formContext.submit;
141
+ resetFn = formContext.reset;
142
+ }
143
+ const isMiniSize = size === 'mini';
144
+ const [color, hoverColor, plainColor, disabledColor] = TypeColorMap[type];
145
+ const normalBackgroundColor = disabled ? disabledColor : isHover || loading ? hoverColor : color;
146
+ const plainBorderColor = disabled
147
+ ? 'rgba(0, 0, 0, .2)'
148
+ : isHover
149
+ ? `rgba(${plainColor},.6)`
150
+ : `rgb(${plainColor})`;
151
+ const normalBorderColor = type === 'default' ? 'rgba(0, 0, 0, .2)' : normalBackgroundColor;
152
+ const plainTextColor = disabled
153
+ ? 'rgba(0, 0, 0, .2)'
154
+ : isHover
155
+ ? `rgba(${plainColor}, .6)`
156
+ : `rgb(${plainColor})`;
157
+ const normalTextColor = type === 'default'
158
+ ? `rgba(0, 0, 0, ${disabled ? 0.3 : isHover || loading ? 0.6 : 1})`
159
+ : `rgba(255 ,255 ,255 , ${disabled || isHover || loading ? 0.6 : 1})`;
160
+ const viewStyle = {
161
+ borderWidth: 1,
162
+ borderStyle: 'solid',
163
+ borderColor: plain ? plainBorderColor : normalBorderColor,
164
+ backgroundColor: plain ? 'transparent' : normalBackgroundColor
165
+ };
166
+ const defaultViewStyle = extendObject({}, styles.button, isMiniSize ? styles.buttonMini : null, viewStyle);
167
+ const defaultTextStyle = extendObject({}, styles.text, isMiniSize ? styles.textMini : {}, { color: plain ? plainTextColor : normalTextColor });
168
+ const defaultStyle = extendObject({}, defaultViewStyle, defaultTextStyle);
169
+ const styleObj = extendObject({}, defaultStyle, style, isHover ? hoverStyle : {});
170
+ const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
171
+ const nodeRef = useRef(null);
172
+ useNodesRef(props, ref, nodeRef, { style: normalStyle });
173
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
174
+ const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle);
175
+ if (backgroundStyle) {
176
+ warn('Button does not support background image-related styles!');
177
+ }
178
+ const handleOpenTypeEvent = (evt) => {
179
+ const handleEvent = getOpenTypeEvent(openType);
180
+ if (!handleEvent)
181
+ return;
182
+ if (openType === 'share') {
183
+ const currentPage = getCurrentPage(pageId);
184
+ const event = {
185
+ from: 'button',
186
+ target: getCustomEvent('tap', evt, { layoutRef }, props).target,
187
+ webViewUrl: currentPage?.__webViewUrl
188
+ };
189
+ if (currentPage) {
190
+ const defaultMessage = {
191
+ title: global.__mpx.config.rnConfig.projectName || 'AwesomeProject',
192
+ path: currentPage.route || ''
193
+ };
194
+ if (currentPage.onShareAppMessage) {
195
+ const { promise, ...message } = currentPage.onShareAppMessage(event) || {};
196
+ if (promise) {
197
+ Promise.race([Promise.resolve(promise), timer(message)])
198
+ .then((msg) => {
199
+ handleEvent(Object.assign({}, defaultMessage, msg));
200
+ });
201
+ }
202
+ else {
203
+ handleEvent(Object.assign({}, defaultMessage, message));
204
+ }
205
+ }
206
+ else {
207
+ handleEvent(defaultMessage);
208
+ }
209
+ }
210
+ else {
211
+ warn('Current page not found');
212
+ // Todo handleEvent(event)
213
+ }
214
+ }
215
+ if (openType === 'getUserInfo' && bindgetuserinfo) {
216
+ Promise.resolve(handleEvent)
217
+ .then((userInfo) => {
218
+ if (typeof userInfo === 'object') {
219
+ bindgetuserinfo(userInfo);
220
+ }
221
+ });
222
+ }
223
+ };
224
+ const handleFormTypeFn = () => {
225
+ if (formType === 'submit') {
226
+ submitFn && submitFn();
227
+ }
228
+ else if (formType === 'reset') {
229
+ resetFn && resetFn();
230
+ }
231
+ };
232
+ const onTap = (evt) => {
233
+ if (disabled)
234
+ return;
235
+ bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props));
236
+ handleOpenTypeEvent(evt);
237
+ handleFormTypeFn();
238
+ };
239
+ const innerProps = useInnerProps(props, extendObject({
240
+ ref: nodeRef,
241
+ style: extendObject({}, innerStyle, layoutStyle)
242
+ }, layoutProps, {
243
+ bindtap: !disabled && onTap
244
+ }), [
245
+ 'disabled',
246
+ 'size',
247
+ 'type',
248
+ 'plain',
249
+ 'loading',
250
+ 'hover-class',
251
+ 'hover-style',
252
+ 'hover-start-time',
253
+ 'hover-stay-time',
254
+ 'open-type',
255
+ 'form-type'
256
+ ], {
257
+ layoutRef,
258
+ disableTap: disabled
259
+ });
260
+ const baseButton = createElement(View, innerProps, loading && createElement(Loading, { alone: !children }), wrapChildren(props, {
261
+ hasVarDec,
262
+ varContext: varContextRef.current,
263
+ textStyle,
264
+ textProps
265
+ }));
266
+ return enableHover
267
+ ? createElement(GestureDetector, { gesture: gesture }, baseButton)
268
+ : baseButton;
269
+ });
270
+ Button.displayName = 'MpxButton';
271
+ export default Button;