@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
@@ -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
 
21
22
  export type IconType =
22
23
  | 'success'
@@ -75,6 +76,7 @@ const Icon = forwardRef<HandlerRef<Text, IconProps>, IconProps>(
75
76
  const styleObj = extendObject({}, defaultStyle, style)
76
77
 
77
78
  const {
79
+ hasPositionFixed,
78
80
  hasSelfPercent,
79
81
  normalStyle,
80
82
  setWidth,
@@ -103,7 +105,13 @@ const Icon = forwardRef<HandlerRef<Text, IconProps>, IconProps>(
103
105
  }
104
106
  )
105
107
 
106
- return createElement(Image, innerProps)
108
+ const finalComponent = createElement(Image, innerProps)
109
+
110
+ if (hasPositionFixed) {
111
+ return createElement(Portal, null, finalComponent)
112
+ }
113
+
114
+ return finalComponent
107
115
  }
108
116
  )
109
117
 
@@ -27,6 +27,7 @@ import { SvgCssUri } from 'react-native-svg/css'
27
27
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
28
28
  import useNodesRef, { HandlerRef } from './useNodesRef'
29
29
  import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils'
30
+ import Portal from './mpx-portal'
30
31
 
31
32
  export type Mode =
32
33
  | 'scaleToFill'
@@ -159,7 +160,13 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
159
160
  }
160
161
  }
161
162
 
162
- const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
163
+ const {
164
+ hasPositionFixed,
165
+ hasSelfPercent,
166
+ normalStyle,
167
+ setWidth,
168
+ setHeight
169
+ } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
163
170
 
164
171
  const { layoutRef, layoutStyle, layoutProps } = useLayout({
165
172
  props,
@@ -356,25 +363,31 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
356
363
 
357
364
  useEffect(() => {
358
365
  if (!isSvg && isLayoutMode) {
359
- RNImage.getSize(src, (width: number, height: number) => {
360
- state.current.imageWidth = width
361
- state.current.imageHeight = height
362
- state.current.ratio = !width ? 0 : height / width
363
-
364
- if (isWidthFixMode
365
- ? state.current.viewWidth
366
- : isHeightFixMode
367
- ? state.current.viewHeight
368
- : state.current.viewWidth && state.current.viewHeight) {
369
- state.current.viewWidth && setViewWidth(state.current.viewWidth)
370
- state.current.viewHeight && setViewHeight(state.current.viewHeight)
371
- setRatio(!width ? 0 : height / width)
372
- setImageWidth(width)
373
- setImageHeight(height)
374
- state.current = {}
366
+ RNImage.getSize(
367
+ src,
368
+ (width: number, height: number) => {
369
+ state.current.imageWidth = width
370
+ state.current.imageHeight = height
371
+ state.current.ratio = !width ? 0 : height / width
372
+
373
+ if (isWidthFixMode
374
+ ? state.current.viewWidth
375
+ : isHeightFixMode
376
+ ? state.current.viewHeight
377
+ : state.current.viewWidth && state.current.viewHeight) {
378
+ state.current.viewWidth && setViewWidth(state.current.viewWidth)
379
+ state.current.viewHeight && setViewHeight(state.current.viewHeight)
380
+ setRatio(!width ? 0 : height / width)
381
+ setImageWidth(width)
382
+ setImageHeight(height)
383
+ state.current = {}
384
+ setLoaded(true)
385
+ }
386
+ },
387
+ () => {
375
388
  setLoaded(true)
376
389
  }
377
- })
390
+ )
378
391
  }
379
392
  }, [src, isSvg, isLayoutMode])
380
393
 
@@ -441,7 +454,13 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
441
454
 
442
455
  const LayoutImage = createElement(View, innerProps, loaded && BaseImage)
443
456
 
444
- return isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage
457
+ const finalComponent = isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage
458
+
459
+ if (hasPositionFixed) {
460
+ return createElement(Portal, null, finalComponent)
461
+ }
462
+
463
+ return finalComponent
445
464
  })
446
465
 
447
466
  Image.displayName = 'mpx-image'
@@ -58,6 +58,7 @@ import { useUpdateEffect, useTransformStyle, useLayout, extendObject, isIOS } fr
58
58
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
59
59
  import useNodesRef, { HandlerRef } from './useNodesRef'
60
60
  import { FormContext, FormFieldValue, KeyboardAvoidContext } from './context'
61
+ import Portal from './mpx-portal'
61
62
 
62
63
  type InputStyle = Omit<
63
64
  TextStyle & ViewStyle & Pick<FlexStyle, 'minHeight'>,
@@ -202,6 +203,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
202
203
  )
