@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
@@ -237,6 +237,95 @@ function transformPosition(styleObj, meta) {
237
237
  meta.hasPositionFixed = true;
238
238
  }
239
239
  }
240
+ // 多value解析
241
+ function parseValues(str, char = ' ') {
242
+ let stack = 0;
243
+ let temp = '';
244
+ const result = [];
245
+ for (let i = 0; i < str.length; i++) {
246
+ if (str[i] === '(') {
247
+ stack++;
248
+ }
249
+ else if (str[i] === ')') {
250
+ stack--;
251
+ }
252
+ // 非括号内 或者 非分隔字符且非空
253
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
254
+ temp += str[i];
255
+ }
256
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
257
+ result.push(temp);
258
+ temp = '';
259
+ }
260
+ }
261
+ return result;
262
+ }
263
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
264
+ function parseTransform(transformStr) {
265
+ const values = parseValues(transformStr);
266
+ const transform = [];
267
+ values.forEach(item => {
268
+ const match = item.match(/([/\w]+)\((.+)\)/);
269
+ if (match && match.length >= 3) {
270
+ let key = match[1];
271
+ const val = match[2];
272
+ switch (key) {
273
+ case 'translateX':
274
+ case 'translateY':
275
+ case 'scaleX':
276
+ case 'scaleY':
277
+ case 'rotateX':
278
+ case 'rotateY':
279
+ case 'rotateZ':
280
+ case 'rotate':
281
+ case 'skewX':
282
+ case 'skewY':
283
+ case 'perspective':
284
+ // rotate 处理成 rotateZ
285
+ key = key === 'rotate' ? 'rotateZ' : key;
286
+ // 单个值处理
287
+ transform.push({ [key]: global.__formatValue(val) });
288
+ break;
289
+ case 'matrix':
290
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) });
291
+ break;
292
+ case 'translate':
293
+ case 'scale':
294
+ case 'skew':
295
+ case 'translate3d': // x y 支持 z不支持
296
+ case 'scale3d': // x y 支持 z不支持
297
+ {
298
+ // 2 个以上的值处理
299
+ key = key.replace('3d', '');
300
+ const vals = parseValues(val, ',').splice(0, 3);
301
+ // scale(.5) === scaleX(.5) scaleY(.5)
302
+ if (vals.length === 1 && key === 'scale') {
303
+ vals.push(vals[0]);
304
+ }
305
+ const xyz = ['X', 'Y', 'Z'];
306
+ transform.push(...vals.map((v, index) => {
307
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
308
+ }));
309
+ break;
310
+ }
311
+ }
312
+ }
313
+ });
314
+ return transform;
315
+ }
316
+ // format style transform
317
+ function transformTransform(style) {
318
+ if (!style.transform || Array.isArray(style.transform))
319
+ return;
320
+ style.transform = parseTransform(style.transform);
321
+ }
322
+ function transformBoxShadow(styleObj) {
323
+ if (!styleObj.boxShadow)
324
+ return;
325
+ styleObj.boxShadow = parseValues(styleObj.boxShadow).reduce((res, i, idx) => {
326
+ return `${res}${idx === 0 ? '' : ' '}${global.__formatValue(i)}`;
327
+ }, '');
328
+ }
240
329
  export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
241
330
  const varStyle = {};
242
331
  const unoVarStyle = {};
@@ -365,6 +454,10 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
365
454
  transformPosition(normalStyle, positionMeta);
366
455
  // transform number enum stringify
367
456
  transformStringify(normalStyle);
457
+ // transform rpx to px
458
+ transformBoxShadow(normalStyle);
459
+ // transform 字符串格式转化数组格式
460
+ transformTransform(normalStyle);
368
461
  return {
369
462
  hasVarDec,
370
463
  varContextRef,
@@ -440,7 +533,7 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
440
533
  }
441
534
  if (enableOffset) {
442
535
  nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
443
- const { y: navigationY = 0 } = navigation?.layout || {};
536
+ const { top: navigationY = 0 } = navigation?.layout || {};
444
537
  layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft, offsetTop: offsetTop - navigationY };
445
538
  });
446
539
  }
@@ -42,7 +42,8 @@ import {
42
42
  TextStyle,
43
43
  Animated,
44
44
  Easing,
45
- NativeSyntheticEvent
45
+ NativeSyntheticEvent,
46
+ useAnimatedValue
46
47
  } from 'react-native'
47
48
  import { warn } from '@mpxjs/utils'
48
49
  import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
@@ -157,7 +158,7 @@ const timer = (data: any, time = 3000) => new Promise((resolve) => {
157
158
  })
158
159
 
