@mpxjs/webpack-plugin 2.10.4 → 2.10.5

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 (70) hide show
  1. package/lib/platform/style/wx/index.js +22 -21
  2. package/lib/react/processScript.js +9 -1
  3. package/lib/react/script-helper.js +5 -1
  4. package/lib/runtime/components/react/dist/event.config.js +0 -2
  5. package/lib/runtime/components/react/dist/getInnerListeners.js +127 -153
  6. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -3
  7. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +3 -4
  8. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -2
  9. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -3
  10. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
  11. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -2
  12. package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
  13. package/lib/runtime/components/react/dist/mpx-input.jsx +17 -11
  14. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +22 -29
  15. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -3
  16. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +2 -2
  17. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
  18. package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
  19. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -2
  20. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +2 -3
  21. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +4 -4
  22. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -2
  23. package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -3
  24. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +2 -2
  25. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +1 -1
  26. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +3 -2
  27. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +3 -3
  28. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -5
  29. package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -9
  30. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -5
  31. package/lib/runtime/components/react/dist/mpx-text.jsx +4 -7
  32. package/lib/runtime/components/react/dist/mpx-video.jsx +2 -2
  33. package/lib/runtime/components/react/dist/mpx-view.jsx +13 -6
  34. package/lib/runtime/components/react/dist/useAnimationHooks.js +27 -4
  35. package/lib/runtime/components/react/dist/utils.jsx +85 -95
  36. package/lib/runtime/components/react/event.config.ts +1 -8
  37. package/lib/runtime/components/react/getInnerListeners.ts +146 -192
  38. package/lib/runtime/components/react/mpx-button.tsx +4 -5
  39. package/lib/runtime/components/react/mpx-canvas/index.tsx +23 -15
  40. package/lib/runtime/components/react/mpx-checkbox-group.tsx +4 -3
  41. package/lib/runtime/components/react/mpx-checkbox.tsx +8 -9
  42. package/lib/runtime/components/react/mpx-form.tsx +25 -19
  43. package/lib/runtime/components/react/mpx-icon/index.tsx +4 -3
  44. package/lib/runtime/components/react/mpx-image.tsx +4 -3
  45. package/lib/runtime/components/react/mpx-input.tsx +22 -15
  46. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +30 -41
  47. package/lib/runtime/components/react/mpx-label.tsx +4 -5
  48. package/lib/runtime/components/react/mpx-movable-area.tsx +22 -13
  49. package/lib/runtime/components/react/mpx-movable-view.tsx +47 -40
  50. package/lib/runtime/components/react/mpx-navigator.tsx +4 -6
  51. package/lib/runtime/components/react/mpx-picker/index.tsx +7 -4
  52. package/lib/runtime/components/react/mpx-picker-view/index.tsx +17 -14
  53. package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +4 -4
  54. package/lib/runtime/components/react/mpx-radio-group.tsx +4 -3
  55. package/lib/runtime/components/react/mpx-radio.tsx +8 -9
  56. package/lib/runtime/components/react/mpx-rich-text/index.tsx +15 -6
  57. package/lib/runtime/components/react/mpx-scroll-view.tsx +96 -90
  58. package/lib/runtime/components/react/mpx-simple-text.tsx +10 -3
  59. package/lib/runtime/components/react/mpx-simple-view.tsx +10 -4
  60. package/lib/runtime/components/react/mpx-swiper-item.tsx +31 -24
  61. package/lib/runtime/components/react/mpx-swiper.tsx +67 -61
  62. package/lib/runtime/components/react/mpx-switch.tsx +19 -14
  63. package/lib/runtime/components/react/mpx-text.tsx +16 -13
  64. package/lib/runtime/components/react/mpx-video.tsx +34 -33
  65. package/lib/runtime/components/react/mpx-view.tsx +30 -14
  66. package/lib/runtime/components/react/types/getInnerListeners.d.ts +65 -35
  67. package/lib/runtime/components/react/useAnimationHooks.ts +30 -9
  68. package/lib/runtime/components/react/utils.tsx +91 -98
  69. package/lib/template-compiler/compiler.js +1 -1
  70. package/package.json +3 -3