203
204
 
204
205
  const {
206
+ hasPositionFixed,
205
207
  hasSelfPercent,
206
208
  normalStyle,
207
209
  setWidth,
@@ -481,7 +483,14 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
481
483
  layoutRef
482
484
  }
483
485
  )
484
- return createElement(TextInput, innerProps)
486
+
487
+ const finalComponent = createElement(TextInput, innerProps)
488
+
489
+ if (hasPositionFixed) {
490
+ return createElement(Portal, null, finalComponent)
491
+ }
492
+
493
+ return finalComponent
485
494
  })
486
495
 
487
496
  Input.displayName = 'MpxInput'
@@ -48,7 +48,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
48
48
  const { ref, cursorSpacing = 0 } = keyboardAvoid.current
49
49
  setTimeout(() => {
50
50
  ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
51
- const aboveOffset = pageY + height - endCoordinates.screenY
51
+ const aboveOffset = offset.value + pageY + height - endCoordinates.screenY
52
52
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing
53
53
  const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing)
54
54
  const value = aboveOffset > 0 ? belowValue : aboveValue
@@ -8,6 +8,7 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners'
8
8
  import useNodesRef, { HandlerRef } from './useNodesRef'
9
9
  import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils'
10
10
  import { LabelContext, LabelContextValue } from './context'
11
+ import Portal from './mpx-portal'
11
12
 
12
13
  export interface LabelProps {
13
14
  for?: string
@@ -45,6 +46,7 @@ const Label = forwardRef<HandlerRef<View, LabelProps>, LabelProps>(
45
46
  const styleObj = extendObject({}, defaultStyle, style)
46
47
 
47
48
  const {
49
+ hasPositionFixed,
48
50
  hasSelfPercent,
49
51
  normalStyle,
50
52
  hasVarDec,
@@ -91,7 +93,7 @@ const Label = forwardRef<HandlerRef<View, LabelProps>, LabelProps>(
91
93
  }
92
94
  )
93
95
 
94
- return createElement(View, innerProps, createElement(
96
+ const finalComponent = createElement(View, innerProps, createElement(
95
97
  LabelContext.Provider,
96
98
  { value: contextRef },
97
99
  wrapChildren(
@@ -104,6 +106,12 @@ const Label = forwardRef<HandlerRef<View, LabelProps>, LabelProps>(
104
106
  }
105
107
  )
106
108
  ))
109
+
110
+ if (hasPositionFixed) {
111
+ return createElement(Portal, null, finalComponent)
112
+ }
113
+
114
+ return finalComponent
107
115
  }
108
116
  )
109
117
 
@@ -8,6 +8,7 @@ import useNodesRef, { HandlerRef } from './useNodesRef'
8
8
  import useInnerProps from './getInnerListeners'
9
9
  import { MovableAreaContext } from './context'
10
10
  import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils'
11
+ import Portal from './mpx-portal'
11
12
 
12
13
  interface MovableAreaProps {
13
14
  style?: Record<string, any>
@@ -30,6 +31,7 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
30
31
  normalStyle,
31
32
  hasVarDec,
32
33
  varContextRef,
34
+ hasPositionFixed,
33
35
  setWidth,
34
36
  setHeight
35
37
  } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
@@ -52,7 +54,7 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
52
54
  props,
53
55
  layoutProps,
54
56
  {
55
- style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
57
+ style: extendObject({ height: contextValue.height, width: contextValue.width }, normalStyle, layoutStyle),
56
58
  ref: movableViewRef
57
59
  }
58
60
  ),
@@ -60,7 +62,7 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
60
62
  { layoutRef }
61
63
  )
62
64
 
63
- return createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(
65
+ let movableComponent: JSX.Element = createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(
64
66
  View,
65
67
  innerProps,
66
68
  wrapChildren(
@@ -71,6 +73,10 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
71
73
  }
72
74
  )
73
75
  ))
