@mpxjs/webpack-plugin 2.9.69 → 2.9.70

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 (111) hide show
  1. package/lib/parser.js +1 -1
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +51 -54
  4. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  5. package/lib/platform/template/wx/component-config/index.js +1 -1
  6. package/lib/platform/template/wx/component-config/input.js +1 -1
  7. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  8. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  9. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  10. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  11. package/lib/react/processTemplate.js +3 -0
  12. package/lib/runtime/components/react/context.ts +4 -0
  13. package/lib/runtime/components/react/dist/context.js +1 -0
  14. package/lib/runtime/components/react/dist/event.config.js +24 -24
  15. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -166
  16. package/lib/runtime/components/react/dist/mpx-button.jsx +35 -42
  17. package/lib/runtime/components/react/dist/mpx-canvas/html.js +2 -4
  18. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +35 -13
  19. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  20. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  21. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  22. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  23. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  24. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  25. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  26. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  27. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  28. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  29. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  30. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  31. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  32. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  33. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  34. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  35. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -1
  36. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +5 -3
  37. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  38. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  39. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  40. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  41. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  42. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  43. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  44. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +4 -2
  45. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  46. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  47. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  48. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  49. package/lib/runtime/components/react/dist/mpx-view.jsx +34 -46
  50. package/lib/runtime/components/react/dist/mpx-web-view.jsx +105 -42
  51. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -10
  52. package/lib/runtime/components/react/dist/utils.jsx +107 -82
  53. package/lib/runtime/components/react/event.config.ts +25 -26
  54. package/lib/runtime/components/react/getInnerListeners.ts +238 -188
  55. package/lib/runtime/components/react/mpx-button.tsx +64 -50
  56. package/lib/runtime/components/react/mpx-canvas/html.ts +2 -4
  57. package/lib/runtime/components/react/mpx-canvas/index.tsx +46 -48
  58. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  59. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  60. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  61. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  62. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  63. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  64. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  65. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  66. package/lib/runtime/components/react/mpx-movable-view.tsx +21 -25
  67. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  68. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  69. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  70. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  71. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  72. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  73. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  74. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  75. package/lib/runtime/components/react/mpx-picker-view-column.tsx +4 -1
  76. package/lib/runtime/components/react/mpx-picker-view.tsx +7 -1
  77. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  78. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  79. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  80. package/lib/runtime/components/react/mpx-rich-text/index.tsx +121 -0
  81. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  82. package/lib/runtime/components/react/mpx-scroll-view.tsx +72 -71
  83. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  84. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  85. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  86. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  87. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  88. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  89. package/lib/runtime/components/react/mpx-view.tsx +55 -65
  90. package/lib/runtime/components/react/mpx-web-view.tsx +108 -63
  91. package/lib/runtime/components/react/types/global.d.ts +3 -17
  92. package/lib/runtime/components/react/useAnimationHooks.ts +36 -12
  93. package/lib/runtime/components/react/utils.tsx +113 -82
  94. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  95. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  96. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  97. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  98. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  99. package/lib/runtime/optionProcessor.js +7 -38
  100. package/lib/runtime/utils.js +2 -0
  101. package/lib/style-compiler/plugins/scope-id.js +30 -2
  102. package/lib/template-compiler/bind-this.js +7 -2
  103. package/lib/template-compiler/compiler.js +77 -46
  104. package/lib/template-compiler/gen-node-react.js +2 -2
  105. package/lib/utils/pre-process-json.js +9 -5
  106. package/package.json +5 -4
  107. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  108. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  109. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  110. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  111. package/lib/runtime/components/web/event.js +0 -105
