@mpxjs/webpack-plugin 2.10.20 → 2.10.21

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/index.js +13 -1
  2. package/lib/parser.js +1 -1
  3. package/lib/platform/style/wx/index.js +78 -30
  4. package/lib/platform/template/wx/component-config/block.js +2 -1
  5. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  6. package/lib/react/processTemplate.js +23 -10
  7. package/lib/react/style-helper.js +1 -1
  8. package/lib/react/template-loader.js +15 -2
  9. package/lib/runtime/components/react/context.ts +8 -1
  10. package/lib/runtime/components/react/dist/context.d.ts +6 -1
  11. package/lib/runtime/components/react/dist/context.js +1 -0
  12. package/lib/runtime/components/react/dist/getInnerListeners.js +1 -0
  13. package/lib/runtime/components/react/dist/mpx-button.d.ts +1 -1
  14. package/lib/runtime/components/react/dist/mpx-button.jsx +6 -5
  15. package/lib/runtime/components/react/dist/mpx-camera.jsx +1 -0
  16. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +4 -1
  17. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -1
  18. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +6 -4
  19. package/lib/runtime/components/react/dist/mpx-form.jsx +3 -3
  20. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +5 -1
  21. package/lib/runtime/components/react/dist/mpx-image.d.ts +3 -2
  22. package/lib/runtime/components/react/dist/mpx-image.jsx +46 -12
  23. package/lib/runtime/components/react/dist/mpx-inline-text.jsx +10 -6
  24. package/lib/runtime/components/react/dist/mpx-input.jsx +17 -4
  25. package/lib/runtime/components/react/dist/mpx-label.jsx +6 -4
  26. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +19 -4
  27. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +12 -2
  28. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +7 -4
  29. package/lib/runtime/components/react/dist/mpx-portal/index.jsx +5 -1
  30. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +4 -1
  31. package/lib/runtime/components/react/dist/mpx-radio.jsx +5 -4
  32. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +3 -1
  33. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -4
  34. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +52 -6
  35. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +36 -6
  36. package/lib/runtime/components/react/dist/mpx-slider.jsx +2 -1
  37. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +8 -4
  38. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +6 -4
  39. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +7 -4
  40. package/lib/runtime/components/react/dist/mpx-swiper.jsx +15 -4
  41. package/lib/runtime/components/react/dist/mpx-switch.jsx +4 -1
  42. package/lib/runtime/components/react/dist/mpx-text.jsx +57 -12
  43. package/lib/runtime/components/react/dist/mpx-video.d.ts +2 -1
  44. package/lib/runtime/components/react/dist/mpx-video.jsx +10 -4
  45. package/lib/runtime/components/react/dist/mpx-view.jsx +42 -7
  46. package/lib/runtime/components/react/dist/utils.d.ts +21 -11
  47. package/lib/runtime/components/react/dist/utils.jsx +102 -33
  48. package/lib/runtime/components/react/getInnerListeners.ts +1 -0
  49. package/lib/runtime/components/react/mpx-button.tsx +6 -5
  50. package/lib/runtime/components/react/mpx-camera.tsx +1 -0
  51. package/lib/runtime/components/react/mpx-canvas/index.tsx +4 -1
  52. package/lib/runtime/components/react/mpx-checkbox-group.tsx +2 -1
  53. package/lib/runtime/components/react/mpx-checkbox.tsx +6 -4
  54. package/lib/runtime/components/react/mpx-form.tsx +3 -3
  55. package/lib/runtime/components/react/mpx-icon/index.tsx +5 -1
  56. package/lib/runtime/components/react/mpx-image.tsx +58 -19
  57. package/lib/runtime/components/react/mpx-inline-text.tsx +12 -7
  58. package/lib/runtime/components/react/mpx-input.tsx +17 -4
  59. package/lib/runtime/components/react/mpx-label.tsx +6 -4
  60. package/lib/runtime/components/react/mpx-movable-view.tsx +20 -4
  61. package/lib/runtime/components/react/mpx-picker/index.tsx +12 -2
  62. package/lib/runtime/components/react/mpx-picker-view/index.tsx +8 -4
  63. package/lib/runtime/components/react/mpx-portal/index.tsx +5 -1
  64. package/lib/runtime/components/react/mpx-radio-group.tsx +4 -1
  65. package/lib/runtime/components/react/mpx-radio.tsx +5 -4
  66. package/lib/runtime/components/react/mpx-rich-text/index.tsx +3 -1
  67. package/lib/runtime/components/react/mpx-scroll-view.tsx +13 -4
  68. package/lib/runtime/components/react/mpx-simple-text.tsx +55 -8
  69. package/lib/runtime/components/react/mpx-simple-view.tsx +30 -6
  70. package/lib/runtime/components/react/mpx-slider.tsx +2 -1
  71. package/lib/runtime/components/react/mpx-sticky-header.tsx +8 -4
  72. package/lib/runtime/components/react/mpx-sticky-section.tsx +6 -4
  73. package/lib/runtime/components/react/mpx-swiper-item.tsx +7 -4
  74. package/lib/runtime/components/react/mpx-swiper.tsx +16 -4
  75. package/lib/runtime/components/react/mpx-switch.tsx +4 -1
  76. package/lib/runtime/components/react/mpx-text.tsx +55 -15
  77. package/lib/runtime/components/react/mpx-video.tsx +11 -5
  78. package/lib/runtime/components/react/mpx-view.tsx +35 -7
  79. package/lib/runtime/components/react/types/global.d.ts +4 -0
  80. package/lib/runtime/components/react/utils.tsx +123 -43
  81. package/lib/runtime/optionProcessorReact.js +5 -0
  82. package/lib/script-setup-compiler/index.js +1 -1
  83. package/lib/style-compiler/plugins/trans-special.js +1 -1
  84. package/lib/template-compiler/compiler.js +37 -14
  85. package/lib/utils/gen-component-tag.js +1 -5
  86. package/lib/utils/normalize-perf-options.js +47 -0
  87. package/lib/web/index.js +1 -0
  88. package/lib/web/processMainScript.js +3 -7
  89. package/lib/web/processScript.js +3 -6
  90. package/lib/web/processStyles.js +12 -3
  91. package/lib/wxml/loader.js +1 -1
  92. package/package.json +5 -4
