@mpxjs/webpack-plugin 2.10.5 → 2.10.6-beta.2

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 (92) hide show
  1. package/lib/dependencies/WriteVfsDependency.js +46 -0
  2. package/lib/index.js +22 -6
  3. package/lib/json-compiler/helper.js +1 -4
  4. package/lib/platform/index.js +4 -2
  5. package/lib/platform/json/wx/index.js +0 -1
  6. package/lib/platform/template/wx/component-config/button.js +1 -1
  7. package/lib/platform/template/wx/component-config/index.js +7 -3
  8. package/lib/platform/template/wx/component-config/input.js +1 -1
  9. package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
  10. package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
  11. package/lib/platform/template/wx/component-config/template.js +26 -1
  12. package/lib/platform/template/wx/index.js +31 -4
  13. package/lib/react/processJSON.js +7 -6
  14. package/lib/resolver/PackageEntryPlugin.js +3 -1
  15. package/lib/runtime/components/react/context.ts +12 -3
  16. package/lib/runtime/components/react/dist/context.js +4 -1
  17. package/lib/runtime/components/react/dist/mpx-button.jsx +9 -4
  18. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
  19. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +20 -17
  20. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +7 -2
  21. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +7 -2
  22. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +7 -2
  23. package/lib/runtime/components/react/dist/mpx-image.jsx +9 -2
  24. package/lib/runtime/components/react/dist/mpx-input.jsx +7 -2
  25. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +1 -1
  26. package/lib/runtime/components/react/dist/mpx-label.jsx +7 -2
  27. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +8 -3
  28. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +100 -62
  29. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +11 -13
  30. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +8 -7
  31. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +26 -8
  32. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +9 -2
  33. package/lib/runtime/components/react/dist/mpx-radio.jsx +7 -2
  34. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +7 -2
  35. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +30 -10
  36. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +115 -0
  37. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  38. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +11 -9
  39. package/lib/runtime/components/react/dist/mpx-swiper.jsx +82 -36
  40. package/lib/runtime/components/react/dist/mpx-switch.jsx +7 -2
  41. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -2
  42. package/lib/runtime/components/react/dist/mpx-video.jsx +7 -2
  43. package/lib/runtime/components/react/dist/mpx-view.jsx +2 -4
  44. package/lib/runtime/components/react/dist/mpx-web-view.jsx +13 -13
  45. package/lib/runtime/components/react/dist/utils.jsx +14 -3
  46. package/lib/runtime/components/react/mpx-button.tsx +12 -3
  47. package/lib/runtime/components/react/mpx-canvas/Image.ts +4 -4
  48. package/lib/runtime/components/react/mpx-canvas/index.tsx +24 -17
  49. package/lib/runtime/components/react/mpx-checkbox-group.tsx +9 -1
  50. package/lib/runtime/components/react/mpx-checkbox.tsx +9 -1
  51. package/lib/runtime/components/react/mpx-icon/index.tsx +9 -1
  52. package/lib/runtime/components/react/mpx-image.tsx +38 -19
  53. package/lib/runtime/components/react/mpx-input.tsx +10 -1
  54. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
  55. package/lib/runtime/components/react/mpx-label.tsx +9 -1
  56. package/lib/runtime/components/react/mpx-movable-area.tsx +8 -2
  57. package/lib/runtime/components/react/mpx-movable-view.tsx +100 -62
  58. package/lib/runtime/components/react/mpx-picker/index.tsx +18 -16
  59. package/lib/runtime/components/react/mpx-picker-view/index.tsx +22 -8
  60. package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +34 -30
  61. package/lib/runtime/components/react/mpx-radio-group.tsx +20 -9
  62. package/lib/runtime/components/react/mpx-radio.tsx +9 -1
  63. package/lib/runtime/components/react/mpx-rich-text/index.tsx +10 -2
  64. package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -53
  65. package/lib/runtime/components/react/mpx-sticky-header.tsx +179 -0
  66. package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
  67. package/lib/runtime/components/react/mpx-swiper-item.tsx +11 -19
  68. package/lib/runtime/components/react/mpx-swiper.tsx +95 -38
  69. package/lib/runtime/components/react/mpx-switch.tsx +10 -2
  70. package/lib/runtime/components/react/mpx-text.tsx +10 -2
  71. package/lib/runtime/components/react/mpx-video.tsx +7 -2
  72. package/lib/runtime/components/react/mpx-view.tsx +8 -4
  73. package/lib/runtime/components/react/mpx-web-view.tsx +12 -12
  74. package/lib/runtime/components/react/utils.tsx +16 -5
  75. package/lib/runtime/components/web/mpx-scroll-view.vue +21 -4
  76. package/lib/runtime/components/web/mpx-sticky-header.vue +91 -0
  77. package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
  78. package/lib/runtime/components/web/mpx-web-view.vue +1 -1
  79. package/lib/runtime/mpxGlobal.js +1 -0
  80. package/lib/runtime/optionProcessor.d.ts +5 -0
  81. package/lib/runtime/optionProcessor.js +2 -2
  82. package/lib/template-compiler/bind-this.js +8 -7
  83. package/lib/template-compiler/compiler.js +59 -9
  84. package/lib/utils/get-template-content.js +47 -0
  85. package/lib/web/index.js +2 -0
  86. package/lib/web/processScript.js +29 -7
  87. package/lib/web/processTemplate.js +10 -4
  88. package/lib/web/template2vue.js +280 -0
  89. package/lib/web/wxml-template-loader.js +29 -0
  90. package/lib/wxs/pre-loader.js +1 -0
  91. package/package.json +4 -4
  92. package/LICENSE +0 -433