@@ -0,0 +1,436 @@
1
+ /**
2
+ * ✔ src
3
+ * ✔ mode
4
+ * ✘ show-menu-by-longpress
5
+ * ✔ binderror
6
+ * ✔ bindload
7
+ * ✘ fade-in
8
+ * ✔ webp
9
+ * ✘ lazy-load
10
+ * ✔ bindtap
11
+ * ✔ DEFAULT_SIZE
12
+ */
13
+ import { useEffect, useMemo, useState, useRef, forwardRef, createElement } from 'react'
14
+ import {
15
+ Image as RNImage,
16
+ View,
17
+ ImageStyle,
18
+ ImageResizeMode,
19
+ NativeSyntheticEvent,
20
+ ImageErrorEventData,
21
+ LayoutChangeEvent,
22
+ DimensionValue,
23
+ ImageLoadEventData
24
+ } from 'react-native'
25
+ import { noop } from '@mpxjs/utils'
26
+ import { SvgCssUri } from 'react-native-svg/css'
27
+ import useInnerProps, { getCustomEvent } from './getInnerListeners'
28
+ import useNodesRef, { HandlerRef } from './useNodesRef'
29
+ import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils'
30
+
31
+ export type Mode =
32
+ | 'scaleToFill'
33
+ | 'aspectFit'
34
+ | 'aspectFill'
35
+ | 'widthFix'
36
+ | 'heightFix'
37
+ | 'top'
38
+ | 'bottom'
39
+ | 'center'
40
+ | 'left'
41
+ | 'right'
42
+ | 'top left'
43
+ | 'top right'
44
+ | 'bottom left'
45
+ | 'bottom right'
46
+
47
+ export interface ImageProps {
48
+ src?: string
49
+ mode?: Mode
50
+ svg?: boolean
51
+ style?: ImageStyle & Record<string, any>
52
+ 'enable-offset'?: boolean;
53
+ 'enable-var'?: boolean
54
+ 'external-var-context'?: Record<string, any>
55
+ 'parent-font-size'?: number
56
+ 'parent-width'?: number
57
+ 'parent-height'?: number
58
+ 'enable-fast-image'?: boolean
59
+ bindload?: (evt: NativeSyntheticEvent<ImageLoadEventData> | unknown) => void
60
+ binderror?: (evt: NativeSyntheticEvent<ImageErrorEventData> | unknown) => void
61
+ }
62
+
63
+ interface ImageState {
64
+ viewWidth?: number
65
+ viewHeight?: number
66
+ imageWidth?: number
67
+ imageHeight?: number
68
+ ratio?: number
69
+ }
70
+
71
+ const DEFAULT_IMAGE_WIDTH = 320
72
+ const DEFAULT_IMAGE_HEIGHT = 240
73
+
74
+ const cropMode: Mode[] = [
75
+ 'top',
76
+ 'bottom',
77
+ 'center',
78
+ 'right',
79
+ 'left',
80
+ 'top left',
81
+ 'top right',
82
+ 'bottom left',
83
+ 'bottom right'
84
+ ]
85
+
86
+ const ModeMap = new Map<Mode, ImageResizeMode | undefined>([
87
+ ['scaleToFill', 'stretch'],
88
+ ['aspectFit', 'contain'],
89
+ ['aspectFill', 'cover'],
90
+ ['widthFix', 'stretch'],
91
+ ['heightFix', 'stretch'],
92
+ ...cropMode.map<[Mode, ImageResizeMode]>(mode => [mode, 'stretch'])
93
+ ])
94
+
95
+ const isNumber = (value: DimensionValue) => typeof value === 'number'
96
+
97
+ const relativeCenteredSize = (viewSize: number, imageSize: number) => (viewSize - imageSize) / 2
98
+
99
+ function noMeetCalcRule (isSvg: boolean, mode: Mode, viewWidth: number, viewHeight: number, ratio: number) {
100
+ const isMeetSize = viewWidth && viewHeight && ratio
101
+ if (isSvg && !isMeetSize) return true
102
+ if (!isSvg && !['scaleToFill', 'aspectFit', 'aspectFill'].includes(mode) && !isMeetSize) return true
103
+ return false
104
+ }
105
+
106
+ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, ref): JSX.Element => {
107
+ const {
108
+ src = '',
109
+ mode = 'scaleToFill',
110
+ style = {},
111
+ 'enable-var': enableVar,
112
+ 'external-var-context': externalVarContext,
113
+ 'parent-font-size': parentFontSize,
114
+ 'enable-fast-image': enableFastImage,
115
+ 'parent-width': parentWidth,
116
+ 'parent-height': parentHeight,
117
+ bindload,
118
+ binderror
119
+ } = props
120
+
121
+ const defaultStyle = {
122
+ width: DEFAULT_IMAGE_WIDTH,
123
+ height: DEFAULT_IMAGE_HEIGHT
124
+ }
125
+
126
+ const styleObj = extendObject(
127
+ {},
128
+ defaultStyle,
129
+ style,
130
+ { overflow: 'hidden' }
131
+ )
132
+
133
+ const state = useRef<ImageState>({})
134
+
135
+ const nodeRef = useRef(null)
136
+ useNodesRef(props, ref, nodeRef, {
137
+ defaultStyle
138
+ })
139
+
140
+ const isSvg = SVG_REGEXP.test(src)
141
+ const isWidthFixMode = mode === 'widthFix'
142
+ const isHeightFixMode = mode === 'heightFix'
143
+ const isCropMode = cropMode.includes(mode)
144
+ const isLayoutMode = isWidthFixMode || isHeightFixMode || isCropMode
145
+ const resizeMode: ImageResizeMode = ModeMap.get(mode) || 'stretch'
146
+
147
+ const onLayout = ({ nativeEvent: { layout: { width, height } } }: LayoutChangeEvent) => {
148
+ state.current.viewWidth = width
149
+ state.current.viewHeight = height
150
+
151
+ if (state.current.imageWidth && state.current.imageHeight && state.current.ratio) {
152
+ setViewWidth(width)
153
+ setViewHeight(height)
154
+ setRatio(state.current.ratio)
155
+ setImageWidth(state.current.imageWidth)
156
+ setImageHeight(state.current.imageHeight)
157
+ state.current = {}
158
+ setLoaded(true)
159
+ }
160
+ }
161
+
162
+ const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
163
+
164
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({
165
+ props,
166
+ hasSelfPercent,
167
+ setWidth,
168
+ setHeight,
169
+ nodeRef,
170
+ onLayout: isLayoutMode ? onLayout : noop
171
+ })
172
+
173
+ const { width, height } = normalStyle
174
+
175
+ const [viewWidth, setViewWidth] = useState(isNumber(width) ? width : 0)
176
+ const [viewHeight, setViewHeight] = useState(isNumber(height) ? height : 0)
177
+ const [imageWidth, setImageWidth] = useState(0)
178
+ const [imageHeight, setImageHeight] = useState(0)
179
+ const [ratio, setRatio] = useState(0)
180
+ const [loaded, setLoaded] = useState(!isLayoutMode)
181
+
182
+ const fixedHeight = useMemo(() => {
183
+ const fixed = viewWidth * ratio
184
+ return !fixed ? viewHeight : fixed
185
+ }, [ratio, viewWidth, viewHeight])
186
+
187
+ const fixedWidth = useMemo(() => {
188
+ if (!ratio) return viewWidth
189
+ const fixed = viewHeight / ratio
190
+ return !fixed ? viewWidth : fixed
191
+ }, [ratio, viewWidth, viewHeight])
192
+
193
+ const modeStyle: ImageStyle = useMemo(() => {
194
+ if (noMeetCalcRule(isSvg, mode, viewWidth, viewHeight, ratio)) return {}
195
+ switch (mode) {
196
+ case 'scaleToFill':
197
+ case 'aspectFit':
198
+ if (isSvg) {
199
+ const scale = ratio <= 1
200
+ ? imageWidth >= viewWidth ? viewWidth / imageWidth : imageWidth / viewWidth
201
+ : imageHeight >= viewHeight ? viewHeight / imageHeight : imageHeight / viewHeight
202
+ return {
203
+ transform: [
204
+ { scale },
205
+ ratio <= 1 ? { translateY: -(imageHeight * scale - viewHeight) / 2 / scale } : { translateX: -(imageWidth * scale - viewWidth) / 2 / scale }
206
+ ]
207
+ }
208
+ }
209
+ return {}
210
+ case 'aspectFill':
211
+ if (isSvg) {
212
+ const scale = ratio >= 1
213
+ ? imageWidth >= viewWidth ? viewWidth / imageWidth : imageWidth / viewWidth
214
+ : imageHeight >= viewHeight ? viewHeight / imageHeight : imageHeight / viewHeight
215
+ return {
216
+ transform: [
217
+ { scale },
218
+ ratio >= 1 ? { translateY: -(imageHeight * scale - viewHeight) / 2 / scale } : { translateX: -(imageWidth * scale - viewWidth) / 2 / scale }
219
+ ]
220
+ }
221
+ }
222
+ return {}
223
+ case 'widthFix':
224
+ case 'heightFix':
225
+ if (isSvg) {
226
+ const scale = ratio >= 1
227
+ ? imageWidth >= fixedWidth ? fixedWidth / imageWidth : imageWidth / fixedWidth
228
+ : imageHeight >= fixedHeight ? fixedHeight / imageHeight : imageHeight / fixedHeight
229
+ return {
230
+ transform: [{ scale }]
231
+ }
232
+ }
233
+ return {}
234
+ case 'top':
235
+ return {
236
+ transform: [
237
+ { translateX: relativeCenteredSize(viewWidth, imageWidth) }
238
+ ]
239
+ }
240
+ case 'bottom':
241
+ return {
242
+ transform: [
243
+ { translateY: viewHeight - imageHeight },
244
+ { translateX: relativeCenteredSize(viewWidth, imageWidth) }
245
+ ]
246
+ }
247
+ case 'center':
248
+ return {
249
+ transform: [
250
+ { translateY: relativeCenteredSize(viewHeight, imageHeight) },
251
+ { translateX: relativeCenteredSize(viewWidth, imageWidth) }
252
+ ]
253
+ }
254
+ case 'left':
255
+ return {
256
+ transform: [
257
+ { translateY: relativeCenteredSize(viewHeight, imageHeight) }
258
+ ]
259
+ }
260
+ case 'right':
261
+ return {
262
+ transform: [
263
+ { translateY: relativeCenteredSize(viewHeight, imageHeight) },
264
+ { translateX: viewWidth - imageWidth }
265
+ ]
266
+ }
267
+ case 'top left':
268
+ return {}
269
+ case 'top right':
270
+ return {
271
+ transform: [
272
+ { translateX: viewWidth - imageWidth }
273
+ ]
274
+ }
275
+ case 'bottom left':
276
+ return {
277
+ transform: [
278
+ { translateY: viewHeight - imageHeight }
279
+ ]
280
+ }
281
+ case 'bottom right':
282
+ return {
283
+ transform: [
284
+ { translateY: viewHeight - imageHeight },
285
+ { translateX: viewWidth - imageWidth }
286
+ ]
287
+ }
288
+ default:
289
+ return {}
290
+ }
291
+ }, [isSvg, mode, viewWidth, viewHeight, imageWidth, imageHeight, ratio, fixedWidth, fixedHeight])
292
+
293
+ const onSvgLoad = (evt: LayoutChangeEvent) => {
294
+ const { width, height } = evt.nativeEvent.layout
295
+ setRatio(!width ? 0 : height / width)
296
+ setImageWidth(width)
297
+ setImageHeight(height)
298
+
299
+ bindload && bindload(
300
+ getCustomEvent(
301
+ 'load',
302
+ evt,
303
+ {
304
+ detail: { width, height },
305
+ layoutRef
306
+ },
307
+ props
308
+ )
309
+ )
310
+ }
311
+
312
+ const onSvgError = (evt: Error) => {
313
+ binderror!(
314
+ getCustomEvent(
315
+ 'error',
316
+ evt,
317
+ {
318
+ detail: { errMsg: evt?.message },
319
+ layoutRef
320
+ },
321
+ props
322
+ )
323
+ )
324
+ }
325
+
326
+ const onImageLoad = (evt: NativeSyntheticEvent<ImageLoadEventData>) => {
327
+ evt.persist()
328
+ RNImage.getSize(src, (width: number, height: number) => {
329
+ bindload!(
330
+ getCustomEvent(
331
+ 'load',
332
+ evt,
333
+ {
334
+ detail: { width, height },
335
+ layoutRef
336
+ },
337
+ props
338
+ )
339
+ )
340
+ })
341
+ }
342
+
343
+ const onImageError = (evt: NativeSyntheticEvent<ImageErrorEventData>) => {
344
+ binderror!(
345
+ getCustomEvent(
346
+ 'error',
347
+ evt,
348
+ {
349
+ detail: { errMsg: evt.nativeEvent.error },
350
+ layoutRef
351
+ },
352
+ props
353
+ )
354
+ )
355
+ }
356
+
357
+ useEffect(() => {
358
+ 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 = {}
375
+ setLoaded(true)
376
+ }
377
+ })
378
+ }
379
+ }, [src, isSvg, isLayoutMode])
380
+
381
+ const innerProps = useInnerProps(
382
+ props,
383
+ extendObject(
384
+ {
385
+ ref: nodeRef,
386
+ style: extendObject(
387
+ {},
388
+ normalStyle,
389
+ layoutStyle,
390
+ isHeightFixMode ? { width: fixedWidth } : {},
391
+ isWidthFixMode ? { height: fixedHeight } : {}
392
+ )
393
+ },
394
+ layoutProps
395
+ ),
396
+ [
397
+ 'src',
398
+ 'mode',
399
+ 'svg'
400
+ ],
401
+ {
402
+ layoutRef
403
+ }
404
+ )
405
+
406
+ return createElement(View, innerProps,
407
+ isSvg
408
+ ? createElement(SvgCssUri, {
409
+ uri: src,
410
+ onLayout: onSvgLoad,
411
+ onError: binderror && onSvgError,
412
+ style: extendObject(
413
+ { transformOrigin: 'top left' },
414
+ modeStyle
415
+ )
416
+ })
417
+ : loaded && renderImage({
418
+ source: { uri: src },
419
+ resizeMode: resizeMode,
420
+ onLoad: bindload && onImageLoad,
421
+ onError: binderror && onImageError,
422
+ style: extendObject(
423
+ {
424
+ transformOrigin: 'top left',
425
+ width: isCropMode ? imageWidth : '100%',
426
+ height: isCropMode ? imageHeight : '100%'
427
+ },
428
+ isCropMode ? modeStyle : {}
429
+ )
430
+ }, enableFastImage)
431
+ )
432
+ })
433
+
434
+ Image.displayName = 'mpx-image'
435
+
436
+ export default Image
@@ -17,7 +17,7 @@
17
17
  * ✔ cursor-color