@@ -79,7 +79,7 @@ const Input = forwardRef((props, ref) => {
79
79
  const lineCount = useRef(0);
80
80
  const [inputValue, setInputValue] = useState(defaultValue);
81
81
  const [contentHeight, setContentHeight] = useState(0);
82
- const [selection, setSelection] = useState({ start: -1, end: -1 });
82
+ const [selection, setSelection] = useState({ start: -1, end: tmpValue.current.length });
83
83
  const styleObj = extendObject({ padding: 0, backgroundColor: '#fff' }, style, multiline && autoHeight
84
84
  ? { height: 'auto', minHeight: Math.max(style?.minHeight || 35, contentHeight) }
85
85
  : {});
@@ -91,15 +91,17 @@ const Input = forwardRef((props, ref) => {
91
91
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
92
92
  useEffect(() => {
93
93
  if (inputValue !== value) {
94
- setInputValue(parseValue(value));
94
+ const parsed = parseValue(value);
95
+ tmpValue.current = parsed;
96
+ setInputValue(parsed);
95
97
  }
96
98
  }, [value]);
97
99
  useEffect(() => {
98
- if (typeof cursor === 'number') {
99
- setSelection({ start: cursor, end: cursor });
100
+ if (selectionStart > -1) {
101
+ setSelection({ start: selectionStart, end: selectionEnd === -1 ? tmpValue.current.length : selectionEnd });
100
102
  }
101
- else if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart !== selectionEnd) {
102
- setSelection({ start: selectionStart, end: selectionEnd });
103
+ else if (typeof cursor === 'number') {
104
+ setSelection({ start: cursor, end: cursor });
103
105
  }
104
106
  }, [cursor, selectionStart, selectionEnd]);
105
107
  // have not selection on the Android platformg
@@ -149,6 +151,9 @@ const Input = forwardRef((props, ref) => {
149
151
  // sometimes the focus event occurs later than the keyboardWillShow event
150
152
  setKeyboardAvoidContext();
151
153
  };
154
+ const onTouchEnd = (evt) => {
155
+ evt.nativeEvent.origin = 'input';
156
+ };
152
157
  const onFocus = (evt) => {
153
158
  setKeyboardAvoidContext();
154
159
  bindfocus && bindfocus(getCustomEvent('focus', evt, {
@@ -208,6 +213,7 @@ const Input = forwardRef((props, ref) => {
208
213
  }
209
214
  };
210
215
  const resetValue = () => {
216
+ tmpValue.current = '';
211
217
  setInputValue('');
212
218
  };
213
219
  const getValue = () => {
@@ -241,7 +247,7 @@ const Input = forwardRef((props, ref) => {
241
247
  ? nodeRef.current?.focus()
242
248
  : nodeRef.current?.blur();
243
249
  }, [focus]);
244
- const innerProps = useInnerProps(props, extendObject({
250
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
245
251
  ref: nodeRef,
246
252
  style: extendObject({}, normalStyle, layoutStyle),
247
253
  allowFontScaling,
@@ -252,22 +258,22 @@ const Input = forwardRef((props, ref) => {
252
258
  maxLength: maxlength === -1 ? undefined : maxlength,
253
259
  editable: !disabled,
254
260
  autoFocus: !!autoFocus || !!focus,
255
- selection: selection,
261
+ selection: selectionStart > -1 || typeof cursor === 'number' ? selection : undefined,
256
262
  selectionColor: cursorColor,
257
263
  blurOnSubmit: !multiline && !confirmHold,
258
264
  underlineColorAndroid: 'rgba(0,0,0,0)',
259
265
  textAlignVertical: textAlignVertical,
260
266
  placeholderTextColor: placeholderStyle?.color,
261
- multiline: !!multiline
262
- }, !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }, layoutProps, {
267
+ multiline: !!multiline,
263
268
  onTouchStart,
269
+ onTouchEnd,
264
270
  onFocus,
265
271
  onBlur,
266
272
  onChange,
267
273
  onSelectionChange,
268
274
  onContentSizeChange,
269
275
  onSubmitEditing: bindconfirm && !multiline && onSubmitEditing
270
- }), [
276
+ }, !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }), [
271
277
  'type',
272
278
  'password',
273
279
  'placeholder-style',
@@ -1,7 +1,6 @@
1
- import React, { useContext, useEffect, useMemo } from 'react';
1
+ import React, { useContext, useEffect } from 'react';
2
2
  import { Keyboard, View } from 'react-native';
3
3
  import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
4
- import { GestureDetector, Gesture } from 'react-native-gesture-handler';
5
4
  import { KeyboardAvoidContext } from './context';
6
5
  import { isIOS } from './utils';
7
6
  const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
@@ -10,20 +9,10 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
10
9
  const offset = useSharedValue(0);
11
10
  const basic = useSharedValue('auto');
12
11
  const keyboardAvoid = useContext(KeyboardAvoidContext);
13
- const dismiss = () => {
14
- Keyboard.isVisible() && Keyboard.dismiss();
15
- };
16
- const gesture = useMemo(() => {
17
- return Gesture.Tap()
18
- .onEnd(() => {
19
- dismiss();
20
- }).runOnJS(true);
21
- }, []);
22
- const animatedStyle = useAnimatedStyle(() => {
23
- return Object.assign({
24
- transform: [{ translateY: -offset.value }]
25
- }, isIOS ? {} : { flexBasis: basic.value });
26
- });
12
+ const animatedStyle = useAnimatedStyle(() => ({
13
+ transform: [{ translateY: -offset.value }],
14
+ flexBasis: basic.value
15
+ }));
27
16
  const resetKeyboard = () => {
28
17
  if (keyboardAvoid?.current) {
29
18
  keyboardAvoid.current = null;
@@ -31,6 +20,11 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
31
20
  offset.value = withTiming(0, { duration, easing });
32
21
  basic.value = 'auto';
33
22
  };
23
+ const onTouchEnd = ({ nativeEvent }) => {
24
+ if (nativeEvent.origin !== 'input') {
25
+ Keyboard.isVisible() && Keyboard.dismiss();
26
+ }
27
+ };
34
28
  useEffect(() => {
35
29
  let subscriptions = [];
36
30
  if (isIOS) {
@@ -46,7 +40,12 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
46
40
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
47
41
  const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
48
42
  const value = aboveOffset > 0 ? belowValue : aboveValue;
49
- offset.value = withTiming(value, { duration, easing });
43
+ offset.value = withTiming(value, { duration, easing }, (finished) => {
44
+ if (finished) {
45
+ // Set flexBasic after animation to trigger re-layout and reset layout information
46
+ basic.value = '99.99%';
47
+ }
48
+ });
50
49
  });
51
50
  });
52
51
  }),
@@ -68,11 +67,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
68
67
  const value = aboveOffset > 0 ? belowValue : aboveValue;
69
68
  offset.value = withTiming(value, { duration, easing }, (finished) => {
70
69
  if (finished) {
71
- /**
72
- * In the Android environment, the layout information is not synchronized after the animation,
73
- * which results in the inability to correctly trigger element events.
74
- * Here, we utilize flexBasic to proactively trigger a re-layout
75
- */
70
+ // Set flexBasic after animation to trigger re-layout and reset layout information
76
71
  basic.value = '99.99%';
77
72
  }
78
73
  });
@@ -85,16 +80,14 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
85
80
  subscriptions.forEach(subscription => subscription.remove());
86
81
  };
87
82
  }, [keyboardAvoid]);
88
- return (<GestureDetector gesture={gesture}>
89
- <View style={style}>
90
- <Animated.View style={[
83
+ return (<View style={style} onTouchEnd={onTouchEnd}>
84
+ <Animated.View style={[
91
85
  contentContainerStyle,
92
86
  animatedStyle
93
87
  ]}>
94
- {children}
95
- </Animated.View>
96
- </View>
97
- </GestureDetector>);
88
+ {children}
89
+ </Animated.View>
90
+ </View>);
98
91
  };
99
92
  KeyboardAvoidingView.displayName = 'MpxKeyboardAvoidingView';
100
93
  export default KeyboardAvoidingView;
@@ -33,10 +33,9 @@ const Label = forwardRef((labelProps, ref) => {
33
33
  bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, { props: propsRef.current }));
34
34
  contextRef.current.triggerChange(evt);
35
35
  }, []);
36
- const innerProps = useInnerProps(props, extendObject({
36
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
37
37
  ref: nodeRef,
38
- style: extendObject({}, innerStyle, layoutStyle)
39
- }, layoutProps, {
38
+ style: extendObject({}, innerStyle, layoutStyle),
40
39
  bindtap: onTap
41
40
  }), [], {
42
41
  layoutRef
@@ -19,10 +19,10 @@ const _MovableArea = forwardRef((props, ref) => {
19
19
  width: normalStyle.width || 10
20
20
  }), [normalStyle.width, normalStyle.height]);
21
21
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef });
22
- const innerProps = useInnerProps(props, extendObject({
22
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
23
23
  style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
24
24
  ref: movableViewRef
25
- }, layoutProps), [], { layoutRef });
25
+ }), [], { layoutRef });
26
26
  return createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(View, innerProps, wrapChildren(props, {
27
27
  hasVarDec,
28
28
  varContext: varContextRef.current
@@ -452,7 +452,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
452
452
  'catchhtouchmove',
453
453
  'catchtouchend'
454
454
  ]);
455
- const innerProps = useInnerProps(filterProps, extendObject({
455
+ const innerProps = useInnerProps(extendObject({}, filterProps, {
456
456
  ref: nodeRef,
457
457
  onLayout: onLayout,
458
458
  style: [innerStyle, animatedStyles, layoutStyle]
@@ -1,5 +1,13 @@
1
+ /**
2
+ * ✔ hover-class
3
+ * ✘ hover-stop-propagation
4
+ * ✔ hover-start-time
5
+ * ✔ hover-stay-time
6
+ * ✔ open-type
7
+ * ✔ url
8
+ * ✔ delta
9
+ */
1
10
  import { useCallback, forwardRef, createElement } from 'react';
2
- import useInnerProps from './getInnerListeners';
3
11
  import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
4
12
  import MpxView from './mpx-view';
5
13
  const _Navigator = forwardRef((props, ref) => {
@@ -23,10 +31,10 @@ const _Navigator = forwardRef((props, ref) => {
23
31
  break;
24
32
  }
25
33
  }, [openType, url, delta]);
26
- const innerProps = useInnerProps(props, {
34
+ const innerProps = {
27
35
  ref,
28
36
  bindtap: handleClick
29
- });
37
+ };
30
38
  return createElement(MpxView, innerProps, children);
31
39
  });
32
40
  _Navigator.displayName = 'MpxNavigator';
@@ -114,9 +114,9 @@ const Picker = forwardRef((props, ref) => {
114
114
  const pickerRef = useRef(null);
115
115
  const { open, show, hide, remove } = useRef(createPopupManager()).current;
116
116
  useNodesRef(props, ref, nodeRef);
117
- const innerProps = useInnerProps(props, {
117
+ const innerProps = useInnerProps(extendObject({}, props, {
118
118
  ref: nodeRef
119
- }, [], { layoutRef: innerLayout });
119
+ }), [], { layoutRef: innerLayout });
120
120
  const getInnerLayout = (layout) => {
121
121
  innerLayout.current = layout.current;
122
122
  };
@@ -47,13 +47,12 @@ const _PickerView = forwardRef((props, ref) => {
47
47
  snapActiveValueRef.current = value.slice();
48
48
  }
49
49
  };
50
- const innerProps = useInnerProps(props, extendObject({
50
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
51
51
  ref: nodeRef,
52
52
  style: extendObject({}, normalStyle, layoutStyle, {
53
53
  position: 'relative',
54
54
  overflow: 'hidden'
55
- }),
56
- layoutProps
55
+ })
57
56
  }), [
58
57
  'enable-offset',
59
58
  'indicator-style',
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
3
  import Reanimated, { useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated';
4
- import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS } from '../utils';
4
+ import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS, isHarmony } from '../utils';
5
5
  import useNodesRef from '../useNodesRef';
6
6
  import PickerIndicator from './pickerViewIndicator';
7
7
  import PickerMask from './pickerViewMask';
@@ -143,9 +143,9 @@ const _PickerViewColumn = forwardRef((props, ref) => {
143
143
  }, [itemRawH]);
144
144
  const onScrollEndDrag = useCallback((e) => {
145
145
  dragging.current = false;
146
- if (isIOS) {
146
+ if (!isAndroid) {
147
147
  const { y } = e.nativeEvent.contentOffset;
148
- if (y % itemRawH === 0) {
148
+ if (y % itemRawH === 0 || (isHarmony && y > snapToOffsets[maxIndex])) {
149
149
  onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } });
150
150
  }
151
151
  else if (y > 0 && y < snapToOffsets[maxIndex]) {
@@ -221,7 +221,7 @@ const _PickerViewColumn = forwardRef((props, ref) => {
221
221
  });
222
222
  const renderScollView = () => {
223
223
  return (<PickerViewColumnAnimationContext.Provider value={offsetYShared}>
224
- <Reanimated.ScrollView ref={scrollViewRef} bounces={true} horizontal={false} nestedScrollEnabled={true} removeClippedSubviews={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} scrollEventThrottle={16} {...layoutProps} onTouchStart={onClickOnceItem} style={[{ width: '100%' }]} decelerationRate="fast" snapToOffsets={snapToOffsets} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} onScrollEndDrag={onScrollEndDrag} onMomentumScrollBegin={onMomentumScrollBegin} onMomentumScrollEnd={onMomentumScrollEnd} onContentSizeChange={onContentSizeChange} contentContainerStyle={contentContainerStyle}>
224
+ <Reanimated.ScrollView ref={scrollViewRef} bounces={true} horizontal={false} nestedScrollEnabled={true} removeClippedSubviews={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} scrollEventThrottle={16} {...layoutProps} onTouchEnd={onClickOnceItem} style={[{ width: '100%' }]} decelerationRate="fast" snapToOffsets={snapToOffsets} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} onScrollEndDrag={onScrollEndDrag} onMomentumScrollBegin={onMomentumScrollBegin} onMomentumScrollEnd={onMomentumScrollEnd} onContentSizeChange={onContentSizeChange} contentContainerStyle={contentContainerStyle}>
225
225
  {renderInnerchild()}
226
226
  </Reanimated.ScrollView>
227
227
  </PickerViewColumnAnimationContext.Provider>);
@@ -71,10 +71,10 @@ const radioGroup = forwardRef((props, ref) => {
71
71
  notifyChange
72
72
  };
73
73
  }, []);
74
- const innerProps = useInnerProps(props, extendObject({
74
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
75
75
  ref: nodeRef,
76
76
  style: extendObject({}, normalStyle, layoutStyle)
77
- }, layoutProps), ['name'], {
77
+ }), ['name'], {
78
78
  layoutRef
79
79
  });
80
80
  return createElement(View, innerProps, createElement(RadioGroupContext.Provider, { value: contextValue }, wrapChildren(props, {
@@ -91,10 +91,9 @@ const Radio = forwardRef((radioProps, ref) => {
91
91
  if (labelContext) {
92
92
  labelContext.current.triggerChange = onChange;
93
93
  }
94
- const innerProps = useInnerProps(props, extendObject({
94
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
95
95
  ref: nodeRef,
96
- style: extendObject({}, innerStyle, layoutStyle)
97
- }, layoutProps, {
96
+ style: extendObject({}, innerStyle, layoutStyle),
98
97
  bindtap: !disabled && onTap
99
98
  }), [
100
99
  'value',
@@ -44,10 +44,10 @@ const _RichText = forwardRef((props, ref) => {
44
44
  useNodesRef(props, ref, nodeRef, {
45
45
  layoutRef
46
46
  });
47
- const innerProps = useInnerProps(props, extendObject({
47
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
48
48
  ref: nodeRef,
49
49
  style: extendObject(normalStyle, layoutStyle)
50
- }, layoutProps), [], {
50
+ }), [], {
51
51
  layoutRef
52
52
  });
53
53
  const html = typeof nodes === 'string' ? nodes : jsonToHtmlStr(nodes);
@@ -491,7 +491,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
491
491
  pagingEnabled
492
492
  });
493
493
  }
494
- const innerProps = useInnerProps(props, scrollAdditionalProps, [
494
+ const innerProps = useInnerProps(extendObject({}, props, scrollAdditionalProps), [
495
495
  'id',
496
496
  'scroll-x',
497
497
  'scroll-y',
@@ -1,11 +1,12 @@
1
1
  import { Text } from 'react-native';
2
2
  import { createElement } from 'react';
3
3
  import useInnerProps from './getInnerListeners';
4
+ import { extendObject } from './utils';
4
5
  const SimpleText = (props) => {
5
6
  const { allowFontScaling = false, children } = props;
6
- const innerProps = useInnerProps(props, {
7
+ const innerProps = useInnerProps(extendObject({}, props, {
7
8
  allowFontScaling
8
- }, []);
9
+ }));
9
10
  return createElement(Text, innerProps, children);
10
11
  };
11
12
  SimpleText.displayName = 'MpxSimpleText';
@@ -1,13 +1,13 @@
1
1
  import { View } from 'react-native';
2
2
  import { createElement } from 'react';
3
- import { splitProps, splitStyle, wrapChildren } from './utils';
3
+ import { splitProps, splitStyle, wrapChildren, extendObject } from './utils';
4
4
  import useInnerProps from './getInnerListeners';
5
5
  const SimpleView = (simpleViewProps) => {
6
6
  const { textProps, innerProps: props = {} } = splitProps(simpleViewProps);
7
7
  const { textStyle, innerStyle = {} } = splitStyle(props.style || {});
8
- const innerProps = useInnerProps(props, {
8
+ const innerProps = useInnerProps(extendObject({}, props, {
9
9
  style: innerStyle
10
- }, []);
10
+ }));
11
11
  return createElement(View, innerProps, wrapChildren(props, {
12
12
  hasVarDec: false,
13
13
  textStyle: textStyle,
@@ -2,7 +2,7 @@ import Animated, { useAnimatedStyle, interpolate } from 'react-native-reanimated
2
2
  import { forwardRef, useRef, useContext } from 'react';
3
3
  import useInnerProps from './getInnerListeners';
4
4
  import useNodesRef from './useNodesRef'; // 引入辅助函数
5
- import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils';
5
+ import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject } from './utils';
6
6
  import { SwiperContext } from './context';
7
7
  const _SwiperItem = forwardRef((props, ref) => {
8
8
  const { 'enable-var': enableVar, 'external-var-context': externalVarContext, style, customStyle, itemIndex } = props;
@@ -21,10 +21,9 @@ const _SwiperItem = forwardRef((props, ref) => {
21
21
  const {
22
22
  // 存储layout布局信息
23
23
  layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: nodeRef });
24
- const innerProps = useInnerProps(props, {
25
- ref: nodeRef,
26
- ...layoutProps
27
- }, [
24
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
25
+ ref: nodeRef
26
+ }), [
28
27
  'children',
29
28
  'enable-offset',
30
29
  'style'
@@ -4,7 +4,7 @@ import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS
4
4
  import React, { forwardRef, useRef, useEffect, useMemo } from 'react';
5
5
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
6
6
  import useNodesRef from './useNodesRef'; // 引入辅助函数
7
- import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren } from './utils';
7
+ import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject } from './utils';
8
8
  import { SwiperContext } from './context';
9
9
  /**
10
10
  * 默认的Style类型
@@ -124,9 +124,9 @@ const SwiperWrapper = forwardRef((props, ref) => {
124
124
  const {
125
125
  // 存储layout布局信息
126
126
  layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef, onLayout: onWrapperLayout });
127
- const innerProps = useInnerProps(props, {
127
+ const innerProps = useInnerProps(extendObject({}, props, {
128
128
  ref: nodeRef
129
- }, [
129
+ }), [
130
130
  'style',
131
131
  'indicator-dots',
132
132
  'indicator-color',
@@ -187,8 +187,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
187
187
  dotAnimatedStyle
188
188
  ]}/>
189
189
  {dots}
190
- </View>
191
- </View>);
190
+ </View>
191
+ </View>);
192
192
  }
193
193
  function renderItems() {
194
194
  const intLen = children.length;
@@ -641,12 +641,12 @@ const SwiperWrapper = forwardRef((props, ref) => {
641
641
  function renderSwiper() {
642
642
  const arrPages = renderItems();
643
643
  return (<View style={[normalStyle, layoutStyle, styles.swiper]} {...layoutProps} {...innerProps}>
644
- <Animated.View style={[{
644
+ <Animated.View style={[{
645
645
  flexDirection: dir === 'x' ? 'row' : 'column',
646
646
  width: '100%',
647
647
  height: '100%'
648
648
  }, animatedStyles]}>
649
- {wrapChildren({
649
+ {wrapChildren({
650
650
  children: arrPages
651
651
  }, {
652
652
  hasVarDec,
@@ -654,8 +654,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
654
654
  textStyle,
655
655
  textProps
656
656
  })}
657
- </Animated.View>
658
- {showsPagination && renderPagination()}
657
+ </Animated.View>
658
+ {showsPagination && renderPagination()}
659
659
  </View>);
660
660
  }
661
661
  if (children.length === 1) {
@@ -67,17 +67,15 @@ const _Switch = forwardRef((props, ref) => {
67
67
  }
68
68
  };
69
69
  }, []);
70
- const innerProps = useInnerProps(props, extendObject({
70
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
71
71
  ref: nodeRef,
72
72
  style: extendObject({}, normalStyle, layoutStyle)
73
- }, layoutProps, !disabled ? { [type === 'switch' ? 'onValueChange' : '_onChange']: onChange } : {}), [
73
+ }, !disabled ? { [type === 'switch' ? 'onValueChange' : '_onChange']: onChange } : {}), [
74
74
  'checked',
75
75
  'disabled',
76
76
  'type',
77
77
  'color'
78
- ], {
79
- layoutRef
80
- });
78
+ ], { layoutRef });
81
79
  if (type === 'checkbox') {
82
80
  return createElement(CheckBox, extendObject({}, innerProps, {
83
81
  color: color,
@@ -7,10 +7,9 @@ import { Text } from 'react-native';
7
7
  import { useRef, forwardRef, createElement } from 'react';
8
8
  import useInnerProps from './getInnerListeners';
9
9
  import useNodesRef from './useNodesRef'; // 引入辅助函数
10
- import { useTransformStyle, wrapChildren } from './utils';
10
+ import { useTransformStyle, wrapChildren, extendObject } from './utils';
11
11
  const _Text = forwardRef((props, ref) => {
12
12
  const { style = {}, allowFontScaling = false, selectable, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'user-select': userSelect, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
13
- const layoutRef = useRef({});
14
13
  const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, {
15
14
  enableVar,
16
15
  externalVarContext,
@@ -22,16 +21,14 @@ const _Text = forwardRef((props, ref) => {
22
21
  useNodesRef(props, ref, nodeRef, {
23
22
  style: normalStyle
24
23
  });
25
- const innerProps = useInnerProps(props, {
24
+ const innerProps = useInnerProps(extendObject({}, props, {
26
25
  ref: nodeRef,
27
26
  style: normalStyle,
28
27
  selectable: !!selectable || !!userSelect,
29
28
  allowFontScaling
30
- }, [
29
+ }), [
31
30
  'user-select'
32
- ], {
33
- layoutRef
34
- });
31
+ ]);
35
32
  return createElement(Text, innerProps, wrapChildren(props, {
36
33
  hasVarDec,
37
34
  varContext: varContextRef.current
@@ -206,7 +206,7 @@ const MpxVideo = forwardRef((videoProps, ref) => {
206
206
  licenseServer: licenseUrl
207
207
  };
208
208
  }
209
- const innerProps = useInnerProps(props, extendObject({
209
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
210
210
  style: styles.video,
211
211
  ref: videoRef,
212
212
  source,
@@ -228,7 +228,7 @@ const MpxVideo = forwardRef((videoProps, ref) => {
228
228
  onFullscreenPlayerWillDismiss: bindfullscreenchange && handleExitFullScreen,
229
229
  onControlsVisibilityChange: bindcontrolstoggle && handleAndroidControlsVisibilityChange,
230
230
  onLoad: handleVideoLoad
231
- }, layoutProps), [
231
+ }), [
232
232
  'src',
233
233
  'autoplay',
234
234
  'loop',
@@ -11,7 +11,7 @@ import Animated from 'react-native-reanimated';
11
11
  import useAnimationHooks from './useAnimationHooks';
12
12
  import useNodesRef from './useNodesRef';
13
13
  import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHover } from './utils';
14
- import { error } from '@mpxjs/utils';
14
+ import { error, isFunction } from '@mpxjs/utils';
15
15
  import LinearGradient from 'react-native-linear-gradient';
16
16
  import { GestureDetector } from 'react-native-gesture-handler';
17
17
  import Portal from './mpx-portal';
@@ -543,7 +543,7 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
543
543
  }
544
544
  const _View = forwardRef((viewProps, ref) => {
545
545
  const { textProps, innerProps: props = {} } = splitProps(viewProps);
546
- let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
546
+ let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation, catchtransitionend, bindtransitionend } = props;
547
547
  // 默认样式
548
548
  const defaultStyle = style.display === 'flex'
549
549
  ? {
@@ -575,15 +575,22 @@ const _View = forwardRef((viewProps, ref) => {
575
575
  });
576
576
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
577
577
  const viewStyle = extendObject({}, innerStyle, layoutStyle);
578
+ const transitionend = isFunction(catchtransitionend)
579
+ ? catchtransitionend
580
+ : isFunction(bindtransitionend)
581
+ ? bindtransitionend
582
+ : undefined;
578
583
  const { enableStyleAnimation, animationStyle } = useAnimationHooks({
579
- enableAnimation,
584
+ layoutRef,
580
585
  animation,
581
- style: viewStyle
586
+ enableAnimation,
587
+ style: viewStyle,
588
+ transitionend
582
589
  });
583
- const innerProps = useInnerProps(props, extendObject({
590
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
584
591
  ref: nodeRef,
585
592
  style: enableStyleAnimation ? [viewStyle, animationStyle] : viewStyle
586
- }, layoutProps), [
593
+ }), [
587
594
  'hover-start-time',
588
595
  'hover-stay-time',
589
596
  'hover-style',
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useMemo, useRef } from 'react';
2
- import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation } from 'react-native-reanimated';
3
- import { error, hasOwn } from '@mpxjs/utils';
2
+ import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation, runOnJS } from 'react-native-reanimated';
3
+ import { error, hasOwn, collectDataset } from '@mpxjs/utils';
4
4
  // 微信 timingFunction 和 RN Easing 对应关系
5
5
  const EasingKey = {
6
6
  linear: Easing.linear,
@@ -140,7 +140,7 @@ function getTransformObj(transforms) {
140
140
  }, {});
141
141
  }
142
142
  export default function useAnimationHooks(props) {
143
- const { style = {}, animation, enableAnimation } = props;
143
+ const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props;
144
144
  const enableStyleAnimation = enableAnimation || !!animation;
145
145
  const enableAnimationRef = useRef(enableStyleAnimation);
146
146
  if (enableAnimationRef.current !== enableStyleAnimation) {
@@ -249,10 +249,33 @@ export default function useAnimationHooks(props) {
249
249
  });
250
250
  });
251
251
  }
252
+ function withTimingCallback(finished, current, duration) {
253
+ if (!transitionend)
254
+ return;
255
+ const target = {
256
+ id: animation?.id || -1,
257
+ dataset: collectDataset(props),
258
+ offsetLeft: layoutRef?.current?.offsetLeft || 0,
259
+ offsetTop: layoutRef?.current?.offsetTop || 0
260
+ };
261
+ transitionend({
262
+ type: 'transitionend',
263
+ // elapsedTime 对齐wx 单位s
264
+ detail: { elapsedTime: duration ? duration / 1000 : 0, finished, current },
265
+ target,
266
+ currentTarget: target,
267
+ timeStamp: Date.now()
268
+ });
269
+ }
252
270
  // 创建单个animation
253
271
  function getAnimation({ key, value }, { delay, duration, easing }, callback) {
254
272
  const animation = typeof callback === 'function'
255
- ? withTiming(value, { duration, easing }, callback)
273
+ ? withTiming(value, { duration, easing }, (finished, current) => {
274
+ callback(finished, current);
275
+ if (transitionend && finished) {
276
+ runOnJS(withTimingCallback)(finished, current, duration);
277
+ }
278
+ })
256
279
  : withTiming(value, { duration, easing });
257
280
  return delay ? withDelay(delay, animation) : animation;
258
281
  }