@mpxjs/webpack-plugin 2.9.59 → 2.9.64

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 (115) hide show
  1. package/lib/index.js +1 -3
  2. package/lib/platform/style/wx/index.js +344 -270
  3. package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
  4. package/lib/platform/template/wx/component-config/checkbox.js +8 -0
  5. package/lib/platform/template/wx/component-config/cover-image.js +15 -0
  6. package/lib/platform/template/wx/component-config/cover-view.js +9 -0
  7. package/lib/platform/template/wx/component-config/form.js +13 -1
  8. package/lib/platform/template/wx/component-config/icon.js +8 -0
  9. package/lib/platform/template/wx/component-config/index.js +5 -1
  10. package/lib/platform/template/wx/component-config/label.js +15 -0
  11. package/lib/platform/template/wx/component-config/movable-area.js +18 -1
  12. package/lib/platform/template/wx/component-config/movable-view.js +18 -1
  13. package/lib/platform/template/wx/component-config/navigator.js +8 -0
  14. package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
  15. package/lib/platform/template/wx/component-config/picker-view.js +18 -2
  16. package/lib/platform/template/wx/component-config/picker.js +14 -1
  17. package/lib/platform/template/wx/component-config/radio-group.js +8 -0
  18. package/lib/platform/template/wx/component-config/radio.js +8 -0
  19. package/lib/platform/template/wx/component-config/root-portal.js +15 -0
  20. package/lib/platform/template/wx/component-config/switch.js +8 -0
  21. package/lib/platform/template/wx/component-config/unsupported.js +1 -3
  22. package/lib/react/processScript.js +2 -0
  23. package/lib/react/processStyles.js +1 -0
  24. package/lib/react/processTemplate.js +2 -3
  25. package/lib/react/style-helper.js +12 -7
  26. package/lib/runtime/components/react/context.ts +40 -0
  27. package/lib/runtime/components/react/dist/context.js +8 -0
  28. package/lib/runtime/components/react/dist/getInnerListeners.js +34 -12
  29. package/lib/runtime/components/react/dist/mpx-button.jsx +88 -88
  30. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +82 -0
  31. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +139 -0
  32. package/lib/runtime/components/react/dist/mpx-form.jsx +61 -0
  33. package/lib/runtime/components/react/dist/mpx-icon.jsx +48 -0
  34. package/lib/runtime/components/react/dist/mpx-image/index.jsx +39 -43
  35. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +3 -2
  36. package/lib/runtime/components/react/dist/mpx-input.jsx +63 -37
  37. package/lib/runtime/components/react/dist/mpx-label.jsx +55 -0
  38. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +41 -0
  39. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
  40. package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +142 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +94 -0
  45. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  46. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
  47. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
  48. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  49. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +107 -0
  50. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +162 -0
  51. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +80 -0
  52. package/lib/runtime/components/react/dist/mpx-radio.jsx +154 -0
  53. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +15 -0
  54. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +93 -70
  55. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +281 -157
  56. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +21 -11
  57. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +19 -11
  58. package/lib/runtime/components/react/dist/mpx-switch.jsx +79 -0
  59. package/lib/runtime/components/react/dist/mpx-text.jsx +21 -49
  60. package/lib/runtime/components/react/dist/mpx-textarea.jsx +2 -2
  61. package/lib/runtime/components/react/dist/mpx-view.jsx +451 -146
  62. package/lib/runtime/components/react/dist/mpx-web-view.jsx +17 -20
  63. package/lib/runtime/components/react/dist/parser.js +218 -0
  64. package/lib/runtime/components/react/dist/types/common.js +1 -0
  65. package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
  66. package/lib/runtime/components/react/dist/utils.jsx +433 -0
  67. package/lib/runtime/components/react/getInnerListeners.ts +43 -21
  68. package/lib/runtime/components/react/mpx-button.tsx +129 -119
  69. package/lib/runtime/components/react/mpx-checkbox-group.tsx +152 -0
  70. package/lib/runtime/components/react/mpx-checkbox.tsx +234 -0
  71. package/lib/runtime/components/react/mpx-form.tsx +117 -0
  72. package/lib/runtime/components/react/mpx-icon.tsx +106 -0
  73. package/lib/runtime/components/react/mpx-image/index.tsx +62 -68
  74. package/lib/runtime/components/react/mpx-image/svg.tsx +7 -5
  75. package/lib/runtime/components/react/mpx-input.tsx +90 -42
  76. package/lib/runtime/components/react/mpx-label.tsx +110 -0
  77. package/lib/runtime/components/react/mpx-movable-area.tsx +81 -0
  78. package/lib/runtime/components/react/mpx-movable-view.tsx +424 -0
  79. package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
  80. package/lib/runtime/components/react/mpx-picker/date.tsx +82 -0
  81. package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
  82. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +156 -0
  83. package/lib/runtime/components/react/mpx-picker/region.tsx +107 -0
  84. package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
  85. package/lib/runtime/components/react/mpx-picker/selector.tsx +91 -0
  86. package/lib/runtime/components/react/mpx-picker/time.tsx +270 -0
  87. package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
  88. package/lib/runtime/components/react/mpx-picker-view-column.tsx +156 -0
  89. package/lib/runtime/components/react/mpx-picker-view.tsx +220 -0
  90. package/lib/runtime/components/react/mpx-radio-group.tsx +150 -0
  91. package/lib/runtime/components/react/mpx-radio.tsx +230 -0
  92. package/lib/runtime/components/react/mpx-root-portal.tsx +27 -0
  93. package/lib/runtime/components/react/mpx-scroll-view.tsx +184 -130
  94. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +308 -183
  95. package/lib/runtime/components/react/mpx-swiper/index.tsx +27 -19
  96. package/lib/runtime/components/react/mpx-swiper/type.ts +23 -5
  97. package/lib/runtime/components/react/mpx-swiper-item.tsx +49 -14
  98. package/lib/runtime/components/react/mpx-switch.tsx +148 -0
  99. package/lib/runtime/components/react/mpx-text.tsx +53 -77
  100. package/lib/runtime/components/react/mpx-textarea.tsx +3 -3
  101. package/lib/runtime/components/react/mpx-view.tsx +576 -195
  102. package/lib/runtime/components/react/mpx-web-view.tsx +34 -39
  103. package/lib/runtime/components/react/parser.ts +245 -0
  104. package/lib/runtime/components/react/types/common.ts +12 -0
  105. package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
  106. package/lib/runtime/components/react/types/global.d.ts +17 -1
  107. package/lib/runtime/components/react/useNodesRef.ts +4 -10
  108. package/lib/runtime/components/react/utils.tsx +505 -0
  109. package/lib/runtime/optionProcessor.js +19 -17
  110. package/lib/template-compiler/compiler.js +84 -61
  111. package/lib/template-compiler/gen-node-react.js +7 -9
  112. package/lib/web/processStyles.js +2 -5
  113. package/package.json +8 -3
  114. package/lib/runtime/components/react/dist/utils.js +0 -80
  115. package/lib/runtime/components/react/utils.ts +0 -92
