@mpxjs/webpack-plugin 2.10.6 → 2.10.7-beta.10

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 (51) hide show
  1. package/lib/dependencies/RecordPageConfigsMapDependency.js +1 -1
  2. package/lib/index.js +71 -51
  3. package/lib/parser.js +1 -1
  4. package/lib/platform/json/wx/index.js +0 -1
  5. package/lib/platform/style/wx/index.js +7 -0
  6. package/lib/platform/template/wx/component-config/button.js +1 -1
  7. package/lib/platform/template/wx/component-config/index.js +5 -1
  8. package/lib/platform/template/wx/component-config/input.js +1 -1
  9. package/lib/platform/template/wx/component-config/movable-view.js +1 -10
  10. package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
  11. package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
  12. package/lib/react/processJSON.js +2 -1
  13. package/lib/runtime/components/react/AsyncContainer.tsx +189 -0
  14. package/lib/runtime/components/react/context.ts +23 -4
  15. package/lib/runtime/components/react/dist/AsyncContainer.jsx +141 -0
  16. package/lib/runtime/components/react/dist/context.js +5 -2
  17. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -2
  18. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
  19. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +64 -10
  20. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +358 -98
  21. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +3 -0
  22. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +31 -15
  23. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +117 -0
  24. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  25. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +2 -2
  26. package/lib/runtime/components/react/dist/mpx-swiper.jsx +53 -27
  27. package/lib/runtime/components/react/dist/mpx-view.jsx +21 -7
  28. package/lib/runtime/components/react/dist/mpx-web-view.jsx +13 -13
  29. package/lib/runtime/components/react/dist/utils.jsx +94 -1
  30. package/lib/runtime/components/react/mpx-button.tsx +3 -2
  31. package/lib/runtime/components/react/mpx-input.tsx +1 -1
  32. package/lib/runtime/components/react/mpx-movable-area.tsx +99 -12
  33. package/lib/runtime/components/react/mpx-movable-view.tsx +413 -100
  34. package/lib/runtime/components/react/mpx-rich-text/index.tsx +3 -0
  35. package/lib/runtime/components/react/mpx-scroll-view.tsx +84 -59
  36. package/lib/runtime/components/react/mpx-sticky-header.tsx +181 -0
  37. package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
  38. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -2
  39. package/lib/runtime/components/react/mpx-swiper.tsx +53 -25
  40. package/lib/runtime/components/react/mpx-view.tsx +20 -7
  41. package/lib/runtime/components/react/mpx-web-view.tsx +12 -12
  42. package/lib/runtime/components/react/utils.tsx +93 -1
  43. package/lib/runtime/components/web/mpx-scroll-view.vue +18 -4
  44. package/lib/runtime/components/web/mpx-sticky-header.vue +99 -0
  45. package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
  46. package/lib/runtime/optionProcessor.js +0 -2
  47. package/lib/script-setup-compiler/index.js +27 -5
  48. package/lib/template-compiler/bind-this.js +2 -1
  49. package/lib/template-compiler/compiler.js +4 -3
  50. package/package.json +4 -4
  51. package/LICENSE +0 -433