@@ -1,20 +1,37 @@
1
- import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement, createElement } from 'react';
1
+ import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, createElement } from 'react';
2
2
  import { Image } from 'react-native';
3
3
  import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils';
4
- import { VarContext, ScrollViewContext, RouteContext } from './context';
4
+ import { VarContext, ScrollViewContext, RouteContext, TextPassThroughContext } from './context';
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser';
6
6
  import { initialWindowMetrics } from 'react-native-safe-area-context';
7
7
  import { Gesture } from 'react-native-gesture-handler';
8
- export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/;
8
+ export const TEXT_STYLE_MAP = {
9
+ color: true,
10
+ letterSpacing: true,
11
+ lineHeight: true,
12
+ includeFontPadding: true,
13
+ writingDirection: true
14
+ };
9
15
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/;
10
16
  export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/;
11
- export const SVG_REGEXP = /https?:\/\/.*\.(?:svg)/i;
12
- export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/;
13
- export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines|allowFontScaling/;
17
+ export const SVG_REGEXP = /\.svg(?:[?#].*)?$/i;
18
+ export const BACKGROUND_STYLE_MAP = {
19
+ backgroundImage: true,
20
+ backgroundSize: true,
21
+ backgroundRepeat: true,
22
+ backgroundPosition: true
23
+ };
24
+ export const TEXT_PROPS_MAP = {
25
+ ellipsizeMode: true,
26
+ numberOfLines: true
27
+ };
14
28
  export const DEFAULT_FONT_SIZE = 16;
15
29
  export const HIDDEN_STYLE = {
16
30
  opacity: 0
17
31
  };
32
+ export const DEFAULT_BOX_SIZING_STYLE = {
33
+ boxSizing: 'content-box'
34
+ };
18
35
  export const isIOS = __mpx_mode__ === 'ios';
19
36
  export const isAndroid = __mpx_mode__ === 'android';
20
37
  export const isHarmony = __mpx_mode__ === 'harmony';
@@ -23,9 +40,19 @@ const varUseRegExp = /var\(/;
23
40
  const unoVarDecRegExp = /^--un-/;
24
41
  const unoVarUseRegExp = /var\(--un-/;
25
42
  const calcUseRegExp = /calc\(/;
26
- const calcPercentExp = /^calc\(.*-?\d+(\.\d+)?%.*\)$/;
27
43
  const envUseRegExp = /env\(/;
28
- const filterRegExp = /(calc|env|%)/;
44
+ const boxSizingAffectingStyleMap = {
45
+ padding: true,
46
+ paddingTop: true,
47
+ paddingRight: true,
48
+ paddingBottom: true,
49
+ paddingLeft: true,
50
+ borderWidth: true,
51
+ borderTopWidth: true,
52
+ borderRightWidth: true,
53
+ borderBottomWidth: true,
54
+ borderLeftWidth: true
55
+ };
29
56
  const safeAreaInsetMap = {
30
57
  'safe-area-inset-top': 'top',
31
58
  'safe-area-inset-right': 'right',
@@ -33,6 +60,21 @@ const safeAreaInsetMap = {
33
60
  'safe-area-inset-left': 'left'
34
61
  };
35
62
  export const extendObject = Object.assign;
63
+ export function getDefaultAllowFontScaling() {
64
+ return global.__mpx?.config?.rnConfig?.allowFontScaling ?? false;
65
+ }
66
+ export function transformBoxSizing(style = {}, hasBoxSizingAffectingStyle = false) {
67
+ if (hasBoxSizingAffectingStyle && style.boxSizing === undefined) {
68
+ style.boxSizing = global.__mpx?.config?.rnConfig?.defaultBoxSizing ?? DEFAULT_BOX_SIZING_STYLE.boxSizing;
69
+ }
70
+ return style;
71
+ }
72
+ export function isBoxSizingAffectingStyle(key) {
73
+ return hasOwn(boxSizingAffectingStyleMap, key);
74
+ }
75
+ function isTextStyle(key) {
76
+ return hasOwn(TEXT_STYLE_MAP, key) || key.startsWith('font') || key.startsWith('text');
77
+ }
36
78
  function getSafeAreaInset(name, navigation) {
37
79
  const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets);
38
80
  return insets[safeAreaInsetMap[name]];
@@ -86,9 +128,12 @@ export function isText(ele) {
86
128
  }
87
129
  return false;
88
130
  }
89
- export function every(children, callback) {
90
- const childrenArray = Array.isArray(children) ? children : [children];
91
- return childrenArray.every((child) => callback(child));
131
+ export function isStringChildren(children) {
132
+ if (typeof children === 'string')
133
+ return true;
134
+ if (!Array.isArray(children))
135
+ return false;
136
+ return children.every((child) => typeof child === 'string');
92
137
  }
93
138
  export function groupBy(obj, callback, group = {}) {
94
139
  Object.entries(obj).forEach(([key, val]) => {
@@ -98,12 +143,13 @@ export function groupBy(obj, callback, group = {}) {
98
143
  });
99
144
  return group;
100
145
  }
101
- export function splitStyle(styleObj) {
102
- return groupBy(styleObj, (key) => {
103
- if (TEXT_STYLE_REGEX.test(key)) {
146
+ export function splitStyle(styleObj, sideEffect) {
147
+ return groupBy(styleObj, (key, val) => {
148
+ sideEffect && sideEffect(key, val);
149
+ if (isTextStyle(key)) {
104
150
  return 'textStyle';
105
151
  }
106
- else if (BACKGROUND_REGEX.test(key)) {
152
+ else if (hasOwn(BACKGROUND_STYLE_MAP, key)) {
107
153
  return 'backgroundStyle';
108
154
  }
109
155
  else {
@@ -357,6 +403,7 @@ export function useTransformStyle(styleObj = {}, { enableVar, transformRadiusPer
357
403
  let hasVarDec = false;
358
404
  let hasVarUse = false;
359
405
  let hasSelfPercent = false;
406
+ let hasBoxSizingAffectingStyle = false;
360
407
  const varKeyPaths = [];
361
408
  const unoVarKeyPaths = [];
362
409
  const percentKeyPaths = [];
@@ -394,18 +441,18 @@ export function useTransformStyle(styleObj = {}, { enableVar, transformRadiusPer
394
441
  }
395
442
  }
396
443
  }
444
+ function boxSizingVisitor({ key, keyPath }) {
445
+ if (keyPath.length === 1 && !hasBoxSizingAffectingStyle && isBoxSizingAffectingStyle(key)) {
446
+ hasBoxSizingAffectingStyle = true;
447
+ }
448
+ }
397
449
  function envVisitor({ value, keyPath }) {
398
450
  if (envUseRegExp.test(value)) {
399
451
  envKeyPaths.push(keyPath.slice());
400
452
  }
401
453
  }
402
- function calcVisitor({ key, value, keyPath }) {
454
+ function calcVisitor({ value, keyPath }) {
403
455
  if (calcUseRegExp.test(value)) {
404
- // calc translate & border-radius 的百分比计算
405
- if (hasOwn(selfPercentRule, key) && calcPercentExp.test(value)) {
406
- hasSelfPercent = true;
407
- percentKeyPaths.push(keyPath.slice());
408
- }
409
456
  calcKeyPaths.push(keyPath.slice());
410
457
  }
411
458
  }
@@ -421,12 +468,12 @@ export function useTransformStyle(styleObj = {}, { enableVar, transformRadiusPer
421
468
  }
422
469
  }
423
470
  function visitOther({ target, key, value, keyPath }) {
424
- if (filterRegExp.test(value)) {
471
+ if (typeof value === 'string' && (value.includes('%') || value.includes('calc(') || value.includes('env('))) {
425
472
  [envVisitor, percentVisitor, calcVisitor].forEach(visitor => visitor({ target, key, value, keyPath }));
426
473
  }
427
474
  }
428
475
  // traverse var & generate normalStyle
429
- traverseStyle(styleObj, [varVisitor]);
476
+ traverseStyle(styleObj, [varVisitor, boxSizingVisitor]);
430
477
  hasVarDec = hasVarDec || !!externalVarContext;
431
478
  enableVar = enableVar || hasVarDec || hasVarUse;
432
479
  const enableVarRef = useRef(enableVar);
@@ -467,6 +514,9 @@ export function useTransformStyle(styleObj = {}, { enableVar, transformRadiusPer
467
514
  // apply calc
468
515
  transformCalc(normalStyle, calcKeyPaths, (value, key) => {
469
516
  if (PERCENT_REGEX.test(value)) {
517
+ if (hasOwn(selfPercentRule, key)) {
518
+ hasSelfPercent = true;
519
+ }
470
520
  const resolved = resolvePercent(value, key, percentConfig);
471
521
  return typeof resolved === 'number' ? resolved : 0;
472
522
  }
@@ -489,6 +539,7 @@ export function useTransformStyle(styleObj = {}, { enableVar, transformRadiusPer
489
539
  transformBoxShadow(normalStyle);
490
540
  // transform 字符串格式转化数组格式(先转数组再处理css var)
491
541
  transformTransform(normalStyle);
542
+ transformBoxSizing(normalStyle, hasBoxSizingAffectingStyle);
492
543
  return {
493
544
  hasVarDec,
494
545
  varContextRef,
@@ -539,7 +590,7 @@ export function setStyle(styleObj, keyPath, setter) {
539
590
  }
540
591
  export function splitProps(props) {
541
592
  return groupBy(props, (key) => {
542
- if (TEXT_PROPS_REGEX.test(key)) {
593
+ if (hasOwn(TEXT_PROPS_MAP, key)) {
543
594
  return 'textProps';
544
595
  }
545
596
  else {
@@ -578,16 +629,34 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
578
629
  layoutProps
579
630
  };
580
631
  };
581
- export function wrapChildren(props = {}, { hasVarDec, varContext, textStyle, textProps }) {
632
+ export function useTextPassThroughValue(textStyle, textProps, { inheritTextProps = true, disabled = false } = {}) {
633
+ const parent = useContext(TextPassThroughContext);
634
+ const valueRef = useRef(null);
635
+ if (disabled)
636
+ return null;
637
+ if (!textStyle && !textProps && (inheritTextProps || !parent?.pendingTextProps))
638
+ return null;
639
+ const nextTextStyle = textStyle
640
+ ? extendObject({}, parent?.textStyle, textStyle)
641
+ : parent?.textStyle;
642
+ const nextTextProps = inheritTextProps
643
+ ? textProps
644
+ ? extendObject({}, parent?.pendingTextProps, textProps)
645
+ : parent?.pendingTextProps
646
+ : textProps;
647
+ const nextValue = {
648
+ textStyle: nextTextStyle,
649
+ pendingTextProps: nextTextProps
650
+ };
651
+ if (diffAndCloneA(valueRef.current, nextValue).diff) {
652
+ valueRef.current = nextValue;
653
+ }
654
+ return valueRef.current;
655
+ }
656
+ export function wrapChildren(props = {}, { hasVarDec, varContext, textPassThrough }) {
582
657
  let { children } = props;
583
- if (textStyle || textProps) {
584
- children = Children.map(children, (child) => {
585
- if (isText(child)) {
586
- const style = extendObject({}, textStyle, child.props.style);
587
- return cloneElement(child, extendObject({}, textProps, { style }));
588
- }
589
- return child;
590
- });
658
+ if (textPassThrough) {
659
+ children = <TextPassThroughContext.Provider value={textPassThrough} key='textPassThroughWrap'>{children}</TextPassThroughContext.Provider>;
591
660
  }
592
661
  if (hasVarDec && varContext) {
593
662
  children = <VarContext.Provider value={varContext} key='varContextWrap'>{children}</VarContext.Provider>;
@@ -325,6 +325,7 @@ const useInnerProps = (
325
325
  'parent-font-size',
326
326
  'parent-width',
327
327
  'parent-height',
328
+ 'enable-text-pass-through',
328
329
  ...userRemoveProps,
329
330
  ...rawEventKeys
330
331
  ]
@@ -19,7 +19,7 @@
19
19
  * ✘ app-parameter
20
20
  * ✘ show-message-card
21
21
  * ✘ phone-number-no-quota-toast
22
- * bindgetuserinfo
22
+ * bindgetuserinfo
23
23
  * ✘ bindcontact
24
24
  * ✘ createliveactivity
25
25
  * ✘ bindgetphonenumber
@@ -47,7 +47,7 @@ import {
47
47
  } from 'react-native'
48
48
  import { warn } from '@mpxjs/utils'
49
49
  import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
50
- import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover } from './utils'
50
+ import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useHover, useTextPassThroughValue } from './utils'
51
51
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
52
52
  import useNodesRef, { HandlerRef } from './useNodesRef'
53
53
  import { RouteContext, FormContext } from './context'
@@ -308,6 +308,7 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
308
308
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
309
309
 
310
310
  const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle)
311
+ const textPassThrough = useTextPassThroughValue(textStyle, textProps)
311
312
 
312
313
  if (backgroundStyle) {
313
314
  warn('Button does not support background image-related styles!')
@@ -395,7 +396,8 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
395
396
  'hover-start-time',
396
397
  'hover-stay-time',
397
398
  'open-type',
398
- 'form-type'
399
+ 'form-type',
400
+ 'bindgetuserinfo'
399
401
  ],
400
402
  {
401
403
  layoutRef,
@@ -409,8 +411,7 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
409
411
  {
410
412
  hasVarDec,
411
413
  varContext: varContextRef.current,
412
- textStyle,
413
- textProps
414
+ textPassThrough
414
415
  }
415
416
  )
416
417
  )
@@ -328,6 +328,7 @@ const _camera = forwardRef<HandlerRef<any, CameraProps>, CameraProps>((props: Ca
328
328
  'mode',
329
329
  'resolution',
330
330
  'frame-size',
331
+ 'device-position',
331
332
  'bindinitdone',
332
333
  'bindstop',
333
334
  'flash',
@@ -103,7 +103,10 @@ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasPr
103
103
  style: extendObject({}, normalStyle, layoutStyle, { opacity: isLoaded ? 1 : 0 })
104
104
  }
105
105
  ),
106
- [],
106
+ [
107
+ 'originWhitelist',
108
+ 'binderror'
109
+ ],
107
110
  {
108
111
  layoutRef
109
112
  }
@@ -128,7 +128,8 @@ const CheckboxGroup = forwardRef<
128
128
  }
129
129
  ),
130
130
  [
131
- 'name'
131
+ 'name',
132
+ 'bindchange'
132
133
  ],
133
134
  {
134
135
  layoutRef
@@ -26,7 +26,7 @@ import { warn } from '@mpxjs/utils'
26
26
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
27
27
  import useNodesRef, { HandlerRef } from './useNodesRef'
28
28
  import Icon from './mpx-icon'
29
- import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils'
29
+ import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useTextPassThroughValue } from './utils'
30
30
  import { CheckboxGroupContext, LabelContext } from './context'
31
31
  import Portal from './mpx-portal'
32
32
 
@@ -148,6 +148,7 @@ const Checkbox = forwardRef<HandlerRef<View, CheckboxProps>, CheckboxProps>(
148
148
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
149
149
 
150
150
  const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle)
151
+ const textPassThrough = useTextPassThroughValue(textStyle, textProps)
151
152
 
152
153
  if (backgroundStyle) {
153
154
  warn('Checkbox does not support background image-related styles!')
@@ -178,7 +179,9 @@ const Checkbox = forwardRef<HandlerRef<View, CheckboxProps>, CheckboxProps>(
178
179
  [
179
180
  'value',
180
181
  'disabled',
181
- 'checked'
182
+ 'checked',
183
+ 'color',
184
+ '_onChange'
182
185
  ],
183
186
  {
184
187
  layoutRef
@@ -224,8 +227,7 @@ const Checkbox = forwardRef<HandlerRef<View, CheckboxProps>, CheckboxProps>(
224
227
  {
225
228
  hasVarDec,
226
229
  varContext: varContextRef.current,
227
- textStyle,
228
- textProps
230
+ textPassThrough
229
231
  }
230
232
  )
231
233
  )
@@ -9,7 +9,7 @@ import { JSX, useRef, forwardRef, ReactNode, useMemo, createElement } from 'reac
9
9
  import useNodesRef, { HandlerRef } from './useNodesRef'
10
10
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
11
11
  import { FormContext } from './context'
12
- import { useTransformStyle, splitProps, splitStyle, useLayout, wrapChildren, extendObject } from './utils'
12
+ import { useTransformStyle, splitProps, splitStyle, useLayout, wrapChildren, extendObject, useTextPassThroughValue } from './utils'
13
13
  interface FormProps {
14
14
  style?: Record<string, any>
15
15
  children?: ReactNode
@@ -48,6 +48,7 @@ const _Form = forwardRef<HandlerRef<View, FormProps>, FormProps>((fromProps: For
48
48
  } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
49
49
 
50
50
  const { textStyle, innerStyle = {} } = splitStyle(normalStyle)
51
+ const textPassThrough = useTextPassThroughValue(textStyle, textProps)
51
52
 
52
53
  const formRef = useRef(null)
53
54
  useNodesRef(props, ref, formRef, {
@@ -117,8 +118,7 @@ const _Form = forwardRef<HandlerRef<View, FormProps>, FormProps>((fromProps: For
117
118
  {
118
119
  hasVarDec,
119
120
  varContext: varContextRef.current,
120
- textStyle,
121
- textProps
121
+ textPassThrough
122
122
  }
123
123
  )
124
124
  ))
@@ -99,7 +99,11 @@ const Icon = forwardRef<HandlerRef<Text, IconProps>, IconProps>(
99
99
  style: extendObject({}, normalStyle, layoutStyle, { tintColor: color })
100
100
  }
101
101
  ),
102
- [],
102
+ [
103
+ 'type',
104
+ 'size',
105
+ 'color'
106
+ ],
103
107
  {
104
108
  layoutRef
105
109
  }
@@ -20,10 +20,11 @@ import {
20
20
  ImageErrorEventData,
21
21
  LayoutChangeEvent,
22
22
  DimensionValue,
23
- ImageLoadEventData
23
+ ImageLoadEventData,
24
+ ImageSourcePropType
24
25
  } from 'react-native'
25
26
  import { noop } from '@mpxjs/utils'
26
- import { SvgCssUri } from 'react-native-svg/css'
27
+ import { LocalSvg, SvgCssUri } from 'react-native-svg/css'
27
28
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
28
29
  import useNodesRef, { HandlerRef } from './useNodesRef'
29
30
  import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject, isAndroid } from './utils'
@@ -46,7 +47,7 @@ export type Mode =
46
47
  | 'bottom right'
47
48
 
48
49
  export interface ImageProps {
49
- src?: string
50
+ src?: string | ImageSourcePropType
50
51
  mode?: Mode
51
52
  style?: ImageStyle & Record<string, any>
52
53
  'enable-offset'?: boolean
@@ -56,6 +57,7 @@ export interface ImageProps {
56
57
  'parent-width'?: number
57
58
  'parent-height'?: number
58
59
  'enable-fast-image'?: boolean
60
+ 'is-svg'?: boolean
59
61
  bindload?: (evt: NativeSyntheticEvent<ImageLoadEventData> | unknown) => void
60
62
  binderror?: (evt: NativeSyntheticEvent<ImageErrorEventData> | unknown) => void
61
63
  }
@@ -70,7 +72,6 @@ interface ImageState {
70
72
 
71
73
  const DEFAULT_IMAGE_WIDTH = 320
72
74
  const DEFAULT_IMAGE_HEIGHT = 240
73
-
74
75
  const cropMode: Mode[] = [
75
76
  'top',
76
77
  'bottom',
@@ -98,6 +99,32 @@ const relativeCenteredSize = (viewSize: number, imageSize: number) => {
98
99
  return (viewSize - imageSize) / 2
99
100
  }
100
101
 
102
+ function normalizeImageSource (src: string | ImageSourcePropType): ImageSourcePropType {
103
+ return typeof src === 'string' ? { uri: src } : src
104
+ }
105
+
106
+ function getImageUri (src: string | ImageSourcePropType) {
107
+ return typeof src === 'string' ? src : RNImage.resolveAssetSource(src)?.uri || ''
108
+ }
109
+
110
+ function isSvgSource (src: string | ImageSourcePropType) {
111
+ const uri = getImageUri(src)
112
+ return SVG_REGEXP.test(uri)
113
+ }
114
+
115
+ function getImageSize (src: string | ImageSourcePropType, success: (width: number, height: number) => void, fail: () => void = noop) {
116
+ if (typeof src === 'string') {
117
+ RNImage.getSize(src, success, fail)
118
+ return
119
+ }
120
+ const source = RNImage.resolveAssetSource(src)
121
+ if (source && source.width && source.height) {
122
+ success(source.width, source.height)
123
+ } else {
124
+ fail()
125
+ }
126
+ }
127
+
101
128
  // 获取能完全显示图片的缩放比例:长宽方向的缩放比例最小值即为能完全展示的比例
102
129
  function getFitScale (width1: number, height1: number, width2: number, height2: number) {
103
130
  return Math.min(width2 / width1, height2 / height1)
@@ -136,6 +163,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
136
163
  'enable-fast-image': enableFastImage,
137
164
  'parent-width': parentWidth,
138
165
  'parent-height': parentHeight,
166
+ 'is-svg': isSvgProp,
139
167
  bindload,
140
168
  binderror
141
169
  } = props
@@ -157,7 +185,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
157
185
  defaultStyle
158
186
  })
159
187
 
160
- const isSvg = SVG_REGEXP.test(src)
188
+ const isSvg = isSvgProp || isSvgSource(src)
161
189
  const isWidthFixMode = mode === 'widthFix'
162
190
  const isHeightFixMode = mode === 'heightFix'
163
191
  const isCropMode = cropMode.includes(mode)
@@ -379,7 +407,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
379
407
 
380
408
  const onImageLoad = (evt: NativeSyntheticEvent<ImageLoadEventData>) => {
381
409
  evt.persist()
382
- RNImage.getSize(src, (width: number, height: number) => {
410
+ const triggerLoad = (width: number, height: number) => {
383
411
  bindload!(
384
412
  getCustomEvent(
385
413
  'load',
@@ -391,7 +419,13 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
391
419
  props
392
420
  )
393
421
  )
394
- })
422
+ }
423
+ const { source } = evt.nativeEvent
424
+ if (source && source.width && source.height) {
425
+ triggerLoad(source.width, source.height)
426
+ return
427
+ }
428
+ getImageSize(src, triggerLoad)
395
429
  }
396
430
 
397
431
  const onImageError = (evt: NativeSyntheticEvent<ImageErrorEventData>) => {
@@ -410,7 +444,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
410
444
 
411
445
  useEffect(() => {
412
446
  if (!isSvg && isLayoutMode) {
413
- RNImage.getSize(
447
+ getImageSize(
414
448
  src,
415
449
  (width: number, height: number) => {
416
450
  state.current.imageWidth = width
@@ -455,7 +489,11 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
455
489
  ),
456
490
  [
457
491
  'src',
458
- 'mode'
492
+ 'mode',
493
+ 'is-svg',
494
+ 'enable-fast-image',
495
+ 'bindload',
496
+ 'binderror'
459
497
  ],
460
498
  {
461
499
  layoutRef
@@ -463,18 +501,19 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
463
501
  )
464
502
 
465
503
  function renderSvgImage () {
504
+ const svgProps = {
505
+ onLayout: onSvgLoad,
506
+ style: extendObject(
507
+ { transformOrigin: 'left top' },
508
+ modeStyle
509
+ )
510
+ }
466
511
  return createElement(
467
512
  View,
468
513
  innerProps,
469
- createElement(SvgCssUri, {
470
- uri: src,
471
- onLayout: onSvgLoad,
472
- onError: binderror && onSvgError,
473
- style: extendObject(
474
- { transformOrigin: 'left top' },
475
- modeStyle
476
- )
477
- })
514
+ typeof src === 'string'
515
+ ? createElement(SvgCssUri, extendObject({ uri: src, onError: binderror && onSvgError }, svgProps))
516
+ : createElement(LocalSvg, extendObject({ asset: src }, svgProps))
478
517
  )
479
518
  }
480
519
 
@@ -482,7 +521,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
482
521
  return renderImage(
483
522
  extendObject(
484
523
  {
485
- source: { uri: src },
524
+ source: normalizeImageSource(src),
486
525
  resizeMode: resizeMode,
487
526
  onLoad: bindload && onImageLoad,
488
527
  onError: binderror && onImageError,
@@ -1,16 +1,21 @@
1
1
  import { Text, TextProps } from 'react-native'
2
- import { JSX, createElement } from 'react'
2
+ import { JSX, createElement, useContext } from 'react'
3
3
 
4
- import { extendObject } from './utils'
4
+ import { extendObject, getDefaultAllowFontScaling } from './utils'
5
+ import { TextPassThroughContext } from './context'
5
6
 
6
7
  const InlineText = (props: TextProps): JSX.Element => {
8
+ const inheritedText = useContext(TextPassThroughContext)
9
+ const style = extendObject({}, inheritedText?.textStyle, props.style)
10
+ const mergedProps = extendObject({}, inheritedText?.pendingTextProps, props, { style })
7
11
  const {
8
- allowFontScaling = false
9
- } = props
12
+ allowFontScaling,
13
+ children
14
+ } = mergedProps
10
15
 
11
- return createElement(Text, extendObject({}, props, {
12
- allowFontScaling
13
- }))
16
+ return createElement(Text, extendObject({}, mergedProps, {
17
+ allowFontScaling: allowFontScaling ?? getDefaultAllowFontScaling()
18
+ }), children)
14
19
  }
15
20
 
16
21
  InlineText.displayName = 'MpxInlineText'
@@ -54,7 +54,7 @@ import {
54
54
  NativeTouchEvent
55
55
  } from 'react-native'
56
56
  import { warn } from '@mpxjs/utils'
57
- import { useUpdateEffect, useTransformStyle, useLayout, extendObject, isAndroid } from './utils'
57
+ import { useUpdateEffect, useTransformStyle, useLayout, extendObject, isAndroid, getDefaultAllowFontScaling } from './utils'
58
58
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
59
59
  import useNodesRef, { HandlerRef } from './useNodesRef'
60
60
  import { FormContext, FormFieldValue, KeyboardAvoidContext } from './context'
@@ -131,7 +131,7 @@ const inputModeMap: Record<Type, string> = {
131
131
  const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps>((props: FinalInputProps, ref): JSX.Element => {
132
132
  const {
133
133
  style = {},
134
- allowFontScaling = false,
134
+ allowFontScaling,
135
135
  type = 'text',
136
136
  value,
137
137
  password,
@@ -483,7 +483,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
483
483
  {
484
484
  ref: nodeRef,
485
485
  style: extendObject({}, normalStyle, layoutStyle),
486
- allowFontScaling,
486
+ allowFontScaling: allowFontScaling ?? getDefaultAllowFontScaling(),
487
487
  inputMode: originalKeyboardType ? undefined : inputModeMap[type],
488
488
  keyboardType: originalKeyboardType,
489
489
  secureTextEntry: !!password,
@@ -512,7 +512,14 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
512
512
  !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }
513
513
  ),
514
514
  [
515
+ 'name',
515
516
  'type',
517
+ 'maxlength',
518
+ 'cursor-spacing',
519
+ 'adjust-position',
520
+ 'hold-keyboard',
521
+ 'keyboard-type',
522
+ 'auto-height',
516
523
  'password',
517
524
  'placeholder-style',
518
525
  'disabled',
@@ -523,7 +530,13 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
523
530
  'cursor',
524
531
  'cursor-color',
525
532
  'selection-start',
526
- 'selection-end'
533
+ 'selection-end',
534
+ 'bindinput',
535
+ 'bindfocus',
536
+ 'bindblur',
537
+ 'bindconfirm',
538
+ 'bindselectionchange',
539
+ 'bindlinechange'
527
540
  ],
528
541
  {
529
542
  layoutRef