18
18
  * ✔ selection-start
19
19
  * ✔ selection-end
20
- * adjust-position
20
+ * adjust-position
21
21
  * ✘ hold-keyboard
22
22
  * ✘ safe-password-cert-path
23
23
  * ✘ safe-password-length
@@ -37,7 +37,7 @@
37
37
  * ✘ bind:keyboardcompositionend
38
38
  * ✘ bind:onkeyboardheightchange
39
39
  */
40
- import { JSX, forwardRef, useMemo, useRef, useState, useContext, useEffect } from 'react'
40
+ import { JSX, forwardRef, useMemo, useRef, useState, useContext, useEffect, createElement } from 'react'
41
41
  import {
42
42
  KeyboardTypeOptions,
43
43
  Platform,
@@ -55,10 +55,10 @@ import {
55
55
  TextInputSubmitEditingEventData
56
56
  } from 'react-native'
57
57
  import { warn } from '@mpxjs/utils'
58
- import { parseInlineStyle, useUpdateEffect, useTransformStyle, useLayout } from './utils'
58
+ import { parseInlineStyle, useUpdateEffect, useTransformStyle, useLayout, extendObject } from './utils'
59
59
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
60
60
  import useNodesRef, { HandlerRef } from './useNodesRef'
61
- import { FormContext, FormFieldValue } from './context'
61
+ import { FormContext, FormFieldValue, KeyboardAvoidContext } from './context'
62
62
 
63
63
  type InputStyle = Omit<
64
64
  TextStyle & ViewStyle & Pick<FlexStyle, 'minHeight'>,
@@ -98,6 +98,7 @@ export interface InputProps {
98
98
  'parent-font-size'?: number
99
99
  'parent-width'?: number
100
100
  'parent-height'?: number
101
+ 'adjust-position': boolean,
101
102
  bindinput?: (evt: NativeSyntheticEvent<TextInputTextInputEventData> | unknown) => void
102
103
  bindfocus?: (evt: NativeSyntheticEvent<TextInputFocusEventData> | unknown) => void
103
104
  bindblur?: (evt: NativeSyntheticEvent<TextInputFocusEventData> | unknown) => void
@@ -106,6 +107,7 @@ export interface InputProps {
106
107
  }
107
108
 
108
109
  export interface PrivateInputProps {
110
+ allowFontScaling?: boolean
109
111
  multiline?: boolean
110
112
  'auto-height'?: boolean
111
113
  bindlinechange?: (evt: NativeSyntheticEvent<TextInputContentSizeChangeEventData> | unknown) => void
@@ -127,6 +129,7 @@ const keyboardTypeMap: Record<Type, string> = {
127
129
  const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps>((props: FinalInputProps, ref): JSX.Element => {
128
130
  const {
129
131
  style = {},
132
+ allowFontScaling = false,
130
133
  type = 'text',
131
134
  value,
132
135
  password,
@@ -146,6 +149,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
146
149
  'parent-font-size': parentFontSize,
147
150
  'parent-width': parentWidth,
148
151
  'parent-height': parentHeight,
152
+ 'adjust-position': adjustPosition = true,
149
153
  bindinput,
150
154
  bindfocus,
151
155
  bindblur,
@@ -159,6 +163,8 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
159
163
 
160
164
  const formContext = useContext(FormContext)
161
165
 
166
+ const setKeyboardAvoidEnabled = useContext(KeyboardAvoidContext)
167
+
162
168
  let formValuesMap: Map<string, FormFieldValue> | undefined
163
169
 
164
170
  if (formContext) {
@@ -170,20 +176,20 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
170
176
  const placeholderTextColor = parseInlineStyle(placeholderStyle)?.color
171
177
  const textAlignVertical = multiline ? 'top' : 'auto'
172
178
 
173
- const tmpValue = useRef<string>()
179
+ const tmpValue = useRef<string | undefined>(defaultValue)
174
180
  const cursorIndex = useRef<number>(0)
175
181
  const lineCount = useRef<number>(0)
176
182
 
177
183
  const [inputValue, setInputValue] = useState(defaultValue)
178
184
  const [contentHeight, setContentHeight] = useState(0)
179
185
 
180
- const styleObj = {
181
- padding: 0,
182
- ...style,
183
- ...multiline && autoHeight && {
184
- height: Math.max((style as any)?.minHeight || 35, contentHeight)
185
- }
186
- }
186
+ const styleObj = extendObject(
187
+ { padding: 0, backgroundColor: '#fff' },
188
+ style,
189
+ multiline && autoHeight
190
+ ? { minHeight: Math.max((style as any)?.minHeight || 35, contentHeight) }
191
+ : {}
192
+ )
187
193
 
188
194
  const {
189
195
  hasSelfPercent,
@@ -193,7 +199,9 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
193
199
  } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
194
200
 
195
201
  const nodeRef = useRef(null)
196
- useNodesRef(props, ref, nodeRef)
202
+ useNodesRef(props, ref, nodeRef, {
203
+ style: normalStyle
204
+ })
197
205
 
198
206
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
199
207
 
@@ -378,6 +386,10 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
378
386
  }
379
387
  }, [])
380
388
 
389
+ useEffect(() => {
390
+ setKeyboardAvoidEnabled?.(adjustPosition)
391
+ }, [adjustPosition])
392
+
381
393
  useUpdateEffect(() => {
382
394
  if (!nodeRef?.current) {
383
395
  return
@@ -387,52 +399,60 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
387
399
  : (nodeRef.current as TextInput)?.blur()
388
400
  }, [focus])
389
401
 
390
- const composeStyle = { ...normalStyle, ...layoutStyle }
391
-
392
- const innerProps = useInnerProps(props, {
393
- ref: nodeRef,
394
- style: {
395
- padding: 0,
396
- ...composeStyle,
397
- ...multiline && autoHeight && {
398
- height: Math.max((composeStyle as any)?.minHeight || 35, contentHeight)
402
+ const innerProps = useInnerProps(
403
+ props,
404
+ extendObject(
405
+ {
406
+ ref: nodeRef,
407
+ style: extendObject({}, normalStyle, layoutStyle),
408
+ allowFontScaling,
409
+ keyboardType: keyboardType,
410
+ secureTextEntry: !!password,
411
+ defaultValue: defaultValue,
412
+ value: inputValue,
413
+ maxLength: maxlength === -1 ? undefined : maxlength,
414
+ editable: !disabled,
415
+ autoFocus: !!autoFocus || !!focus,
416
+ returnKeyType: confirmType,
417
+ selection: selection,
418
+ selectionColor: cursorColor,
419
+ blurOnSubmit: !multiline && !confirmHold,
420
+ underlineColorAndroid: 'rgba(0,0,0,0)',
421
+ textAlignVertical: textAlignVertical,
422
+ placeholderTextColor: placeholderTextColor,
423
+ multiline: !!multiline
424
+ },
425
+ layoutProps,
426
+ {
427
+ onFocus: bindfocus && onInputFocus,
428
+ onBlur: bindblur && onInputBlur,
429
+ onKeyPress: bindconfirm && onKeyPress,
430
+ onSubmitEditing: bindconfirm && multiline && onSubmitEditing,
431
+ onSelectionChange: bindselectionchange && onSelectionChange,
432
+ onTextInput: onTextInput,
433
+ onChange: onChange,
434
+ onContentSizeChange: onContentSizeChange
399
435
  }
400
- },
401
- ...layoutProps,
402
- onFocus: bindfocus && onInputFocus,
403
- onBlur: bindblur && onInputBlur,
404
- onKeyPress: bindconfirm && onKeyPress,
405
- onSubmitEditing: bindconfirm && multiline && onSubmitEditing,
406
- onSelectionChange: bindselectionchange && onSelectionChange
407
- },
408
- [],
409
- {
410
- layoutRef
411
- })
412
-
413
- return (
414
- <TextInput
415
- {...innerProps}
416
- keyboardType={keyboardType as KeyboardTypeOptions}
417
- secureTextEntry={!!password}
418
- defaultValue={defaultValue}
419
- value={inputValue}
420
- maxLength={maxlength === -1 ? undefined : maxlength}
421
- editable={!disabled}
422
- autoFocus={!!autoFocus || !!focus}
423
- returnKeyType={confirmType}
424
- selection={selection}
425
- selectionColor={cursorColor}
426
- blurOnSubmit={!multiline && !confirmHold}
427
- underlineColorAndroid="rgba(0,0,0,0)"
428
- textAlignVertical={textAlignVertical}
429
- placeholderTextColor={placeholderTextColor}
430
- multiline={!!multiline}
431
- onTextInput={onTextInput}
432
- onChange={onChange}
433
- onContentSizeChange={onContentSizeChange}
434
- />
436
+ ),
437
+ [
438
+ 'type',
439
+ 'password',
440
+ 'placeholder-style',
441
+ 'disabled',
442
+ 'auto-focus',
443
+ 'focus',
444
+ 'confirm-type',
445
+ 'confirm-hold',
446
+ 'cursor',
447
+ 'cursor-color',
448
+ 'selection-start',
449
+ 'selection-end'
450
+ ],
451
+ {
452
+ layoutRef
453
+ }
435
454
  )
455
+ return createElement(TextInput, innerProps)
436
456
  })
437
457
 
438
458
  Input.displayName = 'MpxInput'