@@ -0,0 +1,141 @@
1
+ import { Component, Suspense } from 'react';
2
+ import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native';
3
+ import FastImage from '@d11/react-native-fast-image';
4
+ const styles = StyleSheet.create({
5
+ container: {
6
+ flex: 1,
7
+ padding: 20,
8
+ backgroundColor: '#fff'
9
+ },
10
+ loadingImage: {
11
+ width: 100,
12
+ height: 100,
13
+ marginTop: 220,
14
+ alignSelf: 'center'
15
+ },
16
+ buttonText: {
17
+ color: '#fff',
18
+ fontSize: 16,
19
+ fontWeight: '500',
20
+ textAlign: 'center'
21
+ },
22
+ errorImage: {
23
+ marginTop: 80,
24
+ width: 220,
25
+ aspectRatio: 1,
26
+ alignSelf: 'center'
27
+ },
28
+ errorText: {
29
+ fontSize: 16,
30
+ textAlign: 'center',
31
+ color: '#333',
32
+ marginBottom: 20
33
+ },
34
+ retryButton: {
35
+ position: 'absolute',
36
+ bottom: 54,
37
+ left: 20,
38
+ right: 20,
39
+ backgroundColor: '#fff',
40
+ paddingVertical: 15,
41
+ borderRadius: 30,
42
+ marginTop: 40,
43
+ borderWidth: 1,
44
+ borderColor: '#FF5F00'
45
+ },
46
+ retryButtonText: {
47
+ color: '#FF5F00',
48
+ fontSize: 16,
49
+ fontWeight: '500',
50
+ textAlign: 'center'
51
+ }
52
+ });
53
+ const DefaultLoading = () => {
54
+ return (<View style={styles.container}>
55
+ <FastImage style={styles.loadingImage} source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/439jiCVOtNOnEv9F2LaDs_loading.gif' }} resizeMode={FastImage.resizeMode.contain}></FastImage>
56
+ </View>);
57
+ };
58
+ const DefaultFallback = ({ onReload }) => {
59
+ return (<View style={styles.container}>
60
+ <Image source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/Vak5mZvezPpKV5ZJI6P9b_drn-fallbak.png' }} style={styles.errorImage} resizeMode="contain"/>
61
+ <Text style={styles.errorText}>网络出了点问题,请查看网络环境</Text>
62
+ <TouchableOpacity style={styles.retryButton} onPress={onReload} activeOpacity={0.7}>
63
+ <Text style={styles.retryButtonText}>点击重试</Text>
64
+ </TouchableOpacity>
65
+ </View>);
66
+ };
67
+ export default class AsyncContainer extends Component {
68
+ suspenseFallback;
69
+ errorFallback;
70
+ constructor(props) {
71
+ super(props);
72
+ this.state = {
73
+ hasError: false,
74
+ key: 0
75
+ };
76
+ this.suspenseFallback = this.getSuspenseFallback();
77
+ this.errorFallback = this.getErrorFallback();
78
+ }
79
+ // render 阶段收集到的错误
80
+ static getDerivedStateFromError(error) {
81
+ if (error.name === 'ChunkLoadError') {
82
+ return {
83
+ hasError: true,
84
+ key: 0
85
+ };
86
+ }
87
+ else {
88
+ // 被外层捕获
89
+ throw error;
90
+ }
91
+ }
92
+ componentDidCatch(error) {
93
+ if (error.name === 'ChunkLoadError' && this.props.type === 'component') {
94
+ const request = error.request || '';
95
+ const subpackage = request.split('/').filter((i) => !!i)[0];
96
+ global.onLazyLoadError({
97
+ type: 'subpackage',
98
+ subpackage: [subpackage],
99
+ errMsg: `loadSubpackage: ${error.type}`
100
+ });
101
+ }
102
+ }
103
+ reloadPage() {
104
+ this.setState((prevState) => {
105
+ return {
106
+ hasError: false,
107
+ key: prevState.key + 1
108
+ };
109
+ });
110
+ }
111
+ getSuspenseFallback() {
112
+ if (this.props.type === 'page') {
113
+ const Fallback = this.props.loading || DefaultLoading;
114
+ return <Fallback />;
115
+ }
116
+ else {
117
+ const Fallback = this.props.loading;
118
+ return <Fallback {...this.props.props}></Fallback>;
119
+ }
120
+ }
121
+ getErrorFallback() {
122
+ if (this.props.type === 'page') {
123
+ const Fallback = this.props.fallback || DefaultFallback;
124
+ return <Fallback onReload={this.reloadPage.bind(this)}></Fallback>;
125
+ }
126
+ else {
127
+ const Fallback = this.props.loading;
128
+ return <Fallback {...this.props.props}></Fallback>;
129
+ }
130
+ }
131
+ render() {
132
+ if (this.state.hasError) {
133
+ return this.errorFallback;
134
+ }
135
+ else {
136
+ return (<Suspense fallback={this.suspenseFallback} key={this.state.key}>
137
+ {this.props.children(this.props.props)}
138
+ </Suspense>);
139
+ }
140
+ }
141
+ }
@@ -1,5 +1,7 @@
1
1
  import { createContext } from 'react';
2
- export const MovableAreaContext = createContext({ width: 0, height: 0 });
2
+ import { Animated } from 'react-native';
3
+ import { noop } from '@mpxjs/utils';
4
+ export const MovableAreaContext = createContext({ width: 0, height: 0, scaleArea: false });
3
5
  export const FormContext = createContext(null);
4
6
  export const CheckboxGroupContext = createContext(null);
5
7
  export const RadioGroupContext = createContext(null);
@@ -10,5 +12,6 @@ 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 });
@@ -35,7 +35,7 @@
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';
@@ -104,7 +104,7 @@ const timer = (data, time = 3000) => new Promise((resolve) => {
104
104
  }, time);
105
105
  });