76
+ if (hasPositionFixed) {
77
+ movableComponent = createElement(Portal, null, movableComponent)
78
+ }
79
+ return movableComponent
74
80
  })
75
81
 
76
82
  _MovableArea.displayName = 'MpxMovableArea'
@@ -114,7 +114,8 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
114
114
  catchvtouchmove,
115
115
  catchtouchmove,
116
116
  bindtouchend,
117
- catchtouchend
117
+ catchtouchend,
118
+ bindchange
118
119
  } = props
119
120
 
120
121
  const {
@@ -140,6 +141,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
140
141
  x: 0,
141
142
  y: 0
142
143
  })
144
+
143
145
  const draggableXRange = useSharedValue<[min: number, max: number]>([0, 0])
144
146
  const draggableYRange = useSharedValue<[min: number, max: number]>([0, 0])
145
147
  const isMoving = useSharedValue(false)
@@ -147,6 +149,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
147
149
  const yInertialMotion = useSharedValue(false)
148
150
  const isFirstTouch = useSharedValue(true)
149
151
  const touchEvent = useSharedValue<string>('')
152
+ const initialViewPosition = useSharedValue({ x: x || 0, y: y || 0 })
150
153
 
151
154
  const MovableAreaLayout = useContext(MovableAreaContext)
152
155
 
@@ -214,11 +217,13 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
214
217
  })
215
218
  : newY
216
219
  }
217
- runOnJS(handleTriggerChange)({
218
- x: newX,
219
- y: newY,
220
- type: 'setData'
221
- })
220
+ if (bindchange) {
221
+ runOnJS(handleTriggerChange)({
222
+ x: newX,
223
+ y: newY,
224
+ type: 'setData'
225
+ })
226
+ }
222
227
  }
223
228
  })()
224
229
  }, [x, y])
@@ -230,19 +235,6 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
230
235
  }
231
236
  }, [MovableAreaLayout.height, MovableAreaLayout.width])
232
237
 
233
- useAnimatedReaction(
234
- () => ({
235
- offsetX: offsetX.value,
236
- offsetY: offsetY.value
237
- }),
238
- (currentValue: { offsetX: any; offsetY: any }) => {
239
- const { offsetX, offsetY } = currentValue
240
- runOnJS(handleTriggerChange)({
241
- x: offsetX,
242
- y: offsetY
243
- })
244
- })
245
-
246
238
  const getTouchSource = useCallback((offsetX: number, offsetY: number) => {
247
239
  const hasOverBoundary = offsetX < draggableXRange.value[0] || offsetX > draggableXRange.value[1] ||
248
240
  offsetY < draggableYRange.value[0] || offsetY > draggableYRange.value[1]
@@ -366,12 +358,14 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
366
358
  }, [])
367
359
 
368
360
  const triggerStartOnJS = ({ e }: { e: GestureTouchEvent }) => {
361
+ const { bindtouchstart, catchtouchstart } = propsRef.current
369
362
  extendEvent(e, 'start')
370
363
  bindtouchstart && bindtouchstart(e)
371
364
  catchtouchstart && catchtouchstart(e)
372
365
  }
373
366
 
374
367
  const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }: { e: GestureTouchEvent; hasTouchmove: boolean; hasCatchTouchmove: boolean; touchEvent: string }) => {
368
+ const { bindhtouchmove, bindvtouchmove, bindtouchmove, catchhtouchmove, catchvtouchmove, catchtouchmove } = propsRef.current
375
369
  extendEvent(e, 'move')
376
370
  if (hasTouchmove) {
377
371
  if (touchEvent === 'htouchmove') {
@@ -393,6 +387,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
393
387
  }
394
388
 
395
389
  const triggerEndOnJS = ({ e }: { e: GestureTouchEvent }) => {
390
+ const { bindtouchend, catchtouchend } = propsRef.current
396
391
  extendEvent(e, 'end')
397
392
  bindtouchend && bindtouchend(e)
398
393
  catchtouchend && catchtouchend(e)
@@ -426,6 +421,13 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
426
421
  runOnJS(triggerStartOnJS)({ e })
427
422
  }
428
423
  })