@@ -23,6 +23,7 @@ import './CanvasGradient';
23
23
  import { createImage as canvasCreateImage } from './Image';
24
24
  import { createImageData as canvasCreateImageData } from './ImageData';
25
25
  import { useConstructorsRegistry } from './constructorsRegistry';
26
+ import Portal from '../mpx-portal';
26
27
  const stylesheet = StyleSheet.create({
27
28
  container: { overflow: 'hidden', flex: 0 },
28
29
  webview: {
@@ -41,7 +42,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
41
42
  const { style = {}, originWhitelist = ['*'], 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
42
43
  const [isLoaded, setIsLoaded] = useState(false);
43
44
  const nodeRef = useRef(null);
44
- const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(extendObject({}, style, stylesheet.container), {
45
+ const { normalStyle, hasSelfPercent, hasPositionFixed, setWidth, setHeight } = useTransformStyle(extendObject({}, style, stylesheet.container), {
45
46
  enableVar,
46
47
  externalVarContext,
47
48
  parentFontSize,
@@ -110,10 +111,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
110
111
  const postMessage = useCallback(async (message) => {
111
112
  if (!canvasRef.current?.bus)
112
113
  return;
113
- const { type, payload } = await canvasRef.current.bus.post({
114
- id: ID(),
115
- ...message
116
- });
114
+ const { type, payload } = await canvasRef.current.bus.post(extendObject({ id: ID() }, message));
117
115
  switch (type) {
118
116
  case 'error': {
119
117
  const { binderror } = props;
@@ -142,7 +140,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
142
140
  canvasRef.current.listeners.splice(canvasRef.current.listeners.indexOf(listener), 1);
143
141
  };
144
142
  const onMessage = useCallback((e) => {
145
- let data = JSON.parse(e.nativeEvent.data);
143
+ const data = JSON.parse(e.nativeEvent.data);
146
144
  switch (data.type) {
147
145
  case 'error': {
148
146
  const { binderror } = props;
@@ -156,27 +154,27 @@ const _Canvas = forwardRef((props = {}, ref) => {
156
154
  break;
157
155
  }
158
156
  default: {
157
+ const newData = {};
158
+ // createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
159
+ const constructor = constructors[data.meta.constructor];
159
160
  if (data.payload) {
160
- // createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
161
- const constructor = constructors[data.meta.constructor];
162
161
  if (constructor) {
163
162
  const { args, payload } = data;
164
163
  // RN 端同步生成一个 CanvasGradient 的实例
165
164
  const object = constructor.constructLocally(canvasRef.current, ...args);
166
- Object.assign(object, payload, {
165
+ extendObject(object, payload, {
167
166
  [WEBVIEW_TARGET]: data.meta.target
168
167
  });
169
- data = {
170
- ...data,
168
+ extendObject(newData, data, {
171
169
  payload: object
172
- };
170
+ });
173
171
  }
174
172
  for (const listener of canvasRef.current.listeners) {
175
- listener(data.payload);
173
+ listener(constructor ? newData.payload : data.payload);
176
174
  }
177
175
  }
178
176
  if (canvasRef.current.bus) {
179
- canvasRef.current.bus.handle(data);
177
+ canvasRef.current.bus.handle(constructor && data.payload ? newData : data);
180
178
  }
181
179
  }
182
180
  }
@@ -192,9 +190,10 @@ const _Canvas = forwardRef((props = {}, ref) => {
192
190
  node: canvasRef.current,
193
191
  context: context2D
194
192
  });
195
- if (__mpx_mode__ !== 'ios') {
193
+ let canvasComponent;
194
+ if (__mpx_mode__ === 'android') {
196
195
  const isAndroid9 = Platform.Version >= 28;
197
- return createElement(View, innerProps, createElement(WebView, {
196
+ canvasComponent = createElement(View, innerProps, createElement(WebView, {
198
197
  ref: (element) => {
199
198
  if (canvasRef.current) {
200
199
  canvasRef.current.webview = element;
@@ -217,7 +216,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
217
216
  allowUniversalAccessFromFileURLs: true
218
217
  }));
219
218
  }
220
- return createElement(View, innerProps, createElement(WebView, {
219
+ canvasComponent = createElement(View, innerProps, createElement(WebView, {
221
220
  ref: (element) => {
222
221
  if (canvasRef.current) {
223
222
  canvasRef.current.webview = element;
@@ -230,6 +229,10 @@ const _Canvas = forwardRef((props = {}, ref) => {
230
229
  onLoad: onLoad,
231
230
  scrollEnabled: false
232
231
  }));
232
+ if (hasPositionFixed) {
233
+ canvasComponent = createElement(Portal, null, canvasComponent);
234
+ }
235
+ return canvasComponent;
233
236
  });
234
237
  _Canvas.displayName = 'mpxCanvas';
235
238
  export default _Canvas;
@@ -8,6 +8,7 @@ import { FormContext, CheckboxGroupContext } from './context';
8
8
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
9
9
  import useNodesRef from './useNodesRef';
10
10
  import { useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
11
+ import Portal from './mpx-portal';
11
12
  const CheckboxGroup = forwardRef((props, ref) => {
12
13
  const propsRef = useRef({});
13
14
  propsRef.current = props;
@@ -23,7 +24,7 @@ const CheckboxGroup = forwardRef((props, ref) => {
23
24
  flexWrap: 'wrap'
24
25
  };
25
26
  const styleObj = extendObject({}, defaultStyle, style);
26
- const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
27
+ const { hasPositionFixed, hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
27
28
  const nodeRef = useRef(null);
28
29
  useNodesRef(props, ref, nodeRef, { style: normalStyle });
29
30
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
@@ -81,10 +82,14 @@ const CheckboxGroup = forwardRef((props, ref) => {
81
82
  notifyChange
82
83
  };
83
84
  }, []);
84
- return createElement(View, innerProps, createElement(CheckboxGroupContext.Provider, { value: contextValue }, wrapChildren(props, {
85
+ const finalComponent = createElement(View, innerProps, createElement(CheckboxGroupContext.Provider, { value: contextValue }, wrapChildren(props, {
85
86
  hasVarDec,
86
87
  varContext: varContextRef.current
87
88
  })));
89
+ if (hasPositionFixed) {
90
+ return createElement(Portal, null, finalComponent);
91
+ }
92
+ return finalComponent;
88
93
  });
89
94
  CheckboxGroup.displayName = 'MpxCheckboxGroup';
90
95
  export default CheckboxGroup;
@@ -12,6 +12,7 @@ import useNodesRef from './useNodesRef';
12
12
  import Icon from './mpx-icon';
13
13
  import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
14
14
  import { CheckboxGroupContext, LabelContext } from './context';
15
+ import Portal from './mpx-portal';
15
16
  const styles = StyleSheet.create({
16
17
  container: {
17
18
  flexDirection: 'row',
@@ -63,7 +64,7 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
63
64
  bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props));
64
65
  onChange(evt);
65
66
  };
66
- const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
67
+ const { hasPositionFixed, hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
67
68
  const nodeRef = useRef(null);
68
69
  useNodesRef(props, ref, nodeRef, {
69
70
  style: extendObject({}, defaultStyle, normalStyle),
@@ -114,7 +115,7 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
114
115
  }
115
116
  }
116
117
  }, [checked]);
117
- return createElement(View, innerProps, createElement(View, { style: defaultStyle }, createElement(Icon, {
118
+ const finalComponent = createElement(View, innerProps, createElement(View, { style: defaultStyle }, createElement(Icon, {
118
119
  type: 'success_no_circle',
119
120
  size: 18,
120
121
  color: disabled ? '#ADADAD' : color,
@@ -125,6 +126,10 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
125
126
  textStyle,
126
127
  textProps
127
128
  }));
129
+ if (hasPositionFixed) {
130
+ return createElement(Portal, null, finalComponent);
131
+ }
132
+ return finalComponent;
128
133
  });
129
134
  Checkbox.displayName = 'MpxCheckbox';
130
135
  export default Checkbox;
@@ -17,6 +17,7 @@ import Cancel from './icons/cancel.png';
17
17
  import Download from './icons/download.png';
18
18
  import Search from './icons/search.png';
19
19
  import Clear from './icons/clear.png';
20
+ import Portal from '../mpx-portal';
20
21
  const IconTypeMap = new Map([
21
22
  ['success', Success],
22
23
  ['success_no_circle', SuccessNoCircle],
@@ -33,7 +34,7 @@ const Icon = forwardRef((props, ref) => {
33
34
  const source = IconTypeMap.get(type);
34
35
  const defaultStyle = { width: ~~size, height: ~~size };
35
36
  const styleObj = extendObject({}, defaultStyle, style);
36
- const { hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
37
+ const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
37
38
  const nodeRef = useRef(null);
38
39
  useNodesRef(props, ref, nodeRef, { style: normalStyle });
39
40
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
@@ -44,7 +45,11 @@ const Icon = forwardRef((props, ref) => {
44
45
  }), [], {
45
46
  layoutRef
46
47
  });
47
- return createElement(Image, innerProps);
48
+ const finalComponent = createElement(Image, innerProps);
49
+ if (hasPositionFixed) {
50
+ return createElement(Portal, null, finalComponent);
51
+ }
52
+ return finalComponent;
48
53
  });
49
54
  Icon.displayName = 'MpxIcon';
50
55
  export default Icon;
@@ -17,6 +17,7 @@ import { SvgCssUri } from 'react-native-svg/css';
17
17
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
18
18
  import useNodesRef from './useNodesRef';
19
19
  import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils';
20
+ import Portal from './mpx-portal';
20
21
  const DEFAULT_IMAGE_WIDTH = 320;
21
22
  const DEFAULT_IMAGE_HEIGHT = 240;
22
23
  const cropMode = [
@@ -79,7 +80,7 @@ const Image = forwardRef((props, ref) => {
79
80
  setLoaded(true);
80
81
  }
81
82
  };
82
- const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
83
+ const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
83
84
  const { layoutRef, layoutStyle, layoutProps } = useLayout({
84
85
  props,
85
86
  hasSelfPercent,
@@ -255,6 +256,8 @@ const Image = forwardRef((props, ref) => {
255
256
  state.current = {};
256
257
  setLoaded(true);
257
258
  }
259
+ }, () => {
260
+ setLoaded(true);
258
261
  });
259
262
  }
260
263
  }, [src, isSvg, isLayoutMode]);
@@ -286,7 +289,11 @@ const Image = forwardRef((props, ref) => {
286
289
  }, isCropMode ? modeStyle : {})
287
290
  }, isLayoutMode ? {} : innerProps), enableFastImage);
288
291
  const LayoutImage = createElement(View, innerProps, loaded && BaseImage);
289
- return isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage;
292
+ const finalComponent = isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage;
293
+ if (hasPositionFixed) {
294
+ return createElement(Portal, null, finalComponent);
295
+ }
296
+ return finalComponent;
290
297
  });
291
298
  Image.displayName = 'mpx-image';
292
299
  export default Image;
@@ -44,6 +44,7 @@ import { useUpdateEffect, useTransformStyle, useLayout, extendObject, isIOS } fr
44
44
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
45
45
  import useNodesRef from './useNodesRef';
46
46
  import { FormContext, KeyboardAvoidContext } from './context';
47
+ import Portal from './mpx-portal';
47
48
  const keyboardTypeMap = {
48
49
  text: 'default',
49
50
  number: 'numeric',
@@ -83,7 +84,7 @@ const Input = forwardRef((props, ref) => {
83
84
  const styleObj = extendObject({ padding: 0, backgroundColor: '#fff' }, style, multiline && autoHeight
84
85
  ? { height: 'auto', minHeight: Math.max(style?.minHeight || 35, contentHeight) }
85
86
  : {});
86
- const { hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
87
+ const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
87
88
  const nodeRef = useRef(null);
88
89
  useNodesRef(props, ref, nodeRef, {
89
90
  style: normalStyle
@@ -289,7 +290,11 @@ const Input = forwardRef((props, ref) => {
289
290
  ], {
290
291
  layoutRef
291
292
  });
292
- return createElement(TextInput, innerProps);
293
+ const finalComponent = createElement(TextInput, innerProps);
294
+ if (hasPositionFixed) {
295
+ return createElement(Portal, null, finalComponent);
296
+ }
297
+ return finalComponent;
293
298
  });
294
299
  Input.displayName = 'MpxInput';
295
300
  export default Input;
@@ -36,7 +36,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
36
36
  const { ref, cursorSpacing = 0 } = keyboardAvoid.current;
37
37
  setTimeout(() => {
38
38
  ref?.current?.measure((x, y, width, height, pageX, pageY) => {
39
- const aboveOffset = pageY + height - endCoordinates.screenY;
39
+ const aboveOffset = offset.value + pageY + height - endCoordinates.screenY;
40
40
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
41
41
  const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
42
42
  const value = aboveOffset > 0 ? belowValue : aboveValue;
@@ -8,6 +8,7 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners';
8
8
  import useNodesRef from './useNodesRef';
9
9
  import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
10
10
  import { LabelContext } from './context';
11
+ import Portal from './mpx-portal';
11
12
  const Label = forwardRef((labelProps, ref) => {
12
13
  const { textProps, innerProps: props = {} } = splitProps(labelProps);
13
14
  const propsRef = useRef({});
@@ -17,7 +18,7 @@ const Label = forwardRef((labelProps, ref) => {
17
18
  flexDirection: 'row'
18
19
  };
19
20
  const styleObj = extendObject({}, defaultStyle, style);
20
- const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
21
+ const { hasPositionFixed, hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
21
22
  const nodeRef = useRef(null);
22
23
  useNodesRef(props, ref, nodeRef, { style: normalStyle });
23
24
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
@@ -40,12 +41,16 @@ const Label = forwardRef((labelProps, ref) => {
40
41
  }), [], {
41
42
  layoutRef
42
43
  });
43
- return createElement(View, innerProps, createElement(LabelContext.Provider, { value: contextRef }, wrapChildren(props, {
44
+ const finalComponent = createElement(View, innerProps, createElement(LabelContext.Provider, { value: contextRef }, wrapChildren(props, {
44
45
  hasVarDec,
45
46
  varContext: varContextRef.current,
46
47
  textStyle,
47
48
  textProps
48
49
  })));
50
+ if (hasPositionFixed) {
51
+ return createElement(Portal, null, finalComponent);
52
+ }
53
+ return finalComponent;
49
54
  });
50
55
  Label.displayName = 'MpxLabel';
51
56
  export default Label;
@@ -7,9 +7,10 @@ import useNodesRef from './useNodesRef';
7
7
  import useInnerProps from './getInnerListeners';
8
8
  import { MovableAreaContext } from './context';
9
9
  import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils';
10
+ import Portal from './mpx-portal';
10
11
  const _MovableArea = forwardRef((props, ref) => {
11
12
  const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
12
- const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
13
+ const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, hasPositionFixed, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
13
14
  const movableViewRef = useRef(null);
14
15
  useNodesRef(props, ref, movableViewRef, {
15
16
  style: normalStyle
@@ -20,13 +21,17 @@ const _MovableArea = forwardRef((props, ref) => {
20
21
  }), [normalStyle.width, normalStyle.height]);
21
22
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef });
22
23
  const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
23
- style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
24
+ style: extendObject({ height: contextValue.height, width: contextValue.width }, normalStyle, layoutStyle),
24
25
  ref: movableViewRef
25
26
  }), [], { layoutRef });
26
- return createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(View, innerProps, wrapChildren(props, {
27
+ let movableComponent = createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(View, innerProps, wrapChildren(props, {
27
28
  hasVarDec,
28
29
  varContext: varContextRef.current
29
30
  })));
31
+ if (hasPositionFixed) {
32
+ movableComponent = createElement(Portal, null, movableComponent);
33
+ }
34
+ return movableComponent;
30
35
  });
31
36
  _MovableArea.displayName = 'MpxMovableArea';
32
37
  export default _MovableArea;
@@ -24,7 +24,7 @@ import useNodesRef from './useNodesRef';
24
24
  import { MovableAreaContext } from './context';
25
25
  import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject, omit, useNavigation } from './utils';
26
26
  import { GestureDetector, Gesture } from 'react-native-gesture-handler';
27
- import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, useAnimatedReaction, withSpring } from 'react-native-reanimated';
27
+ import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, withSpring } from 'react-native-reanimated';
28
28
  import { collectDataset, noop } from '@mpxjs/utils';
29
29
  const styles = StyleSheet.create({
30
30
  container: {
@@ -41,7 +41,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
41
41
  const hasLayoutRef = useRef(false);
42
42
  const propsRef = useRef({});
43
43
  propsRef.current = (props || {});
44
- const { x = 0, y = 0, inertia = false, disabled = false, animation = true, 'out-of-bounds': outOfBounds = false, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, direction = 'none', 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, bindtouchstart, catchtouchstart, bindhtouchmove, bindvtouchmove, bindtouchmove, catchhtouchmove, catchvtouchmove, catchtouchmove, bindtouchend, catchtouchend } = props;
44
+ const { x = 0, y = 0, inertia = false, disabled = false, animation = true, 'out-of-bounds': outOfBounds = false, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, direction = 'none', 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, bindtouchstart, catchtouchstart, bindhtouchmove, bindvtouchmove, bindtouchmove, catchhtouchmove, catchvtouchmove, catchtouchmove, bindtouchend, catchtouchend, bindchange } = props;
45
45
  const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(Object.assign({}, style, styles.container), { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
46
46
  const navigation = useNavigation();
47
47
  const prevSimultaneousHandlersRef = useRef(originSimultaneousHandlers || []);
@@ -61,6 +61,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
61
61
  const yInertialMotion = useSharedValue(false);
62
62
  const isFirstTouch = useSharedValue(true);
63
63
  const touchEvent = useSharedValue('');
64
+ const initialViewPosition = useSharedValue({ x: x || 0, y: y || 0 });
64
65
  const MovableAreaLayout = useContext(MovableAreaContext);
65
66
  const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
66
67
  const waitForHandlers = flatGesture(waitFor);
@@ -118,11 +119,13 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
118
119
  })
119
120
  : newY;
120
121
  }
121
- runOnJS(handleTriggerChange)({
122
- x: newX,
123
- y: newY,
124
- type: 'setData'
125
- });
122
+ if (bindchange) {
123
+ runOnJS(handleTriggerChange)({
124
+ x: newX,
125
+ y: newY,
126
+ type: 'setData'
127
+ });
128
+ }
126
129
  }
127
130
  })();
128
131
  }, [x, y]);
@@ -132,16 +135,6 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
132
135
  resetBoundaryAndCheck({ width, height });
133
136
  }
134
137
  }, [MovableAreaLayout.height, MovableAreaLayout.width]);
135
- useAnimatedReaction(() => ({
136
- offsetX: offsetX.value,
137
- offsetY: offsetY.value
138
- }), (currentValue) => {
139
- const { offsetX, offsetY } = currentValue;
140
- runOnJS(handleTriggerChange)({
141
- x: offsetX,
142
- y: offsetY
143
- });
144
- });
145
138
  const getTouchSource = useCallback((offsetX, offsetY) => {
146
139
  const hasOverBoundary = offsetX < draggableXRange.value[0] || offsetX > draggableXRange.value[1] ||
147
140
  offsetY < draggableYRange.value[0] || offsetY > draggableYRange.value[1];
@@ -259,11 +252,13 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
259
252
  });
260
253
  }, []);
261
254
  const triggerStartOnJS = ({ e }) => {
255
+ const { bindtouchstart, catchtouchstart } = propsRef.current;
262
256
  extendEvent(e, 'start');
263
257
  bindtouchstart && bindtouchstart(e);
264
258
  catchtouchstart && catchtouchstart(e);
265
259
  };
266
260
  const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }) => {
261
+ const { bindhtouchmove, bindvtouchmove, bindtouchmove, catchhtouchmove, catchvtouchmove, catchtouchmove } = propsRef.current;
267
262
  extendEvent(e, 'move');
268
263
  if (hasTouchmove) {
269
264
  if (touchEvent === 'htouchmove') {
@@ -285,6 +280,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
285
280
  }
286
281
  };
287
282
  const triggerEndOnJS = ({ e }) => {
283
+ const { bindtouchend, catchtouchend } = propsRef.current;
288
284
  extendEvent(e, 'end');
289
285
  bindtouchend && bindtouchend(e);
290
286
  catchtouchend && catchtouchend(e);
@@ -315,6 +311,13 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
315
311
  if (bindtouchstart || catchtouchstart) {
316
312
  runOnJS(triggerStartOnJS)({ e });
317
313
  }
314
+ })
315
+ .onStart(() => {
316
+ 'worklet';
317
+ initialViewPosition.value = {
318
+ x: offsetX.value,
319
+ y: offsetY.value
320
+ };
318
321
  })
319
322
  .onTouchesMove((e) => {
320
323
  'worklet';
@@ -325,12 +328,13 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
325
328
  isFirstTouch.value = false;
326
329
  }
327
330
  handleTriggerMove(e);
331
+ })
332
+ .onUpdate((e) => {
333
+ 'worklet';
328
334
  if (disabled)
329
335
  return;
330
- const changeX = changedTouches.x - startPosition.value.x;
331
- const changeY = changedTouches.y - startPosition.value.y;
332
336
  if (direction === 'horizontal' || direction === 'all') {
333
- const newX = offsetX.value + changeX;
337
+ const newX = initialViewPosition.value.x + e.translationX;
334
338
  if (!outOfBounds) {
335
339
  const { x } = checkBoundaryPosition({ positionX: newX, positionY: offsetY.value });
336
340
  offsetX.value = x;
@@ -340,7 +344,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
340
344
  }
341
345
  }
342
346
  if (direction === 'vertical' || direction === 'all') {
343
- const newY = offsetY.value + changeY;
347
+ const newY = initialViewPosition.value.y + e.translationY;
344
348
  if (!outOfBounds) {
345
349
  const { y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: newY });
346
350
  offsetY.value = y;
@@ -349,6 +353,12 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
349
353
  offsetY.value = newY;
350
354
  }
351
355
  }
356
+ if (bindchange) {
357
+ runOnJS(handleTriggerChange)({
358
+ x: offsetX.value,
359
+ y: offsetY.value
360
+ });
361
+ }
352
362
  })
353
363
  .onTouchesUp((e) => {
354
364
  'worklet';
@@ -357,55 +367,83 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
357
367
  if (bindtouchend || catchtouchend) {
358
368
  runOnJS(triggerEndOnJS)({ e });
359
369
  }
360
- if (disabled)
361
- return;
362
- if (!inertia) {
363
- const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value });
364
- if (x !== offsetX.value) {
365
- offsetX.value = animation
366
- ? withSpring(x, {
367
- duration: 1500,
368
- dampingRatio: 0.8
369
- })
370
- : x;
371
- }
372
- if (y !== offsetY.value) {
373
- offsetY.value = animation
374
- ? withSpring(y, {
375
- duration: 1500,
376
- dampingRatio: 0.8
377
- })
378
- : y;
379
- }
380
- }
381
370
  })
382
- .onFinalize((e) => {
371
+ .onEnd((e) => {
383
372
  'worklet';
384
373
  isMoving.value = false;
385
- if (!inertia || disabled || !animation)
374
+ if (disabled)
386
375
  return;
387
- if (direction === 'horizontal' || direction === 'all') {
388
- xInertialMotion.value = true;
389
- offsetX.value = withDecay({
390
- velocity: e.velocityX / 10,
391
- rubberBandEffect: outOfBounds,
392
- clamp: draggableXRange.value
393
- }, () => {
394
- xInertialMotion.value = false;
395
- });
376
+ // 处理没有惯性且超出边界的回弹
377
+ if (!inertia && outOfBounds) {
378
+ const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value });
379
+ if (x !== offsetX.value || y !== offsetY.value) {
380
+ if (x !== offsetX.value) {
381
+ offsetX.value = animation
382
+ ? withSpring(x, {
383
+ duration: 1500,
384
+ dampingRatio: 0.8
385
+ })
386
+ : x;
387
+ }
388
+ if (y !== offsetY.value) {
389
+ offsetY.value = animation
390
+ ? withSpring(y, {
391
+ duration: 1500,
392
+ dampingRatio: 0.8
393
+ })
394
+ : y;
395
+ }
396
+ if (bindchange) {
397
+ runOnJS(handleTriggerChange)({
398
+ x,
399
+ y
400
+ });
401
+ }
402
+ }
396
403
  }
397
- if (direction === 'vertical' || direction === 'all') {
398
- yInertialMotion.value = true;
399
- offsetY.value = withDecay({
400
- velocity: e.velocityY / 10,
401
- rubberBandEffect: outOfBounds,
402
- clamp: draggableYRange.value
403
- }, () => {
404
- yInertialMotion.value = false;
405
- });
404
+ else if (inertia) {
405
+ // 惯性处理
406
+ if (direction === 'horizontal' || direction === 'all') {
407
+ xInertialMotion.value = true;
408
+ offsetX.value = withDecay({
409
+ velocity: e.velocityX / 10,
410
+ rubberBandEffect: outOfBounds,
411
+ clamp: draggableXRange.value
412
+ }, () => {
413
+ xInertialMotion.value = false;
414
+ if (bindchange) {
415
+ runOnJS(handleTriggerChange)({
416
+ x: offsetX.value,
417
+ y: offsetY.value
418
+ });
419
+ }
420
+ });
421
+ }
422
+ if (direction === 'vertical' || direction === 'all') {
423
+ yInertialMotion.value = true;
424
+ offsetY.value = withDecay({
425
+ velocity: e.velocityY / 10,
426
+ rubberBandEffect: outOfBounds,
427
+ clamp: draggableYRange.value
428
+ }, () => {
429
+ yInertialMotion.value = false;
430
+ if (bindchange) {
431
+ runOnJS(handleTriggerChange)({
432
+ x: offsetX.value,
433
+ y: offsetY.value
434
+ });
435
+ }
436
+ });
437
+ }
406
438
  }
407
439
  })
408
440
  .withRef(movableGestureRef);
441
+ if (direction === 'horizontal') {
442
+ gesturePan.activeOffsetX([-5, 5]).failOffsetY([-5, 5]);
443
+ }
444
+ else if (direction === 'vertical') {
445
+ gesturePan.activeOffsetY([-5, 5]).failOffsetX([-5, 5]);
446
+ }
409
447
  if (simultaneousHandlers && simultaneousHandlers.length) {
410
448
  gesturePan.simultaneousWithExternalGesture(...simultaneousHandlers);
411
449
  }