@mpxjs/webpack-plugin 2.10.24-test.1 → 2.11.0

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 (128) hide show
  1. package/LICENSE +433 -0
  2. package/lib/index.js +4 -1
  3. package/lib/platform/style/wx/index.js +44 -38
  4. package/lib/platform/template/wx/component-config/picker.js +0 -6
  5. package/lib/resolver/AddEnvPlugin.js +1 -1
  6. package/lib/resolver/AddModePlugin.js +1 -1
  7. package/lib/resolver/ExtendComponentsPlugin.js +68 -0
  8. package/lib/runtime/components/extends/section-list.mpx +14 -0
  9. package/lib/runtime/components/react/dist/mpx-button.d.ts +0 -1
  10. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -2
  11. package/lib/runtime/components/react/dist/mpx-camera.d.ts +0 -1
  12. package/lib/runtime/components/react/dist/mpx-camera.jsx +36 -4
  13. package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts +0 -1
  14. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +1 -2
  15. package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts +0 -1
  16. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -2
  17. package/lib/runtime/components/react/dist/mpx-checkbox.d.ts +0 -1
  18. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -2
  19. package/lib/runtime/components/react/dist/mpx-form.d.ts +0 -1
  20. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
  21. package/lib/runtime/components/react/dist/mpx-icon/index.d.ts +0 -1
  22. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -2
  23. package/lib/runtime/components/react/dist/mpx-image.d.ts +0 -1
  24. package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
  25. package/lib/runtime/components/react/dist/mpx-inline-text.jsx +13 -4
  26. package/lib/runtime/components/react/dist/mpx-input.d.ts +0 -1
  27. package/lib/runtime/components/react/dist/mpx-input.jsx +16 -8
  28. package/lib/runtime/components/react/dist/mpx-label.d.ts +0 -1
  29. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -2
  30. package/lib/runtime/components/react/dist/mpx-movable-area.d.ts +0 -1
  31. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +2 -2
  32. package/lib/runtime/components/react/dist/mpx-movable-view.d.ts +0 -1
  33. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -2
  34. package/lib/runtime/components/react/dist/mpx-nav.jsx +1 -1
  35. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +72 -23
  36. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -2
  37. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +4 -0
  38. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +6 -8
  39. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts +0 -2
  40. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.js +0 -5
  41. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts +1 -0
  42. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +34 -14
  43. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts +0 -2
  44. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.jsx +4 -5
  45. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.d.ts +0 -2
  46. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +3 -5
  47. package/lib/runtime/components/react/dist/mpx-popup/index.d.ts +5 -4
  48. package/lib/runtime/components/react/dist/mpx-popup/index.jsx +2 -2
  49. package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +3 -2
  50. package/lib/runtime/components/react/dist/mpx-progress.d.ts +0 -1
  51. package/lib/runtime/components/react/dist/mpx-progress.jsx +1 -2
  52. package/lib/runtime/components/react/dist/mpx-radio-group.d.ts +0 -1
  53. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -2
  54. package/lib/runtime/components/react/dist/mpx-radio.d.ts +0 -1
  55. package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -2
  56. package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts +0 -1
  57. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +1 -2
  58. package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts +0 -1
  59. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +2 -2
  60. package/lib/runtime/components/react/dist/mpx-section-list.d.ts +51 -0
  61. package/lib/runtime/components/react/dist/mpx-section-list.jsx +376 -0
  62. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +27 -14
  63. package/lib/runtime/components/react/dist/mpx-simple-view.d.ts +1 -0
  64. package/lib/runtime/components/react/dist/mpx-slider.d.ts +0 -1
  65. package/lib/runtime/components/react/dist/mpx-slider.jsx +1 -2
  66. package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts +0 -1
  67. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +2 -2
  68. package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts +0 -1
  69. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +2 -2
  70. package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts +0 -1
  71. package/lib/runtime/components/react/dist/mpx-swiper.d.ts +0 -1
  72. package/lib/runtime/components/react/dist/mpx-swiper.jsx +1 -2
  73. package/lib/runtime/components/react/dist/mpx-switch.d.ts +0 -1
  74. package/lib/runtime/components/react/dist/mpx-switch.jsx +1 -2
  75. package/lib/runtime/components/react/dist/mpx-text.d.ts +0 -1
  76. package/lib/runtime/components/react/dist/mpx-text.jsx +22 -8
  77. package/lib/runtime/components/react/dist/mpx-video.d.ts +0 -1
  78. package/lib/runtime/components/react/dist/mpx-video.jsx +1 -2
  79. package/lib/runtime/components/react/dist/mpx-view.d.ts +0 -1
  80. package/lib/runtime/components/react/dist/mpx-view.jsx +1 -2
  81. package/lib/runtime/components/react/dist/mpx-web-view.d.ts +2 -1
  82. package/lib/runtime/components/react/dist/utils.d.ts +6 -9
  83. package/lib/runtime/components/react/dist/utils.jsx +70 -84
  84. package/lib/runtime/components/react/mpx-button.tsx +1 -3
  85. package/lib/runtime/components/react/mpx-camera.tsx +40 -5
  86. package/lib/runtime/components/react/mpx-canvas/index.tsx +5 -5
  87. package/lib/runtime/components/react/mpx-checkbox-group.tsx +1 -3
  88. package/lib/runtime/components/react/mpx-checkbox.tsx +1 -3
  89. package/lib/runtime/components/react/mpx-form.tsx +1 -3
  90. package/lib/runtime/components/react/mpx-icon/index.tsx +1 -3
  91. package/lib/runtime/components/react/mpx-image.tsx +2 -5
  92. package/lib/runtime/components/react/mpx-inline-text.tsx +13 -4
  93. package/lib/runtime/components/react/mpx-input.tsx +19 -10
  94. package/lib/runtime/components/react/mpx-label.tsx +1 -3
  95. package/lib/runtime/components/react/mpx-movable-area.tsx +2 -3
  96. package/lib/runtime/components/react/mpx-movable-view.tsx +1 -3
  97. package/lib/runtime/components/react/mpx-nav.tsx +1 -1
  98. package/lib/runtime/components/react/mpx-picker/index.tsx +100 -29
  99. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +3 -3
  100. package/lib/runtime/components/react/mpx-picker/selector.tsx +1 -1
  101. package/lib/runtime/components/react/mpx-picker/type.ts +4 -0
  102. package/lib/runtime/components/react/mpx-picker-view/index.tsx +12 -17
  103. package/lib/runtime/components/react/mpx-picker-view/pickerVIewContext.ts +0 -9
  104. package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +44 -21
  105. package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItem.tsx +1 -9
  106. package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItemLite.tsx +0 -9
  107. package/lib/runtime/components/react/mpx-popup/index.tsx +7 -3
  108. package/lib/runtime/components/react/mpx-popup/popupBase.tsx +3 -2
  109. package/lib/runtime/components/react/mpx-progress.tsx +0 -3
  110. package/lib/runtime/components/react/mpx-radio-group.tsx +1 -3
  111. package/lib/runtime/components/react/mpx-radio.tsx +1 -3
  112. package/lib/runtime/components/react/mpx-rich-text/index.tsx +0 -3
  113. package/lib/runtime/components/react/mpx-scroll-view.tsx +1 -3
  114. package/lib/runtime/components/react/mpx-section-list.tsx +557 -0
  115. package/lib/runtime/components/react/mpx-simple-text.tsx +26 -13
  116. package/lib/runtime/components/react/mpx-slider.tsx +0 -3
  117. package/lib/runtime/components/react/mpx-sticky-header.tsx +1 -3
  118. package/lib/runtime/components/react/mpx-sticky-section.tsx +1 -3
  119. package/lib/runtime/components/react/mpx-swiper-item.tsx +0 -1
  120. package/lib/runtime/components/react/mpx-swiper.tsx +0 -3
  121. package/lib/runtime/components/react/mpx-switch.tsx +0 -3
  122. package/lib/runtime/components/react/mpx-text.tsx +21 -9
  123. package/lib/runtime/components/react/mpx-video.tsx +0 -3
  124. package/lib/runtime/components/react/mpx-view.tsx +0 -3
  125. package/lib/runtime/components/react/mpx-web-view.tsx +4 -3
  126. package/lib/runtime/components/react/utils.tsx +82 -88
  127. package/lib/template-compiler/compiler.js +6 -0
  128. package/package.json +5 -5