424
+ .onStart(() => {
425
+ 'worklet'
426
+ initialViewPosition.value = {
427
+ x: offsetX.value,
428
+ y: offsetY.value
429
+ }
430
+ })
429
431
  .onTouchesMove((e: GestureTouchEvent) => {
430
432
  'worklet'
431
433
  const changedTouches = e.changedTouches[0] || { x: 0, y: 0 }
@@ -435,11 +437,12 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
435
437
  isFirstTouch.value = false
436
438
  }
437
439
  handleTriggerMove(e)
440
+ })
441
+ .onUpdate((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
442
+ 'worklet'
438
443
  if (disabled) return
439
- const changeX = changedTouches.x - startPosition.value.x
440
- const changeY = changedTouches.y - startPosition.value.y
441
444
  if (direction === 'horizontal' || direction === 'all') {
442
- const newX = offsetX.value + changeX
445
+ const newX = initialViewPosition.value.x + e.translationX
443
446
  if (!outOfBounds) {
444
447
  const { x } = checkBoundaryPosition({ positionX: newX, positionY: offsetY.value })
445
448
  offsetX.value = x
@@ -448,7 +451,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
448
451
  }
449
452
  }
450
453
  if (direction === 'vertical' || direction === 'all') {
451
- const newY = offsetY.value + changeY
454
+ const newY = initialViewPosition.value.y + e.translationY
452
455
  if (!outOfBounds) {
453
456
  const { y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: newY })
454
457
  offsetY.value = y
@@ -456,6 +459,12 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
456
459
  offsetY.value = newY
457
460
  }
458
461
  }
462
+ if (bindchange) {
463
+ runOnJS(handleTriggerChange)({
464
+ x: offsetX.value,
465
+ y: offsetY.value
466
+ })
467
+ }
459
468
  })
