@mpxjs/webpack-plugin 2.10.4-beta.19-input → 2.10.4-beta.19-input1

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 (34) hide show
  1. package/lib/runtime/components/react/dist/getInnerListeners.js +22 -36
  2. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -7
  3. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +4 -2
  4. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +17 -20
  5. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -7
  6. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -7
  7. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -7
  8. package/lib/runtime/components/react/dist/mpx-image.jsx +20 -33
  9. package/lib/runtime/components/react/dist/mpx-input.jsx +9 -14
  10. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -7
  11. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -8
  12. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +79 -205
  13. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +13 -11
  14. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +7 -8
  15. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +11 -29
  16. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +5 -3
  17. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -9
  18. package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -7
  19. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +2 -10
  20. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +51 -104
  21. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +1 -3
  22. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +9 -11
  23. package/lib/runtime/components/react/dist/mpx-swiper.jsx +141 -203
  24. package/lib/runtime/components/react/dist/mpx-switch.jsx +2 -7
  25. package/lib/runtime/components/react/dist/mpx-text.jsx +2 -7
  26. package/lib/runtime/components/react/dist/mpx-video.jsx +2 -7
  27. package/lib/runtime/components/react/dist/mpx-view.jsx +26 -28
  28. package/lib/runtime/components/react/dist/mpx-web-view.jsx +29 -34
  29. package/lib/runtime/components/react/dist/useAnimationHooks.js +89 -12
  30. package/lib/runtime/components/react/dist/utils.jsx +114 -199
  31. package/package.json +1 -1
  32. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +0 -145
  33. package/lib/runtime/components/react/dist/mpx-progress.jsx +0 -163
  34. package/lib/runtime/components/react/dist/mpx-slider.jsx +0 -321
@@ -68,7 +68,6 @@ import { StyleSheet, View } from 'react-native';
68
68
  import { splitProps, useTransformStyle, useLayout, extendObject } from './utils';
69
69
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
70
70
  import useNodesRef from './useNodesRef';