@@ -4,153 +4,307 @@
4
4
  * ✔ hover-start-time
5
5
  * ✔ hover-stay-time
6
6
  */
7
- import { View, Text, StyleProp, TextStyle, ViewStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent } from 'react-native'
8
- import { useRef, useState, useEffect, forwardRef, ReactNode, JSX } from 'react'
9
- // @ts-ignore
7
+ import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent, Text } from 'react-native'
8
+ import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, Children, cloneElement } from 'react'
10
9
  import useInnerProps from './getInnerListeners'
11
- // @ts-ignore
12
- import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
13
-
14
- import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGEX, isText} from './utils'
15
-
16
-
17
- type ExtendedViewStyle = ViewStyle & {
18
- backgroundImage?: string
19
- backgroundSize?: ImageResizeMode
20
- }
10
+ import { ExtendedViewStyle } from './types/common'
11
+ import useNodesRef, { HandlerRef } from './useNodesRef'
12
+ import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils'
13
+ import LinearGradient from 'react-native-linear-gradient'
21
14
 
22
15
  export interface _ViewProps extends ViewProps {
23
- style?: Array<ExtendedViewStyle>
24
- children?: ReactNode | ReactNode []
25
- hoverStyle: Array<ExtendedViewStyle>
26
- ['hover-start-time']: number
27
- ['hover-stay-time']: number
28
- 'enable-offset'?: boolean
16
+ style?: ExtendedViewStyle
17
+ children?: ReactNode | ReactNode[]
18
+ 'hover-style'?: ExtendedViewStyle
19
+ 'hover-start-time'?: number
20
+ 'hover-stay-time'?: number
21
+ 'enable-background'?: boolean
22
+ 'enable-var'?: boolean
23
+ 'external-var-context'?: Record<string, any>
24
+ 'parent-font-size'?: number
25
+ 'parent-width'?: number
26
+ 'parent-height'?: number
29
27
  bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
30
28
  bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
31
29
  bindtouchend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
32
30
  }
33
31
 
34
- type Obj = Record<string, any>
35
-
36
- type GroupData = Record<string, Record<string, any>>;
37
-
38
- type Handler = (...args: any []) => void
32
+ type Handler = (...args: any[]) => void
39
33
 
40
34
  type Size = {
41
- width: number,
35
+ width: number
42
36
  height: number
43
37
  }
44
38
 
45
- type DimensionValue = number | 'auto' | `${number}%`
39
+ type DimensionValue = number | `${number}%` | 'auto' | 'contain' | 'cover'
40
+
41
+ type Position = {
42
+ left?: number
43
+ right?: number
44
+ top?: number
45
+ bottom?: number
46
+ }
47
+
48
+ type PositionKey = keyof Position
49
+
50
+ type NumberVal = number | `${number}%`
51
+
52
+ type PositionVal = PositionKey | NumberVal
53
+
54
+ type backgroundPositionList = ['left' | 'right', NumberVal, 'top' | 'bottom', NumberVal] | []
55
+
56
+ type LinearInfo = {
57
+ colors: Array<string>,
58
+ locations: Array<number>,
59
+ direction?: string
60
+ }
46
61
 
47
62
  type PreImageInfo = {
48
63
  src?: string,
49
- sizeList: DimensionValue []
64
+ sizeList: DimensionValue[]
65
+ type?: 'image' | 'linear'
66
+ linearInfo?: LinearInfo
67
+ // containPercentSymbol?: boolean
68
+ backgroundPosition: backgroundPositionList
50
69
  }
51
70
 
52
71
  type ImageProps = {
53
72
  style: ImageStyle,
54
- src?: string
73
+ src?: string,
74
+ colors: Array<string>,
75
+ locations?: Array<number>
76
+ angle?: number
55
77
  }
56
78
 
57
- const IMAGE_STYLE_REGEX = /^background(Image|Size|Repeat|Position)$/
79
+ const linearMap = new Map([
80
+ ['top', 0],
81
+ ['bottom', 180],
82
+ ['left', 270],
83
+ ['right', 90]
84
+ ])
85
+
86
+ // 对角线角度
87
+ const diagonalAngleMap: Record<string, (width: number, height: number) => any> = {
88
+ 'top right': (width: number, height: number) => {
89
+ return Math.acos(
90
+ (width / 2) /
91
+ (Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / 2)
92
+ )
93
+ },
94
+ 'right top': (width, height) => { return diagonalAngleMap['top right'](width, height) },
95
+
96
+ 'bottom right': (width, height) => Math.PI - diagonalAngleMap['top right'](width, height),
97
+ 'right bottom': (width, height) => { return diagonalAngleMap['bottom right'](width, height) },
98
+
99
+ 'bottom left': (width, height) => Math.PI + diagonalAngleMap['top right'](width, height),
100
+ 'left bottom': (width, height) => { return diagonalAngleMap['bottom left'](width, height) },
101
+
102
+ 'top left': (width, height) => (2 * Math.PI) - diagonalAngleMap['top right'](width, height),
103
+ 'left top': (width, height) => { return diagonalAngleMap['top left'](width, height) }
104
+ }
58
105
 