460
469
  .onTouchesUp((e: GestureTouchEvent) => {
461
470
  'worklet'
@@ -464,53 +473,82 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
464
473
  if (bindtouchend || catchtouchend) {
465
474
  runOnJS(triggerEndOnJS)({ e })
466
475
  }
476
+ })
477
+ .onEnd((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
478
+ 'worklet'
479
+ isMoving.value = false
467
480
  if (disabled) return
468
- if (!inertia) {
481
+ // 处理没有惯性且超出边界的回弹
482
+ if (!inertia && outOfBounds) {
469
483
  const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value })
470
- if (x !== offsetX.value) {
471
- offsetX.value = animation
472
- ? withSpring(x, {
473
- duration: 1500,
474
- dampingRatio: 0.8
484
+ if (x !== offsetX.value || y !== offsetY.value) {
485
+ if (x !== offsetX.value) {
486
+ offsetX.value = animation
487
+ ? withSpring(x, {
488
+ duration: 1500,
489
+ dampingRatio: 0.8
490
+ })
491
+ : x
492
+ }
493
+ if (y !== offsetY.value) {
494
+ offsetY.value = animation
495
+ ? withSpring(y, {
496
+ duration: 1500,
497
+ dampingRatio: 0.8
498
+ })
499
+ : y
500
+ }
501
+ if (bindchange) {
502
+ runOnJS(handleTriggerChange)({
503
+ x,
504
+ y
475
505
  })
476
- : x
506
+ }
477
507
  }
478
- if (y !== offsetY.value) {
479
- offsetY.value = animation
480
- ? withSpring(y, {
481
- duration: 1500,
482
- dampingRatio: 0.8
483
- })
484
- : y
508
+ } else if (inertia) {
509
+ // 惯性处理
510
+ if (direction === 'horizontal' || direction === 'all') {
511
+ xInertialMotion.value = true
512
+ offsetX.value = withDecay({
513
+ velocity: e.velocityX / 10,
514
+ rubberBandEffect: outOfBounds,
515
+ clamp: draggableXRange.value
516
+ }, () => {
517
+ xInertialMotion.value = false
518
+ if (bindchange) {
519
+ runOnJS(handleTriggerChange)({
520
+ x: offsetX.value,
521
+ y: offsetY.value
522
+ })
523
+ }
524
+ })
525
+ }
526
+ if (direction === 'vertical' || direction === 'all') {
527
+ yInertialMotion.value = true
528
+ offsetY.value = withDecay({
529
+ velocity: e.velocityY / 10,
530
+ rubberBandEffect: outOfBounds,
531
+ clamp: draggableYRange.value
532
+ }, () => {
533
+ yInertialMotion.value = false
534
+ if (bindchange) {
535
+ runOnJS(handleTriggerChange)({
536
+ x: offsetX.value,
537
+ y: offsetY.value
538
+ })
539
+ }
540
+ })
485
541
  }
486
- }
487
- })
488
- .onFinalize((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
489
- 'worklet'
490
- isMoving.value = false
491
- if (!inertia || disabled || !animation) return
492
- if (direction === 'horizontal' || direction === 'all') {
493
- xInertialMotion.value = true
494
- offsetX.value = withDecay({
495
- velocity: e.velocityX / 10,
496
- rubberBandEffect: outOfBounds,
497
- clamp: draggableXRange.value
498
- }, () => {
499
- xInertialMotion.value = false
500
- })
501
- }
502
- if (direction === 'vertical' || direction === 'all') {
503
- yInertialMotion.value = true
504
- offsetY.value = withDecay({
505
- velocity: e.velocityY / 10,
506
- rubberBandEffect: outOfBounds,
507
- clamp: draggableYRange.value
508
- }, () => {
509
- yInertialMotion.value = false
510
- })
511
542
  }
512
543
  })
513
544
  .withRef(movableGestureRef)
545
+
546
+ if (direction === 'horizontal') {
547
+ gesturePan.activeOffsetX([-5, 5]).failOffsetY([-5, 5])
548
+ } else if (direction === 'vertical') {
549
+ gesturePan.activeOffsetY([-5, 5]).failOffsetX([-5, 5])
550
+ }
551
+
514
552
  if (simultaneousHandlers && simultaneousHandlers.length) {
515
553
  gesturePan.simultaneousWithExternalGesture(...simultaneousHandlers)
516
554
  }
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useRef, useContext, useEffect } from 'react'
1
+ import React, { forwardRef, useRef, useContext, useEffect, createElement } from 'react'
2
2
  import { StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native'
3
3
  import { warn } from '@mpxjs/utils'
4
4
  import PickerSelector from './selector'
@@ -9,7 +9,7 @@ import PickerRegion from './region'
9
9
  import { FormContext, FormFieldValue, RouteContext } from '../context'
10
10
  import useNodesRef, { HandlerRef } from '../useNodesRef'
11
11
  import useInnerProps, { getCustomEvent } from '../getInnerListeners'
12
- import { extendObject } from '../utils'
12
+ import { extendObject, useLayout } from '../utils'
13
13
  import { createPopupManager } from '../mpx-popup'
14
14
  import { EventType, LanguageCode, PickerMode, PickerProps } from './type'
15
15
 
@@ -127,26 +127,29 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
127
127
  const buttonText = buttonTextMap[(global.__mpx?.i18n?.locale as LanguageCode) || 'zh-CN']
128
128
  const pickerValue = useRef(value)
129
129
  pickerValue.current = Array.isArray(value) ? value.slice() : value
130
- const innerLayout = useRef({})
131
- const nodeRef = useRef(null)
130
+ const nodeRef = useRef<View>(null)
132
131
  const pickerRef = useRef<any>(null)
133
132
  const { open, show, hide, remove } = useRef(createPopupManager()).current
134
133
 
135
134
  useNodesRef<View, PickerProps>(props, ref, nodeRef)
135
+ const { layoutRef, layoutProps } = useLayout({
136
+ props,
137
+ hasSelfPercent: false,
138
+ nodeRef
139
+ })
140
+
136
141
  const innerProps = useInnerProps(
137
142
  extendObject(
138
143
  {},
139
144
  props,
140
145
  {
141
146
  ref: nodeRef
142
- }
147
+ },
148
+ layoutProps
143
149
  ),
144
150
  [],
145
- { layoutRef: innerLayout }
151
+ { layoutRef }
146
152
  )
147
- const getInnerLayout = (layout: React.MutableRefObject<{}>) => {
148
- innerLayout.current = layout.current
149
- }
150
153
 
151
154
  useEffect(() => {
152
155
  if (range && pickerRef.current && mode === PickerMode.MULTI_SELECTOR) {
@@ -195,7 +198,7 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
195
198
  const eventData = getCustomEvent(
196
199
  'columnchange',
197
200
  {},
198
- { detail: { column: columnIndex, value }, layoutRef: innerLayout }
201
+ { detail: { column: columnIndex, value }, layoutRef }
199
202
  )
200
203
  props.bindcolumnchange?.(eventData)
201
204
  }
@@ -209,7 +212,7 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
209
212
  const eventData = getCustomEvent(
210
213
  'change',
211
214
  {},
212
- { detail: { value: pickerValue.current }, layoutRef: innerLayout }
215
+ { detail: { value: pickerValue.current }, layoutRef }
213
216
  )
214
217
  bindchange?.(eventData)
215
218
  hide()
@@ -220,7 +223,6 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
220
223
  children,
221
224
  bindchange: onChange,
222
225
  bindcolumnchange: onColumnChange,
223
- getInnerLayout,
224
226
  getRange: () => range
225
227
  })
226
228
 
@@ -269,10 +271,10 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
269
271
  }
270
272
  }, [])