71
- import Portal from './mpx-portal';
72
71
  const styles = StyleSheet.create({
73
72
  container: {
74
73
  width: 300,
@@ -86,7 +85,7 @@ const MpxVideo = forwardRef((videoProps, ref) => {
86
85
  const videoInfoRef = useRef({});
87
86
  const propsRef = useRef({});
88
87
  propsRef.current = props;
89
- const { normalStyle, hasSelfPercent, setWidth, setHeight, hasPositionFixed } = useTransformStyle(extendObject({}, styles.container, style), {
88
+ const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(extendObject({}, styles.container, style), {
90
89
  enableVar,
91
90
  externalVarContext,
92
91
  parentFontSize,
@@ -244,10 +243,6 @@ const MpxVideo = forwardRef((videoProps, ref) => {
244
243
  'bindcontrolstoggle',
245
244
  'bindseekcomplete'
246
245
  ], { layoutRef });
247
- let videoComponent = createElement(View, { style: extendObject({}, normalStyle, layoutStyle), ref: viewRef }, createElement(Video, innerProps));
248
- if (hasPositionFixed) {
249
- videoComponent = createElement(Portal, null, videoComponent);
250
- }
251
- return videoComponent;
246
+ return createElement(View, { style: extendObject({}, normalStyle, layoutStyle), ref: viewRef }, createElement(Video, innerProps));
252
247
  });
253
248
  export default MpxVideo;
@@ -57,7 +57,7 @@ const normalizeStyle = (style = {}) => {
57
57
  const isPercent = (val) => typeof val === 'string' && PERCENT_REGEX.test(val);
58
58
  const isBackgroundSizeKeyword = (val) => typeof val === 'string' && /^cover|contain$/.test(val);
59
59
  const isNeedLayout = (preImageInfo) => {
60
- const { sizeList, backgroundPosition, linearInfo, type } = preImageInfo;
60
+ const { sizeList, backgroundPosition, linearInfo } = preImageInfo;
61
61
  const [width, height] = sizeList;
62
62
  const bp = backgroundPosition;
63
63
  // 含有百分号,center 需计算布局
@@ -66,8 +66,7 @@ const isNeedLayout = (preImageInfo) => {
66
66
  (isPercent(width) && height === 'auto') ||
67
67
  isPercent(bp[1]) ||
68
68
  isPercent(bp[3]) ||
69
- isDiagonalAngle(linearInfo) ||
70
- (type === 'linear' && (isPercent(height) || isPercent(width)));
69
+ isDiagonalAngle(linearInfo);
71
70
  };
72
71
  const checkNeedLayout = (preImageInfo) => {
73
72
  const { sizeList } = preImageInfo;
@@ -156,7 +155,7 @@ function backgroundPosition(imageProps, preImageInfo, imageSize, layoutInfo) {
156
155
  }
157
156
  // background-size 转换
158
157
  function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
159
- const { sizeList, type } = preImageInfo;
158
+ const sizeList = preImageInfo.sizeList;
160
159
  if (!sizeList)
161
160
  return;
162
161
  const { width: layoutWidth, height: layoutHeight } = layoutInfo || {};
@@ -203,20 +202,10 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
203
202
  else { // 数值类型 ImageStyle
204
203
  // 数值类型设置为 stretch
205
204
  imageProps.resizeMode = 'stretch';
206
- if (type === 'linear' && (!layoutWidth || !layoutHeight)) {
207
- // ios linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来
208
- // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。
209
- dimensions = {
210
- width: 0,
211
- height: 0
212
- };
213
- }
214
- else {
215
- dimensions = {
216
- width: isPercent(width) ? width : +width,
217
- height: isPercent(height) ? height : +height
218
- };
219
- }
205
+ dimensions = {
206
+ width: isPercent(width) ? width : +width,
207
+ height: isPercent(height) ? height : +height
208
+ };
220
209
  }
221
210
  }
222
211
  // 样式合并
@@ -534,8 +523,10 @@ function useWrapImage(imageStyle, innerStyle, enableFastImage) {
534
523
  setShow(true);
535
524
  }
536
525
  };
537
- const backgroundProps = extendObject({ key: 'backgroundImage' }, needLayout ? { onLayout } : {}, { style: extendObject({}, inheritStyle(innerStyle), StyleSheet.absoluteFillObject, { overflow: 'hidden' }) });
538
- return createElement(View, backgroundProps, show && type === 'linear' && createElement(LinearGradient, extendObject({ useAngle: true }, imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current))), show && type === 'image' && renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage));
526
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
527
+ {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
528
+ {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage))}
529
+ </View>;
539
530
  }
540
531
  function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }) {
541
532
  const children = wrapChildren(props, {
@@ -588,14 +579,21 @@ const _View = forwardRef((viewProps, ref) => {
588
579
  ? catchtransitionend
589
580
  : isFunction(bindtransitionend)
590
581
  ? bindtransitionend
591
- : undefined;
592
- const { enableStyleAnimation, animationStyle } = useAnimationHooks({
593
- layoutRef,
594
- animation,
595
- enableAnimation,
596
- style: viewStyle,
597
- transitionend
598
- });
582
+ : null;
583
+ const { enableStyleAnimation, animationStyle } = useAnimationHooks(transitionend
584
+ ? {
585
+ layoutRef,
586
+ animation,
587
+ enableAnimation,
588
+ style: viewStyle,
589
+ transitionend
590
+ }
591
+ : {
592
+ layoutRef,
593
+ animation,
594
+ enableAnimation,
595
+ style: viewStyle
596
+ });
599
597
  const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
600
598
  ref: nodeRef,
601
599
  style: enableStyleAnimation ? [viewStyle, animationStyle] : viewStyle
@@ -1,7 +1,6 @@
1
1
  import { forwardRef, useRef, useContext, useMemo, useState } from 'react';
2
2
  import { warn, isFunction } from '@mpxjs/utils';
3
3
  import Portal from './mpx-portal/index';
4
- import { usePreventRemove } from '@react-navigation/native';
5
4
  import { getCustomEvent } from './getInnerListeners';
6
5
  import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
7
6
  import { WebView } from 'react-native-webview';
@@ -56,8 +55,8 @@ const _WebView = forwardRef((props, ref) => {
56
55
  const webViewRef = useRef(null);
57
56
  const fristLoaded = useRef(false);
58
57
  const isLoadError = useRef(false);
59
- const isNavigateBack = useRef(false);
60
58
  const statusCode = useRef('');
59
+ const [isLoaded, setIsLoaded] = useState(true);
61
60
  const defaultWebViewStyle = {
62
61
  position: 'absolute',
63
62
  left: 0,
@@ -65,40 +64,33 @@ const _WebView = forwardRef((props, ref) => {
65
64
  top: 0,
66
65
  bottom: 0
67
66
  };
68
- const navigation = useNavigation();
69
- const [isIntercept, setIsIntercept] = useState(false);
70
- usePreventRemove(isIntercept, (event) => {
71
- const { data } = event;
72
- if (isNavigateBack.current) {
73
- navigation?.dispatch(data.action);
74
- }
75
- else {
67
+ const canGoBack = useRef(false);
68
+ const isNavigateBack = useRef(false);
69
+ const beforeRemoveHandle = (e) => {
70
+ if (canGoBack.current && !isNavigateBack.current) {
76
71
  webViewRef.current?.goBack();
72
+ e.preventDefault();
77
73
  }
78
74
  isNavigateBack.current = false;
79
- });
75
+ };
76
+ const navigation = useNavigation();
77
+ // useEffect(() => {
78
+ // let beforeRemoveSubscription:any
79
+ // if (__mpx_mode__ !== 'ios') {
80
+ // beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
81
+ // }
82
+ // return () => {
83
+ // if (isFunction(beforeRemoveSubscription)) {
84
+ // beforeRemoveSubscription()
85
+ // }
86
+ // }
87
+ // }, [])
80
88
  useNodesRef(props, ref, webViewRef, {
81
89
  style: defaultWebViewStyle
82
90
  });
83
- const hostValidate = (url) => {
84
- const host = url && new URL(url).host;
85
- const hostWhitelists = mpx.config.rnConfig?.webviewConfig?.hostWhitelists || [];
86
- if (hostWhitelists.length) {
87
- return hostWhitelists.some((item) => {
88
- return host.endsWith(item);
89
- });
90
- }
91
- else {
92
- return true;
93
- }
94
- };
95
91
  if (!src) {
96
92
  return null;
97
93
  }
98
- if (!hostValidate(src)) {
99
- console.error('访问页面域名不符合domainWhiteLists白名单配置,请确认是否正确配置该域名白名单');
100
- return null;
101
- }
102
94
  const _reload = function () {
103
95
  if (__mpx_mode__ !== 'ios') {
104
96
  fristLoaded.current = false; // 安卓需要重新设置
@@ -139,19 +131,16 @@ const _WebView = forwardRef((props, ref) => {
139
131
  };
140
132
  const _changeUrl = function (navState) {
141
133
  if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
134
+ canGoBack.current = navState.canGoBack;
142
135
  currentPage.__webViewUrl = navState.url;
143
- setIsIntercept(navState.canGoBack);
144
136
  }
145
137
  };
146
138
  const _onLoadProgress = function (event) {
147
139
  if (__mpx_mode__ !== 'ios') {
148
- setIsIntercept(event.nativeEvent.canGoBack);
140
+ canGoBack.current = event.nativeEvent.canGoBack;
149
141
  }
150
142
  };
151
143
  const _message = function (res) {
152
- if (!hostValidate(res.nativeEvent?.url)) {
153
- return;
154
- }
155
144
  let data = {};
156
145
  let asyncCallback;
157
146
  const navObj = promisify({ redirectTo, navigateTo, navigateBack, reLaunch, switchTab });
@@ -203,7 +192,7 @@ const _WebView = forwardRef((props, ref) => {
203
192
  break;
204
193
  default:
205
194
  if (type) {
206
- const implement = mpx.config.rnConfig.webviewConfig && mpx.config.rnConfig.webviewConfig.apiImplementations && mpx.config.rnConfig.webviewConfig.apiImplementations[type];
195
+ const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type];
207
196
  if (isFunction(implement)) {
208
197
  asyncCallback = Promise.resolve(implement(...params));
209
198
  }
@@ -238,6 +227,7 @@ const _WebView = forwardRef((props, ref) => {
238
227
  };
239
228
  const onLoadEndHandle = function (res) {
240
229
  fristLoaded.current = true;
230
+ setIsLoaded(true);
241
231
  const src = res.nativeEvent?.url;
242
232
  if (isLoadError.current) {
243
233
  isLoadError.current = false;
@@ -285,13 +275,18 @@ const _WebView = forwardRef((props, ref) => {
285
275
  setPageLoadErr(true);
286
276
  }
287
277
  };
278
+ const onLoadStart = function () {
279
+ if (!fristLoaded.current) {
280
+ setIsLoaded(false);
281
+ }
282
+ };
288
283
  return (<Portal>
289
284
  {pageLoadErr
290
285
  ? (<View style={[styles.loadErrorContext, defaultWebViewStyle]}>
291
286
  <View style={styles.loadErrorText}><Text style={{ fontSize: 14, color: '#999999' }}>{currentErrorText.text}</Text></View>
292
287
  <View style={styles.loadErrorButton} onTouchEnd={_reload}><Text style={{ fontSize: 12, color: '#666666' }}>{currentErrorText.button}</Text></View>
293
288
  </View>)
294
- : (<WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} allowsBackForwardNavigationGestures={true}></WebView>)}
289
+ : (<WebView style={defaultWebViewStyle} pointerEvents={isLoaded ? 'auto' : 'none'} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} onLoadStart={onLoadStart} allowsBackForwardNavigationGestures={true}></WebView>)}
295
290
  </Portal>);
296
291
  });
297
292
  _WebView.displayName = 'MpxWebview';
@@ -1,7 +1,6 @@
1
1
  import { useEffect, useMemo, useRef } from 'react';
2
2
  import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation, runOnJS } from 'react-native-reanimated';
3
3
  import { error, hasOwn, collectDataset } from '@mpxjs/utils';
4
- import { useRunOnJSCallback } from './utils';
5
4
  // 微信 timingFunction 和 RN Easing 对应关系
6
5
  const EasingKey = {
7
6
  linear: Easing.linear,
@@ -49,6 +48,90 @@ const InitialValue = Object.assign({
49
48
  const TransformOrigin = 'transformOrigin';
50
49
  // transform
51
50
  const isTransform = (key) => Object.keys(TransformInitial).includes(key);
51
+ // 多value解析
52
+ const parseValues = (str, char = ' ') => {
53
+ let stack = 0;
54
+ let temp = '';
55
+ const result = [];
56
+ for (let i = 0; i < str.length; i++) {
57
+ if (str[i] === '(') {
58
+ stack++;
59
+ }
60
+ else if (str[i] === ')') {
61
+ stack--;
62
+ }
63
+ // 非括号内 或者 非分隔字符且非空
64
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
65
+ temp += str[i];
66
+ }
67
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
68
+ result.push(temp);
69
+ temp = '';
70
+ }
71
+ }
72
+ return result;
73
+ };
74
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
75
+ const parseTransform = (transformStr) => {
76
+ const values = parseValues(transformStr);
77
+ const transform = [];
78
+ values.forEach(item => {
79
+ const match = item.match(/([/\w]+)\((.+)\)/);
80
+ if (match && match.length >= 3) {
81
+ let key = match[1];
82
+ const val = match[2];
83
+ switch (key) {
84
+ case 'translateX':
85
+ case 'translateY':
86
+ case 'scaleX':
87
+ case 'scaleY':
88
+ case 'rotateX':
89
+ case 'rotateY':
90
+ case 'rotateZ':
91
+ case 'rotate':
92
+ case 'skewX':
93
+ case 'skewY':
94
+ case 'perspective':
95
+ // rotate 处理成 rotateZ
96
+ key = key === 'rotate' ? 'rotateZ' : key;
97
+ // 单个值处理
98
+ transform.push({ [key]: global.__formatValue(val) });
99
+ break;
100
+ case 'matrix':
101
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) });
102
+ break;
103
+ case 'translate':
104
+ case 'scale':
105
+ case 'skew':
106
+ case 'translate3d': // x y 支持 z不支持
107
+ case 'scale3d': // x y 支持 z不支持
108
+ {
109
+ // 2 个以上的值处理
110
+ key = key.replace('3d', '');
111
+ const vals = parseValues(val, ',').splice(0, 3);
112
+ // scale(.5) === scaleX(.5) scaleY(.5)
113
+ if (vals.length === 1 && key === 'scale') {
114
+ vals.push(vals[0]);
115
+ }
116
+ const xyz = ['X', 'Y', 'Z'];
117
+ transform.push(...vals.map((v, index) => {
118
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
119
+ }));
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ });
125
+ return transform;
126
+ };
127
+ // format style
128
+ const formatStyle = (style) => {
129
+ if (!style.transform || Array.isArray(style.transform))
130
+ return style;
131
+ return Object.assign({}, style, {
132
+ transform: parseTransform(style.transform)
133
+ });
134
+ };
52
135
  // transform 数组转对象
53
136
  function getTransformObj(transforms) {
54
137
  'worklet';
@@ -57,7 +140,7 @@ function getTransformObj(transforms) {
57
140
  }, {});
58
141
  }
59
142
  export default function useAnimationHooks(props) {
60
- const { style: originalStyle = {}, animation, enableAnimation, transitionend, layoutRef } = props;
143
+ const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props;
61
144
  const enableStyleAnimation = enableAnimation || !!animation;
62
145
  const enableAnimationRef = useRef(enableStyleAnimation);
63
146
  if (enableAnimationRef.current !== enableStyleAnimation) {
@@ -65,6 +148,7 @@ export default function useAnimationHooks(props) {
65
148
  }
66
149
  if (!enableAnimationRef.current)
67
150
  return { enableStyleAnimation: false };
151
+ const originalStyle = formatStyle(style);
68
152
  // id 标识
69
153
  const id = animation?.id || -1;
70
154
  // 有动画样式的 style key
@@ -93,7 +177,7 @@ export default function useAnimationHooks(props) {
93
177
  useEffect(() => {
94
178
  // style 更新后同步更新 lastStyleRef & shareValMap
95
179
  updateStyleVal();
96
- }, [originalStyle]);
180
+ }, [style]);
97
181
  // ** 获取动画样式prop & 驱动动画
98
182
  // eslint-disable-next-line react-hooks/rules-of-hooks
99
183
  useEffect(() => {
@@ -176,26 +260,19 @@ export default function useAnimationHooks(props) {
176
260
  };
177
261
  transitionend({
178
262
  type: 'transitionend',
179
- // elapsedTime 对齐wx 单位s
180
- detail: { elapsedTime: duration ? duration / 1000 : 0, finished, current },
263
+ detail: { elapsedTime: duration, finished, current },
181
264
  target,
182
265
  currentTarget: target,
183
266
  timeStamp: Date.now()
184
267
  });
185
268
  }
186
- // eslint-disable-next-line react-hooks/rules-of-hooks
187
- const runOnJSCallbackRef = useRef({
188
- withTimingCallback
189
- });
190
- // eslint-disable-next-line react-hooks/rules-of-hooks
191
- const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
192
269
  // 创建单个animation
193
270
  function getAnimation({ key, value }, { delay, duration, easing }, callback) {
194
271
  const animation = typeof callback === 'function'
195
272
  ? withTiming(value, { duration, easing }, (finished, current) => {
196
273
  callback(finished, current);
197
274
  if (transitionend && finished) {
198
- runOnJS(runOnJSCallback)('withTimingCallback', finished, current, duration);
275
+ runOnJS(withTimingCallback)(finished, current, duration);
199
276
  }
200
277
  })
201
278
  : withTiming(value, { duration, easing });