59
- function groupBy(style: Obj, callback: (key: string, val: string) => string, group:GroupData = {}):GroupData {
60
- let groupKey = ''
61
- for (let key in style) {
62
- if (style.hasOwnProperty(key)) { // 确保处理对象自身的属性
63
- let val: string = style[key] as string
64
- groupKey = callback(key, val)
65
- if (!group[groupKey]) {
66
- group[groupKey] = {}
67
- }
68
- group[groupKey][key] = val
69
- }
70
- }
71
- return group
106
+ // 弧度转化为角度的公式
107
+ function radToAngle (r: number) {
108
+ return r * 180 / Math.PI
72
109
  }
73
110
 
74
- const applyHandlers = (handlers: Handler[] , args: any [] ) => {
75
- for (let handler of handlers) {
111
+ const applyHandlers = (handlers: Handler[], args: any[]) => {
112
+ for (const handler of handlers) {
76
113
  handler(...args)
77
114
  }
78
115
  }
79
116
 
80
- const checkNeedLayout = (style: PreImageInfo) => {
81
- const [width, height] = style.sizeList
82
- return (PERCENT_REGEX.test(`${height}`) && width === 'auto') || (PERCENT_REGEX.test(`${width}`) && height === 'auto')
117
+ const isPercent = (val: string | number | undefined): val is string => typeof val === 'string' && PERCENT_REGEX.test(val)
118
+
119
+ const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val)
120
+
121
+ const isNeedLayout = (preImageInfo: PreImageInfo): boolean => {
122
+ const { sizeList, backgroundPosition, linearInfo } = preImageInfo
123
+ const [width, height] = sizeList
124
+ const bp = backgroundPosition
125
+
126
+ // 含有百分号,center 需计算布局
127
+ return isBackgroundSizeKeyword(width) ||
128
+ (isPercent(height) && width === 'auto') ||
129
+ (isPercent(width) && height === 'auto') ||
130
+ isPercent(bp[1]) ||
131
+ isPercent(bp[3]) ||
132
+ isDiagonalAngle(linearInfo)
133
+ }
134
+
135
+ const checkNeedLayout = (preImageInfo: PreImageInfo) => {
136
+ const { sizeList } = preImageInfo
137
+ const [width] = sizeList
138
+ // 在渐变的时候,background-size的cover,contain, auto属性值,转化为100%, needLayout计算逻辑和原来保持一致,needImageSize始终为false
139
+ return {
140
+ // 是否开启layout的计算
141
+ needLayout: isNeedLayout(preImageInfo),
142
+ // 是否开启原始宽度的计算
143
+ needImageSize: isBackgroundSizeKeyword(width) || sizeList.includes('auto')
144
+ }
83
145
  }
84
146
 
85
147
  /**
86
- * h - 用户设置的高度
87
- * lh - 容器的高度
88
- * ratio - 原始图片的宽高比
89
- * **/
90
- function calculateSize(h: number, lh: number, ratio: number) {
91
- let height, width
92
- if (PERCENT_REGEX.test(`${h}`)) { // auto px/rpx
148
+ * h - 用户设置的高度
149
+ * lh - 容器的高度
150
+ * ratio - 原始图片的宽高比
151
+ * **/
152
+ function calculateSize (h: number, ratio: number, lh?: number | boolean, reverse = false): Size | null {
153
+ let height = 0; let width = 0
154
+
155
+ if (typeof lh === 'boolean') {
156
+ reverse = lh
157
+ }
158
+
159
+ if (isPercent(h)) { // auto px/rpx
93
160
  if (!lh) return null
94
- height = (parseFloat(`${h}`) / 100) * lh
161
+ height = (parseFloat(h) / 100) * (lh as number)
95
162
  width = height * ratio
96
163
  } else { // 2. auto px/rpx - 根据比例计算
97
164
  height = h
98
165
  width = height * ratio
99
166
  }
100
-
101
167
  return {
102
- width,
103
- height
168
+ width: reverse ? height : width,
169
+ height: reverse ? width : height
170
+ }
171
+ }
172
+
173
+ /**
174
+ * 用户设置百分比后,转换为偏移量
175
+ * h - 用户设置图片的高度
176
+ * ch - 容器的高度
177
+ * val - 用户设置的百分比
178
+ * **/
179
+ function calculateSizePosition (h: number, ch: number, val: string): number {
180
+ if (!h || !ch) return 0
181
+
182
+ // 百分比需要单独的计算
183
+ if (isPercent(h)) {
184
+ h = ch * parseFloat(h) / 100
185
+ }
186
+
187
+ // (container width - image width) * (position x%) = (x offset value)
188
+ return (ch - h) * parseFloat(val) / 100
189
+ }
190
+
191
+ /**
192
+ * 获取图片的展示宽高
193
+ * h - 用户设置的高度
194
+ * lh - 容器的高度
195
+ * **/
196
+ const calcPercent = (h: NumberVal, lh: number) => {
197
+ return isPercent(h) ? parseFloat(h) / 100 * lh : +h
198
+ }
199
+
200
+ function backgroundPosition (imageProps: ImageProps, preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) {
201
+ const bps = preImageInfo.backgroundPosition
202
+ if (bps.length === 0) return
203
+ const style: Position = {}
204
+ const imageStyle: ImageStyle = imageProps.style || {}
205
+
206
+ for (let i = 0; i < bps.length; i += 2) {
207
+ const key = bps[i] as PositionKey; const val = bps[i + 1]
208
+ // 需要获取 图片宽度 和 容器的宽度 进行计算
209
+ if (isPercent(val)) {
210
+ if (i === 0) {
211
+ style[key] = calculateSizePosition(imageStyle.width as number, layoutInfo?.width, val)
212
+ } else {
213
+ style[key] = calculateSizePosition(imageStyle.height as number, layoutInfo?.height, val)
214
+ }
215
+ } else {
216
+ style[key] = val as number
217
+ }
218
+ }
219
+
220
+ imageProps.style = {
221
+ ...imageProps.style as ImageStyle,
222
+ ...style
104
223
  }
105
224
  }
106
225
 
107
226
  // background-size 转换
108
227
  function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) {
109
- let sizeList = preImageInfo.sizeList
228
+ const sizeList = preImageInfo.sizeList
110
229
  if (!sizeList) return
230
+ const { width: layoutWidth, height: layoutHeight } = layoutInfo || {}
231
+ const { width: imageSizeWidth, height: imageSizeHeight } = imageSize || {}
232
+ const [width, height] = sizeList
233
+ let dimensions: {
234
+ width: NumberVal,
235
+ height: NumberVal
236
+ } | null = { width: 0, height: 0 }
237
+
111
238
  // 枚举值
112
- if (['cover', 'contain'].includes(`${sizeList[0]}`)) {
113
- imageProps.style.resizeMode = sizeList[0] as ImageResizeMode
239
+ if (typeof width === 'string' && ['cover', 'contain'].includes(width)) {
240
+ if (layoutInfo && imageSize) {
241
+ const layoutRatio = layoutWidth / imageSizeWidth
242
+ const eleRatio = imageSizeWidth / imageSizeHeight
243
+ // 容器宽高比 大于 图片的宽高比,依据宽度作为基准,否则以高度为基准
244
+ if ((layoutRatio <= eleRatio && (width as string) === 'contain') || (layoutRatio >= eleRatio && (width as string) === 'cover')) {
245
+ dimensions = calculateSize(layoutWidth as number, imageSizeHeight / imageSizeWidth, true) as Size
246
+ } else if ((layoutRatio > eleRatio && (width as string) === 'contain') || (layoutRatio < eleRatio && (width as string) === 'cover')) {
247
+ dimensions = calculateSize(layoutHeight as number, imageSizeWidth / imageSizeHeight) as Size
248
+ }
249
+ }
114
250
  } else {
115
- const [width, height] = sizeList
116
- let newWidth: ImageStyle['width'] = 0, newHeight: ImageStyle['height'] = 0
117
-
118
- const { width: imageSizeWidth, height: imageSizeHeight } = imageSize || {}
119
-
120
251
  if (width === 'auto' && height === 'auto') { // 均为auto
121
252
  if (!imageSize) return
122
- newHeight = imageSizeHeight
123
- newWidth = imageSizeWidth
253
+ dimensions = {
254
+ width: imageSizeWidth,
255
+ height: imageSizeHeight
256
+ }
124
257
  } else if (width === 'auto') { // auto px/rpx/%
125
258
  if (!imageSize) return
126
- const dimensions = calculateSize(height as number, layoutInfo?.height, imageSizeWidth / imageSizeHeight)
259
+ dimensions = calculateSize(height as number, imageSizeWidth / imageSizeHeight, layoutInfo?.height)
127
260
  if (!dimensions) return
128
- newWidth = dimensions.width
129
- newHeight = dimensions.height
130
- }else if (height === 'auto') { // auto px/rpx/%
261
+ } else if (height === 'auto') { // auto px/rpx/%
131
262
  if (!imageSize) return
132
- const dimensions = calculateSize(width as number, layoutInfo?.width, imageSizeHeight / imageSizeWidth)
263
+ dimensions = calculateSize(width as number, imageSizeHeight / imageSizeWidth, layoutInfo?.width, true)
133
264
  if (!dimensions) return
134
- newHeight = dimensions.width
135
- newWidth = dimensions.height
136
265
  } else { // 数值类型 ImageStyle
137
266
  // 数值类型设置为 stretch
138
267
  (imageProps.style as ImageStyle).resizeMode = 'stretch'
139
- newWidth = PERCENT_REGEX.test(`${width}`) ? width : +width! as DimensionValue
140
- newHeight = PERCENT_REGEX.test(`${width}`) ? height : +height! as DimensionValue
141
- }
142
- // 样式合并
143
- imageProps.style = {
144
- ...imageProps.style as ImageStyle,
145
- width: newWidth,
146
- height: newHeight
268
+ dimensions = {
269
+ width: isPercent(width) ? width : +width,
270
+ height: isPercent(height) ? height : +height
271
+ } as { width: NumberVal, height: NumberVal }
147
272
  }
148
273
  }
274
+ // 样式合并
275
+ imageProps.style = {
276
+ ...imageProps.style as ImageStyle,
277
+ ...dimensions
278
+ }
149
279
  }
150
280
 
151
281
  // background-image转换为source
152
- function backgroundImage(imageProps: ImageProps, preImageInfo: PreImageInfo) {
153
- imageProps.src = preImageInfo.src
282
+ function backgroundImage (imageProps: ImageProps, preImageInfo: PreImageInfo) {
283
+ if (preImageInfo.src) {
284
+ imageProps.src = preImageInfo.src
285
+ }
286
+ }
287
+
288
+ // 渐变的转换
289
+ function linearGradient (imageProps: ImageProps, preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) {
290
+ const { type, linearInfo } = preImageInfo
291
+ const { colors = [], locations, direction = '' } = linearInfo || {}
292
+ const { width, height } = imageSize || {}
293
+
294
+ if (type !== 'linear') return
295
+
296
+ // 角度计算
297
+ let angle = +(linearMap.get(direction) || direction.match(/(-?\d+(\.\d+)?)deg/)?.[1] || 180) % 360
298
+
299
+ // 对角线角度计算
300
+ if (layoutInfo && diagonalAngleMap[direction] && imageSize && linearInfo) {
301
+ angle = radToAngle(diagonalAngleMap[direction](width, height)) || 180
302
+ }
303
+
304
+ // 赋值
305
+ imageProps.colors = colors
306
+ imageProps.locations = locations
307
+ imageProps.angle = angle
154
308
  }
155
309
 
156
310
  const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) => {
@@ -158,79 +312,265 @@ const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutIn
158
312
  const imageProps: ImageProps = {
159
313
  style: {
160
314
  resizeMode: 'cover' as ImageResizeMode,
161
- ...StyleSheet.absoluteFillObject
162
- }
315
+ position: 'absolute'
316
+ // ...StyleSheet.absoluteFillObject
317
+ },
318
+ colors: []
163
319
  }
320
+ applyHandlers([backgroundSize, backgroundImage, backgroundPosition, linearGradient], [imageProps, preImageInfo, imageSize, layoutInfo])
164
321
 
165
- applyHandlers([ backgroundSize, backgroundImage ],[imageProps, preImageInfo, imageSize, layoutInfo])
166
- if (!imageProps?.src) return null
167
322
  return imageProps
168
323
  }
169
324
 
325
+ function isHorizontal (val: PositionVal): val is 'left' | 'right' {
326
+ return typeof val === 'string' && /^(left|right)$/.test(val)
327
+ }
328
+
329
+ function isVertical (val: PositionVal): val is 'top' | 'bottom' {
330
+ return typeof val === 'string' && /^(top|bottom)$/.test(val)
331
+ }
332
+
333
+ function normalizeBackgroundPosition (parts: PositionVal[]): backgroundPositionList {
334
+ if (parts.length === 0) return []
335
+
336
+ // 定义默认值
337
+ let hStart: 'left' | 'right' = 'left'
338
+ let hOffset: PositionVal = 0
339
+ let vStart: 'top' | 'bottom' = 'top'
340
+ let vOffset: PositionVal = 0
341
+
342
+ if (parts.length === 4) return parts as backgroundPositionList
343
+
344
+ // 归一化
345
+ if (parts.length === 1) {
346
+ // 1. center
347
+ // 2. 2px - hOffset, vOffset(center) - center为50%
348
+ // 3. 10% - hOffset, vOffset(center) - center为50%
349
+ // 4. left - hStart, vOffset(center) - center为50%
350
+ // 5. top - hOffset(center), vStart - center为50%
351
+
352
+ if (isHorizontal(parts[0])) {
353
+ hStart = parts[0]
354
+ vOffset = '50%'
355
+ } else if (isVertical(parts[0])) {
356
+ vStart = parts[0]
357
+ hOffset = '50%'
358
+ } else {
359
+ hOffset = parts[0]
360
+ vOffset = '50%'
361
+ }
362
+ } else if (parts.length === 2) {
363
+ // 1. center center - hOffset, vOffset
364
+ // 2. 10px center - hOffset, vStart
365
+ // 3. left center - hStart, vOffset
366
+ // 4. right center - hStart, vOffset
367
+ // 5. 第一位是 left right 覆盖的是 hStart
368
+ // center, 100% 正常的px 覆盖的是 hOffset
369
+ // 第二位是 top bottom 覆盖的是 vStart
370
+ // center, 100% 覆盖的是 vOffset
371
+ //
372
+ // 水平方向
373
+ if (isHorizontal(parts[0])) {
374
+ hStart = parts[0]
375
+ } else { // center, 100% 正常的px 覆盖的是 hOffset
376
+ hOffset = parts[0]
377
+ }
378
+ // 垂直方向
379
+ if (isVertical(parts[1])) {
380
+ vStart = parts[1]
381
+ } else { // center, 100% 正常的px 覆盖的是 hOffset
382
+ vOffset = parts[1]
383
+ }
384
+ } else if (parts.length === 3) {
385
+ // 1. center top 10px / top 10px center 等价 - center为50%
386
+ // 2. right 10px center / center right 10px 等价 - center为50%
387
+ // 2. bottom 50px right
388
+ if (typeof parts[0] === 'string' && typeof parts[1] === 'string' && /^left|bottom|right|top$/.test(parts[0]) && /^left|bottom|right|top$/.test(parts[1])) {
389
+ [hStart, vStart, vOffset] = parts as ['left' | 'right', 'top' | 'bottom', number]
390
+ } else {
391
+ [hStart, hOffset, vStart] = parts as ['left' | 'right', number, 'top' | 'bottom']
392
+ }
393
+ }
394
+
395
+ return [hStart, hOffset, vStart, vOffset] as backgroundPositionList
396
+ }
397
+
398
+ /**
399
+ *
400
+ * calcSteps - 计算起始位置和终点位置之间的差值
401
+ * startVal - 起始位置距离
402
+ * endVal - 终点位置距离
403
+ * len - 数量
404
+ * **/
405
+ function calcSteps (startVal: number, endVal: number, len: number) {
406
+ const diffVal = endVal - startVal
407
+ const step = diffVal / len
408
+ const newArr: Array<number> = []
409
+ for (let i = 1; i < len; i++) {
410
+ const val = startVal + step * i
411
+ newArr.push(+val.toFixed(2))
412
+ }
413
+
414
+ return newArr
415
+ }
416
+
417
+ function parseLinearGradient (text: string): LinearInfo | undefined {
418
+ let linearText = text.trim().match(/linear-gradient\((.*)\)/)?.[1]
419
+ if (!linearText) return
170
420
 
171
- function preParseImage(imageStyle?: ExtendedViewStyle) {
421
+ // 添加默认的角度
422
+ if (!/^to|^-?\d+deg/.test(linearText)) {
423
+ linearText = '180deg ,' + linearText
424
+ } else {
425
+ linearText = linearText.replace('to', '')
426
+ }
172
427
 
173
- const { backgroundImage, backgroundSize = [ "auto" ] } = imageStyle || {}
174
- const src = parseUrl(backgroundImage)
428
+ // 0deg, red 10%, blue 20% 解析为 ['0deg', 'red, 10%', 'blue, 20%']
429
+ const [direction, ...colorList] = linearText.split(/,(?![^(#]*\))/)
430
+ // 记录需要填充起点的起始位置
431
+ let startIdx = 0; let startVal = 0
432
+ // 把 ['red, 10%', 'blue, 20%']解析为 [[red, 10%], [blue, 20%]]
433
+ const linearInfo = colorList.map(item => item.trim().split(/(?<!,)\s+/))
434
+ .reduce<LinearInfo>((prev, cur, idx, self) => {
435
+ const { colors, locations } = prev
436
+ const [color, val] = cur
437
+ let numberVal: number = parseFloat(val) / 100
438
+
439
+ // 处理渐变默认值
440
+ if (idx === 0) {
441
+ numberVal = numberVal || 0
442
+ } else if (self.length - 1 === idx) {
443
+ numberVal = numberVal || 1
444
+ }
175
445
 
176
- let sizeList = backgroundSize.slice() as DimensionValue []
446
+ // 出现缺省值时进行填充
447
+ if (idx - startIdx > 1 && !isNaN(numberVal)) {
448
+ locations.push(...calcSteps(startVal, numberVal, idx - startIdx))
449
+ }
177
450
 
178
- sizeList.length === 1 && sizeList.push(sizeList[0])
451
+ if (!isNaN(numberVal)) {
452
+ startIdx = idx
453
+ startVal = numberVal
454
+ }
455
+
456
+ // 添加color的数组
457
+ colors.push(color.trim())
458
+
459
+ !isNaN(numberVal) && locations.push(numberVal)
460
+ return prev
461
+ }, { colors: [], locations: [] })
462
+
463
+ return {
464
+ ...linearInfo,
465
+ direction: direction.trim()
466
+ }
467
+ }
468
+
469
+ function parseBgImage (text: string): {
470
+ linearInfo?: LinearInfo;
471
+ direction?: string;
472
+ type?: 'image' | 'linear'
473
+ src?: string
474
+ } {
475
+ if (!text) return {}
476
+
477
+ const src = parseUrl(text)
478
+ if (src) return { src, type: 'image' }
479
+
480
+ const linearInfo = parseLinearGradient(text)
481
+ if (!linearInfo) return {}
482
+ return {
483
+ linearInfo,
484
+ type: 'linear'
485
+ }
486
+ }
487
+
488
+ function normalizeBackgroundSize (backgroundSize: Exclude<ExtendedViewStyle['backgroundSize'], undefined>, type: 'image' | 'linear' | undefined) {
489
+ const sizeList = backgroundSize.slice()
490
+ if (sizeList.length === 1) sizeList.push('auto')
491
+
492
+ if (type === 'linear') {
493
+ // 处理当使用渐变的时候,background-size出现cover, contain, auto,当作100%处理
494
+ for (const i in sizeList) {
495
+ const val = sizeList[i]
496
+ sizeList[i] = /^cover|contain|auto$/.test(val as string) ? '100%' : val
497
+ }
498
+ }
499
+
500
+ return sizeList
501
+ }
502
+
503
+ function preParseImage (imageStyle?: ExtendedViewStyle) {
504
+ const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = imageStyle || {}
505
+ const { type, src, linearInfo } = parseBgImage(backgroundImage)
179
506
 
180
507
  return {
181
508
  src,
182
- sizeList
509
+ linearInfo,
510
+ type,
511
+ sizeList: normalizeBackgroundSize(backgroundSize, type),
512
+ backgroundPosition: normalizeBackgroundPosition(backgroundPosition)
183
513
  }
184
514
  }
185
515
 
186
- function wrapImage(imageStyle?: ExtendedViewStyle) {
187
- const [show, setShow] = useState<boolean>(false)
516
+ function isDiagonalAngle (linearInfo?: LinearInfo): boolean {
517
+ return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction])
518
+ }
519
+
520
+ function wrapImage (imageStyle?: ExtendedViewStyle) {
521
+ // 预处理数据
522
+ const preImageInfo: PreImageInfo = preParseImage(imageStyle)
523
+ // 预解析
524
+ const { src, sizeList, type } = preImageInfo
525
+
526
+ // 判断是否可挂载onLayout
527
+ const { needLayout, needImageSize } = checkNeedLayout(preImageInfo)
528
+
529
+ const [show, setShow] = useState<boolean>(((type === 'image' && !!src) || type === 'linear') && !needLayout && !needImageSize)
188
530
  const [, setImageSizeWidth] = useState<number | null>(null)
189
531
  const [, setImageSizeHeight] = useState<number | null>(null)
190
532
  const [, setLayoutInfoWidth] = useState<number | null>(null)
191
533
  const [, setLayoutInfoHeight] = useState<number | null>(null)
192
534
  const sizeInfo = useRef<Size | null>(null)
193
535
  const layoutInfo = useRef<Size | null>(null)
194
-
195
- // 预解析
196
- const preImageInfo: PreImageInfo = preParseImage(imageStyle)
197
-
198
-
199
- // 判断是否可挂载onLayout
200
- const needLayout = checkNeedLayout(preImageInfo)
201
- const { src, sizeList } = preImageInfo
202
-
203
536
  useEffect(() => {
204
- if(!src) {
205
- setShow(false)
206
- sizeInfo.current = null
207
- layoutInfo.current = null
208
- return
537
+ sizeInfo.current = null
538
+ if (type === 'linear') {
539
+ if (!needLayout) setShow(true)
540
+ return
209
541
  }
210
-
211
- if (!sizeList.includes('auto')) {
542
+
543
+ if (!src) {
544
+ setShow(false)
545
+ return
546
+ // 一开始未出现,数据改变时出现
547
+ } else if (!(needLayout || needImageSize)) {
212
548
  setShow(true)
213
549
  return
214
550
  }
215
- Image.getSize(src, (width, height) => {
216
- sizeInfo.current = {
217
- width,
218
- height
219
- }
220
- //1. 当需要绑定onLayout 2. 获取到布局信息
221
- if (!needLayout || layoutInfo.current) {
222
- setImageSizeWidth(width)
223
- setImageSizeHeight(height)
224
- if(layoutInfo.current) {
225
- setLayoutInfoWidth(layoutInfo.current.width)
226
- setLayoutInfoHeight(layoutInfo.current.height)
551
+
552
+ if (needImageSize) {
553
+ Image.getSize(src, (width, height) => {
554
+ sizeInfo.current = {
555
+ width,
556
+ height
227
557
  }
228
- setShow(true)
229
- }
230
- })
231
- }, [preImageInfo?.src])
558
+ // 1. 当需要绑定onLayout 2. 获取到布局信息
559
+ if (!needLayout || layoutInfo.current) {
560
+ setImageSizeWidth(width)
561
+ setImageSizeHeight(height)
562
+ if (layoutInfo.current) {
563
+ setLayoutInfoWidth(layoutInfo.current.width)
564
+ setLayoutInfoHeight(layoutInfo.current.height)
565
+ }
566
+ setShow(true)
567
+ }
568
+ })
569
+ }
570
+ // type 添加type 处理无渐变 有渐变的场景
571
+ }, [src, type])
232
572
 
233
- if (!preImageInfo?.src) return null
573
+ if (!type) return null
234
574
 
235
575
  const onLayout = (res: LayoutChangeEvent) => {
236
576
  const { width, height } = res?.nativeEvent?.layout || {}
@@ -238,67 +578,78 @@ function wrapImage(imageStyle?: ExtendedViewStyle) {
238
578
  width,
239
579
  height
240
580
  }
241
- if (sizeInfo.current) {
581
+ if (!needImageSize) {
582
+ setLayoutInfoWidth(width)
583
+ setLayoutInfoHeight(height)
584
+ // 有渐变角度的时候,才触发渲染组件
585
+ if (type === 'linear') {
586
+ sizeInfo.current = {
587
+ width: calcPercent(sizeList[0] as NumberVal, width),
588
+ height: calcPercent(sizeList[1] as NumberVal, height)
589
+ }
590
+ setImageSizeWidth(sizeInfo.current.width)
591
+ setImageSizeHeight(sizeInfo.current.height)
592
+ setShow(true)
593
+ }
594
+ } else if (sizeInfo.current) {
595
+ setLayoutInfoWidth(width)
596
+ setLayoutInfoHeight(height)
242
597
  setImageSizeWidth(sizeInfo.current.width)
243
598
  setImageSizeHeight(sizeInfo.current.height)
244
- setLayoutInfoWidth(width)
245
- setLayoutInfoHeight(height)
246
599
  setShow(true)
247
600
  }
248
601
  }
249
-
250
- return <View key='viewBgImg' {...needLayout ? {onLayout} : null } style={{ ...StyleSheet.absoluteFillObject, width: '100%', height: '100%', overflow: 'hidden'}}>
251
- {show && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
252
- </View>
253
- }
254
602
 
255
- function splitStyle(styles: ExtendedViewStyle) {
256
- return groupBy(styles, (key) => {
257
- if (TEXT_STYLE_REGEX.test(key))
258
- return 'textStyle'
259
- else if (IMAGE_STYLE_REGEX.test(key)) return 'imageStyle'
260
- return 'innerStyle'
261
- }, {})
603
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, width: '100%', height: '100%', overflow: 'hidden' }}>
604
+ {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
605
+ {show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
606
+ </View>
262
607
  }
263
608
 
264
- function every(children: ReactNode [], callback: (children: ReactNode) => boolean) {
265
- return children.every((child) => callback(child))
609
+ interface WrapChildrenConfig {
610
+ hasVarDec: boolean
611
+ enableBackground: boolean
612
+ textStyle?: TextStyle
613
+ backgroundStyle?: ExtendedViewStyle
614
+ varContext?: Record<string, any>
615
+ textProps?: Record<string, any>
266
616
  }
267
617
 
268
- function wrapChildren(children: ReactNode | ReactNode [] , textStyle?: StyleProp<TextStyle>, imageStyle?: ExtendedViewStyle) {
269
- children = Array.isArray(children) ? children : [children]
270
- if (every(children as ReactNode[], (child)=>isText(child))) {
271
- children = [<Text key='viewTextWrap' style={textStyle}>{children}</Text>]
272
- } else {
273
- if(textStyle) console.warn('Text style will be ignored unless every child of the view is Text node!')
274
- }
618
+ function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps }: WrapChildrenConfig) {
619
+ const children = wrapChildren(props, {
620
+ hasVarDec,
621
+ varContext,
622
+ textStyle,
623
+ textProps
624
+ })
275
625
 
276
626
  return [
277
- wrapImage(imageStyle),
278
- ...children
627
+ enableBackground ? wrapImage(backgroundStyle) : null,
628
+ children
279
629
  ]
280
630
  }
281
631
 
282
- const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref): JSX.Element => {
283
- const {
284
- style = [],
285
- children,
286
- hoverStyle,
632
+ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, ref): JSX.Element => {
633
+ const { textProps, innerProps: props = {} } = splitProps(viewProps)
634
+ let {
635
+ style = {},
636
+ 'hover-style': hoverStyle,
287
637
  'hover-start-time': hoverStartTime = 50,
288
638
  'hover-stay-time': hoverStayTime = 400,
289
- 'enable-offset': enableOffset
639
+ 'enable-var': enableVar,
640
+ 'external-var-context': externalVarContext,
641
+ 'enable-background': enableBackground,
642
+ 'parent-font-size': parentFontSize,
643
+ 'parent-width': parentWidth,
644
+ 'parent-height': parentHeight
290
645
  } = props
291
646
 
292
647
  const [isHover, setIsHover] = useState(false)
293
648
 
294
- const layoutRef = useRef({})
295
-
296
- // 打平 style 数组
297
- const styleObj:ExtendedViewStyle = StyleSheet.flatten(style)
298
649
  // 默认样式
299
- const defaultStyle:ExtendedViewStyle = {
650
+ const defaultStyle: ExtendedViewStyle = {
300
651
  // flex 布局相关的默认样式
301
- ...styleObj.display === 'flex' && {
652
+ ...style.display === 'flex' && {
302
653
  flexDirection: 'row',
303
654
  flexBasis: 'auto',
304
655
  flexShrink: 1,
@@ -306,6 +657,35 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
306
657
  }
307
658
  }
308
659
 
660
+ const styleObj: ExtendedViewStyle = {
661
+ ...defaultStyle,
662
+ ...style,
663
+ ...(isHover ? hoverStyle : null)
664
+ }
665
+
666
+ const {
667
+ normalStyle,
668
+ hasSelfPercent,
669
+ hasVarDec,
670
+ varContextRef,
671
+ setWidth,
672
+ setHeight
673
+ } = useTransformStyle(styleObj, {
674
+ enableVar,
675
+ externalVarContext,
676
+ parentFontSize,
677
+ parentWidth,
678
+ parentHeight
679
+ })
680
+
681
+ const { textStyle, backgroundStyle, innerStyle } = splitStyle(normalStyle)
682
+
683
+ enableBackground = enableBackground || !!backgroundStyle
684
+ const enableBackgroundRef = useRef(enableBackground)
685
+ if (enableBackgroundRef.current !== enableBackground) {
686
+ throw new Error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.')
687
+ }
688
+
309
689
  const { nodeRef } = useNodesRef<View, _ViewProps>(props, ref, {
310
690
  defaultStyle
311
691
  })
@@ -325,7 +705,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
325
705
  const setStartTimer = () => {
326
706
  dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
327
707
  dataRef.current.startTimer = setTimeout(() => {
328
- setIsHover(() => true)
708
+ setIsHover(true)
329
709
  }, +hoverStartTime)
330
710
  }
331
711
 
@@ -333,50 +713,41 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
333
713
  dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
334
714
  dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
335
715
  dataRef.current.stayTimer = setTimeout(() => {
336
- setIsHover(() => false)
716
+ setIsHover(false)
337
717
  }, +hoverStayTime)
338
718
  }
339
719
 
340
- function onTouchStart(e: NativeSyntheticEvent<TouchEvent>){
341
- const { bindtouchstart } = props;
720
+ function onTouchStart (e: NativeSyntheticEvent<TouchEvent>) {
721
+ const { bindtouchstart } = props
342
722
  bindtouchstart && bindtouchstart(e)
343
723
  setStartTimer()
344
724
  }
345
725
 
346
- function onTouchEnd(e: NativeSyntheticEvent<TouchEvent>){
347
- const { bindtouchend } = props;
726
+ function onTouchEnd (e: NativeSyntheticEvent<TouchEvent>) {
727
+ const { bindtouchend } = props
348
728
  bindtouchend && bindtouchend(e)
349
729
  setStayTimer()
350
730
  }
351
731
 
352
- const onLayout = () => {
353
-
354
- nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
355
- layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
356
- })
357
- }
358
-
359
- const {textStyle, imageStyle, innerStyle} = splitStyle(StyleSheet.flatten<ExtendedViewStyle>([
360
- defaultStyle,
361
- styleObj,
362
- ...(isHover ? hoverStyle : [])]
363
- ))
732
+ const {
733
+ layoutRef,
734
+ layoutStyle,
735
+ layoutProps
736
+ } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
364
737
 
365
738
  const innerProps = useInnerProps(props, {
366
739
  ref: nodeRef,
367
- ...enableOffset ? { onLayout } : {},
740
+ style: { ...innerStyle, ...layoutStyle },
741
+ ...layoutProps,
368
742
  ...(hoverStyle && {
369
743
  bindtouchstart: onTouchStart,
370
744
  bindtouchend: onTouchEnd
371
745
  })
372
746
  }, [
373
- 'style',
374
- 'children',
375
747
  'hover-start-time',
376
748
  'hover-stay-time',
377
- 'hoverStyle',
378
- 'hover-class',
379
- 'enable-offset'
749
+ 'hover-style',
750
+ 'hover-class'
380
751
  ], {
381
752
  layoutRef
382
753
  })
@@ -384,9 +755,20 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
384
755
  return (
385
756
  <View
386
757
  {...innerProps}
387
- style={innerStyle}
388
758
  >
389
- {wrapChildren(children, textStyle, imageStyle)}
759
+ {
760
+ wrapWithChildren(
761
+ props,
762
+ {
763
+ hasVarDec,
764
+ enableBackground: enableBackgroundRef.current,
765
+ textStyle,
766
+ backgroundStyle,
767
+ varContext: varContextRef.current,
768
+ textProps
769
+ }
770
+ )
771
+ }
390
772
  </View>
391
773
  )
392
774
  })
@@ -394,4 +776,3 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
394
776
  _View.displayName = 'mpx-view'
395
777
 
396
778
  export default _View
397
-