106
106
  const Loading = ({ alone = false }) => {
107
- const image = useRef(new Animated.Value(0)).current;
107
+ const image = useAnimatedValue(0);
108
108
  const rotate = image.interpolate({
109
109
  inputRange: [0, 1],
110
110
  outputRange: ['0deg', '360deg']
@@ -91,7 +91,7 @@ const Input = forwardRef((props, ref) => {
91
91
  });
92
92
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
93
93
  useEffect(() => {
94
- if (inputValue !== value) {
94
+ if (value !== tmpValue.current) {
95
95
  const parsed = parseValue(value);
96
96
  tmpValue.current = parsed;
97
97
  setInputValue(parsed);
@@ -1,33 +1,87 @@
1
1
  /**
2
- * scale-area
2
+ * scale-area
3
3
  */
4
4
  import { View } from 'react-native';
5
- import { forwardRef, useRef, useMemo, createElement } from 'react';
5
+ import { forwardRef, useRef, useMemo, useCallback, createElement } from 'react';
6
+ import { GestureDetector, Gesture } from 'react-native-gesture-handler';
7
+ import { useSharedValue } from 'react-native-reanimated';
6
8
  import useNodesRef from './useNodesRef';
7
9
  import useInnerProps from './getInnerListeners';
8
10
  import { MovableAreaContext } from './context';
9
11
  import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils';
10
12
  import Portal from './mpx-portal';
11
13
  const _MovableArea = forwardRef((props, ref) => {
12
- const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
14
+ const { style = {}, 'scale-area': scaleArea = false, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
13
15
  const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, hasPositionFixed, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
14
- const movableViewRef = useRef(null);
15
- useNodesRef(props, ref, movableViewRef, {
16
+ const movableAreaRef = useRef(null);
17
+ const movableViewsValue = useSharedValue({});
18
+ useNodesRef(props, ref, movableAreaRef, {
16
19
  style: normalStyle
17
20
  });
21
+ // 注册/注销 MovableView 的回调
22
+ const registerMovableView = useCallback((id, callbacks) => {
23
+ movableViewsValue.value = extendObject(movableViewsValue.value, { [id]: callbacks });
24
+ }, []);
25
+ const unregisterMovableView = useCallback((id) => {
26
+ delete movableViewsValue.value[id];
27
+ }, []);
28
+ // 处理区域缩放手势
29
+ const handleAreaScale = useCallback((scaleInfo) => {
30
+ 'worklet';
31
+ if (scaleArea) {
32
+ // 将缩放信息广播给所有注册的 MovableView
33
+ Object.values(movableViewsValue.value).forEach((callbacks) => {
34
+ callbacks.onScale && callbacks.onScale(scaleInfo);
35
+ });
36
+ }
37
+ }, [scaleArea]);
38
+ // 处理区域缩放结束
39
+ const handleAreaScaleEnd = useCallback(() => {
40
+ 'worklet';
41
+ if (scaleArea) {
42
+ // 通知所有注册的 MovableView 缩放结束
43
+ Object.values(movableViewsValue.value).forEach((callbacks) => {
44
+ callbacks.onScaleEnd && callbacks.onScaleEnd();
45
+ });
46
+ }
47
+ }, [scaleArea]);
18
48
  const contextValue = useMemo(() => ({
19
49
  height: normalStyle.height || 10,
20
- width: normalStyle.width || 10
21
- }), [normalStyle.width, normalStyle.height]);
22
- const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef });
50
+ width: normalStyle.width || 10,
51
+ scaleArea,
52
+ registerMovableView,
53
+ unregisterMovableView
54
+ }), [normalStyle.width, normalStyle.height, scaleArea]);
55
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableAreaRef });
56
+ // 创建缩放手势
57
+ const scaleGesture = useMemo(() => {
58
+ if (!scaleArea)
59
+ return null;
60
+ return Gesture.Pinch()
61
+ .onUpdate((e) => {
62
+ 'worklet';
63
+ handleAreaScale(e);
64
+ })
65
+ .onEnd(() => {
66
+ 'worklet';
67
+ handleAreaScaleEnd();
68
+ });
69
+ }, [scaleArea]);
23
70
  const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
24
- style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
25
- ref: movableViewRef
71
+ style: extendObject({ height: contextValue.height, width: contextValue.width }, normalStyle, layoutStyle),
72
+ ref: movableAreaRef
26
73
  }), [], { layoutRef });
27
74
  let movableComponent = createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(View, innerProps, wrapChildren(props, {
28
75
  hasVarDec,
29
76
  varContext: varContextRef.current
30
77
  })));
78
+ // 如果启用了 scale-area,包装一个 GestureDetector
79
+ if (scaleArea && scaleGesture) {
80
+ movableComponent = createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(GestureDetector, { gesture: scaleGesture }, createElement(View, innerProps, wrapChildren(props, {
81
+ hasVarDec,
82
+ varContext: varContextRef.current
83
+ }))));
84
+ }
31
85
  if (hasPositionFixed) {
32
86
  movableComponent = createElement(Portal, null, movableComponent);
33
87
  }