159
160
  const Loading = ({ alone = false }: { alone: boolean }): JSX.Element => {
160
- const image = useRef(new Animated.Value(0)).current
161
+ const image = useAnimatedValue(0)
161
162
 
162
163
  const rotate = image.interpolate({
163
164
  inputRange: [0, 1],
@@ -218,7 +218,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
218
218
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
219
219
 
220
220
  useEffect(() => {
221
- if (inputValue !== value) {
221
+ if (value !== tmpValue.current) {
222
222
  const parsed = parseValue(value)
223
223
  tmpValue.current = parsed
224
224
  setInputValue(parsed)
@@ -1,12 +1,14 @@
1
1
  /**
2
- * scale-area
2
+ * scale-area
3
3
  */
4
4
 
5
5
  import { View } from 'react-native'
6
- import { JSX, forwardRef, ReactNode, useRef, useMemo, createElement } from 'react'
6
+ import { JSX, forwardRef, ReactNode, useRef, useMemo, useCallback, createElement } from 'react'
7
+ import { GestureDetector, Gesture } from 'react-native-gesture-handler'
8
+ import { useSharedValue } from 'react-native-reanimated'
7
9
  import useNodesRef, { HandlerRef } from './useNodesRef'
8
10
  import useInnerProps from './getInnerListeners'
9
- import { MovableAreaContext } from './context'
11
+ import { MovableAreaContext, MovableAreaContextValue } from './context'
10
12
  import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils'
11
13
  import Portal from './mpx-portal'
12
14
 
@@ -15,6 +17,7 @@ interface MovableAreaProps {
15
17
  children: ReactNode
16
18
  width?: number
17
19
  height?: number
20
+ 'scale-area'?: boolean
18
21
  'enable-offset'?: boolean
19
22
  'enable-var'?: boolean
20
23
  'external-var-context'?: Record<string, any>
@@ -23,8 +26,21 @@ interface MovableAreaProps {
23
26
  'parent-height'?: number
24
27
  }
25
28
 
29
+ interface MovableViewCallbacks {
30
+ onScale: (scaleInfo: {scale: number}) => void
31
+ onScaleEnd?: () => void
32
+ }
33
+
26
34
  const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaProps>((props: MovableAreaProps, ref): JSX.Element => {
27
- const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props
35
+ const {
36
+ style = {},
37
+ 'scale-area': scaleArea = false,
38
+ 'enable-var': enableVar,
39
+ 'external-var-context': externalVarContext,
40
+ 'parent-font-size': parentFontSize,
41
+ 'parent-width': parentWidth,
42
+ 'parent-height': parentHeight
43
+ } = props
28
44
 
29
45
  const {
30
46
  hasSelfPercent,
@@ -36,17 +52,67 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
36
52
  setHeight
37
53
  } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
38
54
 
39
- const movableViewRef = useRef(null)
40
- useNodesRef(props, ref, movableViewRef, {
55
+ const movableAreaRef = useRef(null)
56
+ const movableViewsValue = useSharedValue<Record<string, MovableViewCallbacks>>({})
57
+ useNodesRef(props, ref, movableAreaRef, {
41
58
  style: normalStyle
42
59
  })
43
60
 
44
- const contextValue = useMemo(() => ({
61
+ // 注册/注销 MovableView 的回调
62
+ const registerMovableView = useCallback((id: string, callbacks: { onScale?: (scaleInfo: { scale: number }) => void; onScaleEnd?: () => void }) => {
63
+ movableViewsValue.value = extendObject(movableViewsValue.value, { [id]: callbacks })
64
+ }, [])
65
+
66
+ const unregisterMovableView = useCallback((id: string) => {
67
+ delete movableViewsValue.value[id]
68
+ }, [])
69
+
70
+ // 处理区域缩放手势
71
+ const handleAreaScale = useCallback((scaleInfo: { scale: number }) => {
72
+ 'worklet'
73
+ if (scaleArea) {
74
+ // 将缩放信息广播给所有注册的 MovableView
75
+ Object.values(movableViewsValue.value).forEach((callbacks) => {
76
+ callbacks.onScale && callbacks.onScale(scaleInfo)
77
+ })
78
+ }
79
+ }, [scaleArea])
80
+
81
+ // 处理区域缩放结束
82
+ const handleAreaScaleEnd = useCallback(() => {
83
+ 'worklet'
84
+ if (scaleArea) {
85
+ // 通知所有注册的 MovableView 缩放结束
86
+ Object.values(movableViewsValue.value).forEach((callbacks) => {
87
+ callbacks.onScaleEnd && callbacks.onScaleEnd()
88
+ })
89
+ }
90
+ }, [scaleArea])
91
+
92
+ const contextValue: MovableAreaContextValue = useMemo(() => ({
45
93
  height: normalStyle.height || 10,
46
- width: normalStyle.width || 10
47
- }), [normalStyle.width, normalStyle.height])
94
+ width: normalStyle.width || 10,
95
+ scaleArea,
96
+ registerMovableView,
97
+ unregisterMovableView
98
+ }), [normalStyle.width, normalStyle.height, scaleArea])
48
99
 
49
- const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef })
100
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableAreaRef })
101
+
102
+ // 创建缩放手势
103
+ const scaleGesture = useMemo(() => {
104
+ if (!scaleArea) return null
105
+
106
+ return Gesture.Pinch()
107
+ .onUpdate((e) => {
108
+ 'worklet'
109
+ handleAreaScale(e)
110
+ })
111
+ .onEnd(() => {
112
+ 'worklet'
113
+ handleAreaScaleEnd()
114
+ })
115
+ }, [scaleArea])
50
116
 
51
117
  const innerProps = useInnerProps(
52
118
  extendObject(
@@ -54,8 +120,8 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
54
120
  props,
55
121
  layoutProps,
56
122
  {
57
- style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
58
- ref: movableViewRef
123
+ style: extendObject({ height: contextValue.height, width: contextValue.width }, normalStyle, layoutStyle),
124
+ ref: movableAreaRef
59
125
  }
60
126
  ),
61
127
  [],
@@ -73,9 +139,30 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
73
139
  }
74
140
  )
75
141
  ))
142
+
143
+ // 如果启用了 scale-area,包装一个 GestureDetector
144
+ if (scaleArea && scaleGesture) {
145
+ movableComponent = createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(
146
+ GestureDetector,
147
+ { gesture: scaleGesture },
148
+ createElement(
149
+ View,
150
+ innerProps,
151
+ wrapChildren(
152
+ props,
153
+ {
154
+ hasVarDec,
155
+ varContext: varContextRef.current
156
+ }
157
+ )
158
+ )
159
+ ))
160
+ }
161
+
76
162
  if (hasPositionFixed) {
77
163
  movableComponent = createElement(Portal, null, movableComponent)
78
164
  }
165
+
79
166
  return movableComponent
80
167
  })
81
168