271
273
 
272
- return (
273
- <TouchableWithoutFeedback onPress={show}>
274
- {children}
275
- </TouchableWithoutFeedback>
274
+ return createElement(
275
+ TouchableWithoutFeedback,
276
+ { onPress: show },
277
+ createElement(View, innerProps, children)
276
278
  )
277
279
  }
278
280
  )
@@ -1,5 +1,5 @@
1
1
  import { View } from 'react-native'
2
- import React, { forwardRef, useRef } from 'react'
2
+ import React, { createElement, forwardRef, useRef } from 'react'
3
3
  import useInnerProps, { getCustomEvent } from '../getInnerListeners'
4
4
  import useNodesRef, { HandlerRef } from '../useNodesRef'
5
5
  import {
@@ -11,6 +11,7 @@ import {
11
11
  extendObject
12
12
  } from '../utils'
13
13
  import { PickerViewStyleContext } from './pickerVIewContext'
14
+ import Portal from '../mpx-portal'
14
15
  import type { AnyFunc } from '../types/common'
15
16
  /**
16
17
  * ✔ value
@@ -86,7 +87,8 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
86
87
  varContextRef,
87
88
  hasSelfPercent,
88
89
  setWidth,
89
- setHeight
90
+ setHeight,
91
+ hasPositionFixed
90
92
  } = useTransformStyle(style, { enableVar, externalVarContext })
91
93
 
92
94
  useNodesRef<View, PickerViewProps>(props, ref, nodeRef, {
@@ -222,13 +224,25 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
222
224
  return renderColumns
223
225
  }
224
226
 
225
- return (
226
- <PickerViewStyleContext.Provider value={textStyle}>
227
- <View {...innerProps}>
228
- <View style={[styles.wrapper]}>{renderPickerColumns()}</View>
229
- </View>
230
- </PickerViewStyleContext.Provider>
227
+ const finalComponent = createElement(
228
+ PickerViewStyleContext.Provider,
229
+ { value: textStyle },
230
+ createElement(
231
+ View,
232
+ innerProps,
233
+ createElement(
234
+ View,
235
+ { style: [styles.wrapper] },
236
+ renderPickerColumns()
237
+ )
238
+ )
231
239
  )
240
+
241
+ if (hasPositionFixed) {
242
+ return createElement(Portal, null, finalComponent)
243
+ }
244
+
245
+ return finalComponent
232
246
  })
233
247
 
234
248
  _PickerView.displayName = 'MpxPickerView'