@@ -97,7 +97,6 @@ export interface InputProps {
97
97
  'placeholder-style'?: { color?: string }
98
98
  'enable-offset'?: boolean
99
99
  'enable-var'?: boolean
100
- 'parent-font-size'?: number
101
100
  'parent-width'?: number
102
101
  'parent-height'?: number
103
102
  // 只有 RN 环境读取
@@ -147,7 +146,6 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
147
146
  'selection-start': selectionStart = -1,
148
147
  'selection-end': selectionEnd = -1,
149
148
  'enable-var': enableVar,
150
- 'parent-font-size': parentFontSize,
151
149
  'parent-width': parentWidth,
152
150
  'parent-height': parentHeight,
153
151
  'adjust-position': adjustPosition = true,
@@ -210,7 +208,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
210
208
  normalStyle,
211
209
  setWidth,
212
210
  setHeight
213
- } = useTransformStyle(styleObj, { enableVar, parentFontSize, parentWidth, parentHeight })
211
+ } = useTransformStyle(styleObj, { enableVar, parentWidth, parentHeight })
214
212
 
215
213
  const nodeRef = useRef(null)
216
214
  useNodesRef(props, ref, nodeRef, {
@@ -293,7 +291,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
293
291
  setKeyboardAvoidContext()
294
292
  }
295
293
 
296
- const onTouchEnd = (evt: NativeSyntheticEvent<NativeTouchEvent & { origin?: string }>) => {
294
+ const markEventOrigin = (evt: NativeSyntheticEvent<NativeTouchEvent & { origin?: string }>) => {
297
295
  evt.nativeEvent.origin = 'input'
298
296
  }
299
297
 
@@ -471,7 +469,18 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
471
469
  // React Native 的 TextInput 在 textAlign center + placeholder 时光标会跑到右边
472
470
  // 这个问题只在 Android 上出现
473
471
  // 参考:https://github.com/facebook/react-native/issues/28794 (Android only)
474
- const needMultilineFix = isAndroid && !multiline
472
+ const conditionalTextInputProps: {
473
+ multiline?: boolean
474
+ numberOfLines?: number
475
+ enterKeyHint?: ConfirmType
476
+ } = {}
477
+ if (isAndroid && !multiline && props.placeholder && normalStyle.textAlign === 'center') {
478
+ conditionalTextInputProps.multiline = true
479
+ conditionalTextInputProps.numberOfLines = 1
480
+ }
481
+ if (!multiline || confirmType !== 'return') {
482
+ conditionalTextInputProps.enterKeyHint = confirmType
483
+ }
475
484
 
476
485
  const innerProps = useInnerProps(
477
486
  extendObject(
@@ -492,13 +501,14 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
492
501
  autoFocus: isAutoFocus,
493
502
  selection: selectionStart > -1 || typeof cursor === 'number' ? selection : undefined,
494
503
  selectionColor: cursorColor,
495
- blurOnSubmit: multiline ? confirmType !== 'return' : !confirmHold,
504
+ submitBehavior: multiline ? (confirmType === 'return' ? 'newline' : 'blurAndSubmit') : (confirmHold ? 'submit' : 'blurAndSubmit'),
496
505
  underlineColorAndroid: 'rgba(0,0,0,0)',
497
506
  textAlignVertical: textAlignVertical,
498
507
  placeholderTextColor: placeholderStyle?.color,
499
- multiline: multiline || needMultilineFix,
508
+ multiline,
500
509
  onTouchStart,
501
- onTouchEnd,
510
+ onTouchEnd: markEventOrigin,
511
+ onTouchMove: markEventOrigin,
502
512
  onFocus,
503
513
  onBlur,
504
514
  onChange,
@@ -506,8 +516,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
506
516
  onContentSizeChange,
507
517
  onSubmitEditing: bindconfirm && onSubmitEditing
508
518
  },
509
- needMultilineFix ? { numberOfLines: 1 } : {},
510
- !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }
519
+ conditionalTextInputProps
511
520
  ),
512
521
  [
513
522
  'name',
@@ -16,7 +16,6 @@ export interface LabelProps {
16
16
  'enable-offset'?: boolean
17
17
  'enable-var'?: boolean
18
18
  'enable-text-pass-through'?: boolean
19
- 'parent-font-size'?: number
20
19
  'parent-width'?: number
21
20
  'parent-height'?: number
22
21
  children: ReactNode
@@ -32,7 +31,6 @@ const Label = forwardRef<HandlerRef<View, LabelProps>, LabelProps>(
32
31
  style = {},
33
32
  'enable-var': enableVar,
34
33
  'enable-text-pass-through': enableTextPassThrough,
35
- 'parent-font-size': parentFontSize,
36
34
  'parent-width': parentWidth,
37
35
  'parent-height': parentHeight
38
36
  } = props
@@ -51,7 +49,7 @@ const Label = forwardRef<HandlerRef<View, LabelProps>, LabelProps>(
51
49
  varContextRef,
52
50
  setWidth,
53
51
  setHeight
54
- } = useTransformStyle(style, { enableVar, parentFontSize, parentWidth, parentHeight, defaultStyle })
52
+ } = useTransformStyle(style, { enableVar, parentWidth, parentHeight, defaultStyle })
55
53
 
56
54
  const nodeRef = useRef(null)
57
55
  useNodesRef(props, ref, nodeRef, { style: normalStyle })
@@ -17,13 +17,12 @@ interface MovableAreaProps {
17
17
  height?: number
18
18
  'enable-offset'?: boolean
19
19
  'enable-var'?: boolean
20
- 'parent-font-size'?: number
21
20
  'parent-width'?: number
22
21
  'parent-height'?: number
23
22
  }
24
23
 
25
24
  const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaProps>((props: MovableAreaProps, ref): JSX.Element => {
26
- const { style = {}, 'enable-var': enableVar, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props
25
+ const { style = {}, 'enable-var': enableVar, 'parent-width': parentWidth, 'parent-height': parentHeight } = props
27
26
 
28
27
  const {
29
28
  hasSelfPercent,
@@ -33,7 +32,7 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
33
32
  hasPositionFixed,
34
33
  setWidth,
35
34
  setHeight
36
- } = useTransformStyle(style, { enableVar, parentFontSize, parentWidth, parentHeight })
35
+ } = useTransformStyle(style, { enableVar, parentWidth, parentHeight })
37
36
 
38
37
  const movableViewRef = useRef(null)
39
38
  useNodesRef(props, ref, movableViewRef, {
@@ -180,7 +180,6 @@ interface MovableViewProps {
180
180
  inertia?: boolean
181
181
  'enable-var'?: boolean
182
182
  'enable-text-pass-through'?: boolean
183
- 'parent-font-size'?: number
184
183
  'parent-width'?: number
185
184
  'parent-height'?: number
186
185
  'disable-event-passthrough'?: boolean
@@ -214,7 +213,6 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
214
213
  'out-of-bounds': outOfBounds = false,
215
214
  'enable-var': enableVar,
216
215
  'enable-text-pass-through': enableTextPassThrough,
217
- 'parent-font-size': parentFontSize,
218
216
  'parent-width': parentWidth,
219
217
  'parent-height': parentHeight,
220
218
  direction = 'none',
@@ -243,7 +241,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
243
241
  varContextRef,
244
242
  setWidth,
245
243
  setHeight
246
- } = useTransformStyle(Object.assign({}, style, styles.container), { enableVar, parentFontSize, parentWidth, parentHeight })
244
+ } = useTransformStyle(Object.assign({}, style, styles.container), { enableVar, parentWidth, parentHeight })
247
245
 
248
246
  const navigation = useNavigation()
249
247
 
@@ -95,7 +95,7 @@ const MpxNav = memo(({ pageConfig, navigation }: MpxNavProps) => {
95
95
  }
96
96
  const isCustom = innerPageConfig.navigationStyle === 'custom'
97
97
  const navigationBarTextStyle = useMemo(() => validBarTextStyle(innerPageConfig.navigationBarTextStyle), [innerPageConfig.navigationBarTextStyle])
98
- // 状态栏的颜色
98
+ // 状态栏由 MpxNav 根据页面配置统一控制,避免 native-stack screenOptions 在页面切换时覆盖页面级配置。
99
99
  const statusBarElement = (
100
100
  <StatusBar
101
101
  translucent
@@ -6,10 +6,11 @@ import PickerMultiSelector from './multiSelector'
6
6
  import PickerTime from './time'
7
7
  import PickerDate from './date'
8
8
  import PickerRegion from './region'
9
+ import Portal from '../mpx-portal'
9
10
  import { FormContext, FormFieldValue, RouteContext } from '../context'
10
11
  import useNodesRef, { HandlerRef } from '../useNodesRef'
11
12
  import useInnerProps, { getCustomEvent } from '../getInnerListeners'
12
- import { extendObject, useLayout } from '../utils'
13
+ import { extendObject, splitProps, splitStyle, useLayout, useTextPassThrough, useTransformStyle, wrapChildren } from '../utils'
13
14
  import { createPopupManager } from '../mpx-popup'
14
15
  import { EventType, LanguageCode, PickerMode, PickerProps } from './type'
15
16
 
@@ -78,13 +79,13 @@ const styles = StyleSheet.create({
78
79
  }
79
80
  })
80
81
 
81
- const pickerModalMap: Record<PickerMode, React.ComponentType<PickerProps>> = {
82
+ const pickerModalMap = {
82
83
  [PickerMode.SELECTOR]: PickerSelector,
83
84
  [PickerMode.MULTI_SELECTOR]: PickerMultiSelector,
84
85
  [PickerMode.TIME]: PickerTime,
85
86
  [PickerMode.DATE]: PickerDate,
86
87
  [PickerMode.REGION]: PickerRegion
87
- }
88
+ } satisfies Record<PickerMode, React.ComponentType<any>>
88
89
 
89
90
  const getDefaultValue = (mode: PickerMode) => {
90
91
  switch (mode) {
@@ -111,17 +112,26 @@ const buttonTextMap: Record<LanguageCode, { cancel: string; confirm: string }> =
111
112
  }
112
113
 
113
114
  const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
114
- (props: PickerProps, ref): React.JSX.Element => {
115
+ (pickerProps: PickerProps, ref): React.JSX.Element => {
116
+ const { textProps, innerProps: splitInnerProps } = splitProps(pickerProps)
117
+ const props = (splitInnerProps || {}) as PickerProps
115
118
  const {
116
119
  mode,
117
120
  value,
118
- range = null,
121
+ range = [],
119
122
  children,
120
123
  disabled,
121
124
  bindcancel,
122
125
  bindchange,
123
- 'header-text': headerText = ''
126
+ 'header-text': headerText = '',
127
+ style,
128
+ 'enable-var': enableVar,
129
+ 'enable-text-pass-through': enableTextPassThrough,
130
+ 'parent-width': parentWidth,
131
+ 'parent-height': parentHeight
124
132
  } = props
133
+ const modalProps = props as any
134
+ const rangeKey = modalProps['range-key']
125
135
 
126
136
  const { pageId } = useContext(RouteContext) || {}
127
137
  const buttonText = buttonTextMap[(global.__mpx?.i18n?.locale as LanguageCode) || 'zh-CN']
@@ -129,12 +139,31 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
129
139
  pickerValue.current = Array.isArray(value) ? value.slice() : value
130
140
  const nodeRef = useRef<View>(null)
131
141
  const pickerRef = useRef<any>(null)
132
- const { open, show, hide, remove } = useRef(createPopupManager()).current
142
+ const { open, show, hide, remove, update } = useRef(createPopupManager()).current
143
+ const {
144
+ normalStyle,
145
+ hasVarDec,
146
+ varContextRef,
147
+ hasSelfPercent,
148
+ hasPositionFixed,
149
+ setWidth,
150
+ setHeight
151
+ } = useTransformStyle(style, { enableVar, parentWidth, parentHeight })
152
+ const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle)
153
+ const textPassThrough = useTextPassThrough(textStyle, textProps, { enableTextPassThrough })
133
154
 
134
- useNodesRef<View, PickerProps>(props, ref, nodeRef)
135
- const { layoutRef, layoutProps } = useLayout({
155
+ if (backgroundStyle) {
156
+ warn('Picker does not support background image-related styles!')
157
+ }
158
+
159
+ useNodesRef<View, PickerProps>(props, ref, nodeRef, {
160
+ style: normalStyle
161
+ })
162
+ const { layoutRef, layoutProps, layoutStyle } = useLayout({
136
163
  props,
137
- hasSelfPercent: false,
164
+ hasSelfPercent,
165
+ setWidth,
166
+ setHeight,
138
167
  nodeRef
139
168
  })
140
169
 
@@ -143,7 +172,8 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
143
172
  {},
144
173
  props,
145
174
  {
146
- ref: nodeRef
175
+ ref: nodeRef,
176
+ style: extendObject({}, innerStyle, layoutStyle)
147
177
  },
148
178
  layoutProps
149
179
  ),
@@ -151,6 +181,12 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
151
181
  'mode',
152
182
  'value',
153
183
  'range',
184
+ 'range-key',
185
+ 'start',
186
+ 'end',
187
+ 'fields',
188
+ 'level',
189
+ 'custom-item',
154
190
  'disabled',
155
191
  'bindcancel',
156
192
  'bindchange',
@@ -163,9 +199,9 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
163
199
 
164
200
  useEffect(() => {
165
201
  if (range && pickerRef.current && mode === PickerMode.MULTI_SELECTOR) {
166
- pickerRef.current.updateRange?.(range)
202
+ pickerRef.current.updateRange?.(range, rangeKey)
167
203
  }
168
- }, [JSON.stringify(range)])
204
+ }, [JSON.stringify(range), rangeKey, mode])
169
205
 
170
206
  /** --- form 表单组件内部方法 --- */
171
207
  const getValue = () => {
@@ -228,15 +264,9 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
228
264
  hide()
229
265
  }
230
266
 
231
- const specificProps = extendObject({}, innerProps, {
232
- mode,
233
- children,
234
- bindchange: onChange,
235
- bindcolumnchange: onColumnChange,
236
- getRange: () => range
237
- })
267
+ const getContentHeight = () => headerText ? 350 : 310
238
268
 
239
- const renderPickerContent = () => {
269
+ const getPickerContent = () => {
240
270
  if (disabled) {
241
271
  return null
242
272
  }
@@ -244,9 +274,21 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
244
274
  if (!(_mode in pickerModalMap)) {
245
275
  return warn(`[Mpx runtime warn]: Unsupported <picker> mode: ${mode}`)
246
276
  }
277
+ const specificProps = {
278
+ mode: _mode,
279
+ range,
280
+ 'range-key': rangeKey,
281
+ start: modalProps.start,
282
+ end: modalProps.end,
283
+ fields: modalProps.fields,
284
+ level: modalProps.level,
285
+ 'custom-item': modalProps['custom-item'],
286
+ bindchange: onChange,
287
+ bindcolumnchange: onColumnChange
288
+ } as PickerProps
247
289
  const _value: any = value
248
- const PickerModal = pickerModalMap[_mode]
249
- const renderPickerModal = (
290
+ const PickerModal = pickerModalMap[_mode] as React.ComponentType<PickerProps>
291
+ return (
250
292
  <>
251
293
  {headerText && (
252
294
  <View style={[styles.header]}>
@@ -270,22 +312,51 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
270
312
  </View>
271
313
  </>
272
314
  )
273
- const contentHeight = headerText ? 350 : 310
274
- open(renderPickerModal, pageId, { contentHeight })
315
+ }
316
+
317
+ const openPickerContent = () => {
318
+ const renderPickerModal = getPickerContent()
319
+ if (!renderPickerModal) {
320
+ return
321
+ }
322
+ open(renderPickerModal, pageId, { contentHeight: getContentHeight() })
275
323
  }
276
324
 
277
325
  useEffect(() => {
278
- renderPickerContent()
326
+ openPickerContent()
279
327
  return () => {
280
328
  remove()
281
329
  }
282
330
  }, [])
283
331
 
284
- return createElement(
332
+ const showPicker = () => {
333
+ const renderPickerModal = getPickerContent()
334
+ if (!renderPickerModal) {
335
+ return
336
+ }
337
+ update(renderPickerModal, { contentHeight: getContentHeight() })
338
+ show()
339
+ }
340
+
341
+ const finalComponent = createElement(
285
342
  TouchableWithoutFeedback,
286
- { onPress: show },
287
- createElement(View, innerProps, children)
343
+ { onPress: showPicker },
344
+ createElement(
345
+ View,
346
+ innerProps,
347
+ wrapChildren(children, {
348
+ hasVarDec,
349
+ varContext: varContextRef.current,
350
+ textPassThrough
351
+ })
352
+ )
288
353
  )
354
+
355
+ if (hasPositionFixed) {
356
+ return createElement(Portal, null, finalComponent)
357
+ }
358
+
359
+ return finalComponent
289
360
  }
290
361
  )
291
362
 
@@ -23,7 +23,7 @@ const styles = StyleSheet.create({
23
23
  })
24
24
 
25
25
  const formatRangeFun = (range: RangeItem[], rangeKey = '') =>
26
- rangeKey ? range.map((item: Obj) => item[rangeKey]) : range
26
+ rangeKey ? range.map((item) => (item as Obj)[rangeKey]) : range
27
27
 
28
28
  const formatValueFn = (value: number | number[]) => {
29
29
  return Array.isArray(value) ? value : [value]
@@ -54,8 +54,8 @@ const PickerMultiSelector = forwardRef<
54
54
  }
55
55
  }, [formatValue])
56
56
 
57
- const updateRange = (newRange: RangeItem[]) => {
58
- const range = formatRangeFun(newRange.slice(), props['range-key'])
57
+ const updateRange = (newRange: RangeItem[], rangeKey?: string) => {
58
+ const range = formatRangeFun(newRange.slice(), rangeKey)
59
59
  setFormatRange(range)
60
60
  }
61
61
 
@@ -24,7 +24,7 @@ const styles = StyleSheet.create({
24
24
  })
25
25
 
26
26
  const formatRangeFun = (range: RangeItem[], rangeKey = '') =>
27
- rangeKey ? range.map((item: Obj) => item[rangeKey]) : range
27
+ rangeKey ? range.map((item) => (item as Obj)[rangeKey]) : range
28
28
 
29
29
  const formatValueFn = (value: number | number[] = 0) => {
30
30
  const _value = Array.isArray(value) ? value[0] : value
@@ -28,6 +28,10 @@ export interface BasePickerProps {
28
28
  /** 作为表单组件时的名称 */
29
29
  name?: string
30
30
  style?: Record<string, any>
31
+ 'enable-var'?: boolean
32
+ 'enable-text-pass-through'?: boolean
33
+ 'parent-width'?: number
34
+ 'parent-height'?: number
31
35
  children?: React.ReactNode
32
36
  range?: RangeItem[]
33
37
  ref?: any
@@ -11,7 +11,6 @@ import {
11
11
  extendObject,
12
12
  useTextPassThrough
13
13
  } from '../utils'
14
- import { PickerViewStyleContext } from './pickerVIewContext'
15
14
  import Portal from '../mpx-portal'
16
15
  import type { AnyFunc } from '../types/common'
17
16
  /**
@@ -76,6 +75,7 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
76
75
  'mask-style': pickerMaskStyle = {},
77
76
  'enable-var': enableVar,
78
77
  'enable-text-pass-through': enableTextPassThrough
78
+
79
79
  } = props
80
80
  const { height: indicatorH, ...pickerIndicatorStyle } = indicatorStyle
81
81
  const nodeRef = useRef(null)
@@ -187,15 +187,7 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
187
187
  enableWheelAnimation
188
188
  }
189
189
  )
190
- const realElement = React.cloneElement(child, wrappedProps)
191
- return wrapChildren(
192
- realElement,
193
- {
194
- hasVarDec,
195
- varContext: varContextRef.current,
196
- textPassThrough
197
- }
198
- )
190
+ return React.cloneElement(child, wrappedProps)
199
191
  }
200
192
 
201
193
  const validateChildInitialIndex = (index: number, data: React.ReactNode[]) => {
@@ -230,15 +222,18 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
230
222
  }
231
223
 
232
224
  const finalComponent = createElement(
233
- PickerViewStyleContext.Provider,
234
- { value: textStyle },
225
+ View,
226
+ innerProps,
235
227
  createElement(
236
228
  View,
237
- innerProps,
238
- createElement(
239
- View,
240
- { style: [styles.wrapper] },
241
- renderPickerColumns()
229
+ { style: [styles.wrapper] },
230
+ wrapChildren(
231
+ renderPickerColumns(),
232
+ {
233
+ hasVarDec,
234
+ varContext: varContextRef.current,
235
+ textPassThrough
236
+ }
242
237
  )
243
238
  )
244
239
  )
@@ -16,12 +16,3 @@ export const usePickerViewColumnAnimationContext = () => {
16
16
  }
17
17
  return value
18
18
  }
19
-
20
- export const PickerViewStyleContext = createContext<
21
- Record<string, any> | undefined
22
- >(undefined)
23
-
24
- export const usePickerViewStyleContext = () => {
25
- const value = useContext(PickerViewStyleContext)
26
- return value
27
- }
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback, createElement } from 'react'
2
2
  import { GestureResponderEvent, LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, ScrollView, StyleSheet, View } from 'react-native'
3
3
  import Reanimated, { AnimatedRef, useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'
4
- import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS, isHarmony, extendObject } from '../utils'
4
+ import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, isIOS, isHarmony, extendObject, useTextPassThrough, wrapChildren } from '../utils'
5
5
  import useNodesRef, { HandlerRef } from '../useNodesRef'
6
6
  import PickerIndicator from './pickerViewIndicator'
7
7
  import PickerMask from './pickerViewMask'
@@ -26,6 +26,7 @@ interface ColumnProps {
26
26
  pickerMaskStyle: Record<string, any>
27
27
  pickerIndicatorStyle: Record<string, any>
28
28
  enableWheelAnimation?: boolean
29
+ 'enable-text-pass-through'?: boolean
29
30
  }
30
31
 
31
32
  const visibleCount = 5
@@ -41,17 +42,22 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
41
42
  pickerMaskStyle,
42
43
  pickerIndicatorStyle,
43
44
  enableWheelAnimation = true,
44
- 'enable-var': enableVar
45
+ 'enable-var': enableVar,
46
+ 'enable-text-pass-through': enableTextPassThrough
47
+
45
48
  } = props
46
49
 
47
50
  const {
48
51
  normalStyle,
52
+ hasVarDec,
53
+ varContextRef,
49
54
  hasSelfPercent,
50
55
  setWidth,
51
56
  setHeight
52
57
  } = useTransformStyle(style, { enableVar })
53
- const { textStyle = {} } = splitStyle(normalStyle)
54
- const { textProps = {} } = splitProps(props)
58
+ const { textStyle } = splitStyle(normalStyle)
59
+ const { textProps } = splitProps(props)
60
+ const textPassThrough = useTextPassThrough(textStyle, textProps, { enableTextPassThrough })
55
61
  const scrollViewRef = useAnimatedRef<Reanimated.ScrollView>()
56
62
  const offsetYShared = useScrollViewOffset(scrollViewRef as AnimatedRef<Reanimated.ScrollView>)
57
63
 
@@ -60,14 +66,14 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
60
66
  })
61
67
 
62
68
  const { height: pickerH, itemHeight } = wrapperStyle
63
- const [itemRawH, setItemRawH] = useState(itemHeight)
69
+ const [itemRawH, setItemRawH] = useState(Math.round(itemHeight))
64
70
  const maxIndex = useMemo(() => columnData.length - 1, [columnData])
65
71
  const prevScrollingInfo = useRef({ index: initialIndex, y: 0 })
66
72
  const dragging = useRef(false)
67
73
  const scrolling = useRef(false)
68
- const timerResetPosition = useRef<NodeJS.Timeout | null>(null)
69
- const timerScrollTo = useRef<NodeJS.Timeout | null>(null)
70
- const timerClickOnce = useRef<NodeJS.Timeout | null>(null)
74
+ const timerResetPosition = useRef<ReturnType<typeof setTimeout> | null>(null)
75
+ const timerScrollTo = useRef<ReturnType<typeof setTimeout> | null>(null)
76
+ const timerClickOnce = useRef<ReturnType<typeof setTimeout> | null>(null)
71
77
  const activeIndex = useRef(initialIndex)
72
78
  const prevIndex = usePrevious(initialIndex)
73
79
  const prevMaxIndex = usePrevious(maxIndex)
@@ -83,8 +89,8 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
83
89
  })
84
90
 
85
91
  const paddingHeight = useMemo(
86
- () => Math.round((pickerH - itemHeight) / 2),
87
- [pickerH, itemHeight]
92
+ () => (pickerH - itemRawH) / 2,
93
+ [pickerH, itemRawH]
88
94
  )
89
95
 
90
96
  const snapToOffsets = useMemo(
@@ -134,6 +140,16 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
134
140
  }
135
141
  }, [])
136
142
 
143
+ // `contentOffset` prop sets visual position but does not fire scroll events,
144
+ // so `offsetYShared` (from `useScrollViewOffset`) stays at 0 until the user scrolls.
145
+ // Directly sync it whenever `itemRawH` is established so wheel animation renders correctly.
146
+ useEffect(() => {
147
+ if (!itemRawH || dragging.current || scrolling.current) {
148
+ return
149
+ }
150
+ offsetYShared.value = activeIndex.current * itemRawH
151
+ }, [itemRawH])
152
+
137
153
  useEffect(() => {
138
154
  if (
139
155
  !scrollViewRef.current ||
@@ -158,13 +174,20 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
158
174
  }, isIOS ? 0 : 200)
159
175
  }, [itemRawH, maxIndex, initialIndex])
160
176
 
177
+ useEffect(() => {
178
+ const roundedH = Math.round(itemHeight)
179
+ if (roundedH) {
180
+ setItemRawH(roundedH)
181
+ }
182
+ }, [itemHeight])
183
+
161
184
  const onItemLayout = useCallback((e: LayoutChangeEvent) => {
162
185
  const { height: rawH } = e.nativeEvent.layout
163
186
  const roundedH = Math.round(rawH)
164
- if (roundedH && roundedH !== itemRawH) {
187
+ if (roundedH) {
165
188
  setItemRawH(roundedH)
166
189
  }
167
- }, [itemRawH])
190
+ }, [])
168
191
 
169
192
  const resetScrollPosition = useCallback((y: number) => {
170
193
  if (dragging.current || scrolling.current) {
@@ -287,9 +310,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
287
310
  key={index}
288
311
  item={item}
289
312
  index={index}
290
- itemHeight={itemHeight}
291
- textStyle={textStyle}
292
- textProps={textProps}
313
+ itemHeight={itemRawH}
293
314
  visibleCount={visibleCount}
294
315
  onItemLayout={onItemLayout}
295
316
  />)
@@ -297,9 +318,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
297
318
  key={index}
298
319
  item={item}
299
320
  index={index}
300
- itemHeight={itemHeight}
301
- textStyle={textStyle}
302
- textProps={textProps}
321
+ itemHeight={itemRawH}
303
322
  onItemLayout={onItemLayout}
304
323
  />)
305
324
  })
@@ -333,21 +352,25 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
333
352
  createElement(
334
353
  Reanimated.ScrollView,
335
354
  innerProps,
336
- renderInnerchild()
355
+ wrapChildren(renderInnerchild(), {
356
+ hasVarDec,
357
+ varContext: varContextRef.current,
358
+ textPassThrough
359
+ })
337
360
  )
338
361
  )
339
362
  }
340
363
 
341
364
  const renderIndicator = () => (
342
365
  <PickerIndicator
343
- itemHeight={itemHeight}
366
+ itemHeight={itemRawH}
344
367
  indicatorItemStyle={pickerIndicatorStyle}
345
368
  />
346
369
  )
347
370
 
348
371
  const renderMask = () => (
349
372
  <PickerMask
350
- itemHeight={itemHeight}
373
+ itemHeight={itemRawH}
351
374
  maskContainerStyle={pickerMaskStyle}
352
375
  />
353
376
  )