@mpxjs/webpack-plugin 2.9.62 → 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.
- package/lib/index.js +1 -3
- package/lib/platform/style/wx/index.js +67 -53
- package/lib/react/processStyles.js +1 -0
- package/lib/react/processTemplate.js +2 -3
- package/lib/react/style-helper.js +12 -7
- package/lib/runtime/components/react/context.ts +9 -7
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +12 -1
- package/lib/runtime/components/react/dist/mpx-button.jsx +52 -74
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +19 -18
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +28 -41
- package/lib/runtime/components/react/dist/mpx-form.jsx +16 -14
- package/lib/runtime/components/react/dist/mpx-icon.jsx +14 -17
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +34 -33
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +3 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +35 -31
- package/lib/runtime/components/react/dist/mpx-label.jsx +29 -37
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -18
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +8 -8
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +9 -9
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +7 -4
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +11 -7
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +18 -18
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +102 -10
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +147 -53
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +19 -18
- package/lib/runtime/components/react/dist/mpx-radio.jsx +28 -43
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +8 -4
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +33 -26
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +139 -74
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +14 -6
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +19 -11
- package/lib/runtime/components/react/dist/mpx-switch.jsx +17 -14
- package/lib/runtime/components/react/dist/mpx-text.jsx +19 -35
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +284 -209
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +8 -5
- package/lib/runtime/components/react/dist/parser.js +218 -0
- package/lib/runtime/components/react/dist/utils.jsx +433 -0
- package/lib/runtime/components/react/getInnerListeners.ts +18 -8
- package/lib/runtime/components/react/mpx-button.tsx +81 -91
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +48 -43
- package/lib/runtime/components/react/mpx-checkbox.tsx +52 -63
- package/lib/runtime/components/react/mpx-form.tsx +49 -21
- package/lib/runtime/components/react/mpx-icon.tsx +30 -27
- package/lib/runtime/components/react/mpx-image/index.tsx +52 -46
- package/lib/runtime/components/react/mpx-image/svg.tsx +5 -3
- package/lib/runtime/components/react/mpx-input.tsx +58 -38
- package/lib/runtime/components/react/mpx-label.tsx +54 -59
- package/lib/runtime/components/react/mpx-movable-area.tsx +38 -24
- package/lib/runtime/components/react/mpx-movable-view.tsx +27 -28
- package/lib/runtime/components/react/mpx-navigator.tsx +2 -2
- package/lib/runtime/components/react/mpx-picker/date.tsx +2 -3
- package/lib/runtime/components/react/mpx-picker/index.tsx +10 -10
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +15 -12
- package/lib/runtime/components/react/mpx-picker/region.tsx +21 -18
- package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -6
- package/lib/runtime/components/react/mpx-picker/time.tsx +25 -29
- package/lib/runtime/components/react/mpx-picker/type.ts +1 -1
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +148 -20
- package/lib/runtime/components/react/mpx-picker-view.tsx +179 -63
- package/lib/runtime/components/react/mpx-radio-group.tsx +50 -47
- package/lib/runtime/components/react/mpx-radio.tsx +56 -72
- package/lib/runtime/components/react/mpx-root-portal.tsx +10 -8
- package/lib/runtime/components/react/mpx-scroll-view.tsx +133 -103
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +174 -96
- package/lib/runtime/components/react/mpx-swiper/index.tsx +18 -9
- package/lib/runtime/components/react/mpx-swiper/type.ts +16 -5
- package/lib/runtime/components/react/mpx-swiper-item.tsx +46 -13
- package/lib/runtime/components/react/mpx-switch.tsx +44 -23
- package/lib/runtime/components/react/mpx-text.tsx +37 -45
- package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
- package/lib/runtime/components/react/mpx-view.tsx +388 -240
- package/lib/runtime/components/react/mpx-web-view.tsx +19 -20
- package/lib/runtime/components/react/parser.ts +245 -0
- package/lib/runtime/components/react/types/common.ts +4 -4
- package/lib/runtime/components/react/types/global.d.ts +14 -2
- package/lib/runtime/components/react/useNodesRef.ts +1 -2
- package/lib/runtime/components/react/utils.tsx +505 -0
- package/lib/template-compiler/compiler.js +28 -20
- package/lib/template-compiler/gen-node-react.js +1 -3
- package/lib/web/processStyles.js +2 -5
- package/package.json +6 -4
- package/lib/runtime/components/react/dist/utils.js +0 -148
- package/lib/runtime/components/react/utils.ts +0 -170
|
@@ -4,21 +4,26 @@
|
|
|
4
4
|
* ✔ hover-start-time
|
|
5
5
|
* ✔ hover-stay-time
|
|
6
6
|
*/
|
|
7
|
-
import { View,
|
|
8
|
-
import { useRef, useState, useEffect, forwardRef, ReactNode, JSX } from 'react'
|
|
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'
|
|
9
9
|
import useInnerProps from './getInnerListeners'
|
|
10
10
|
import { ExtendedViewStyle } from './types/common'
|
|
11
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'
|
|
12
14
|
|
|
13
|
-
import { parseUrl, PERCENT_REGEX, isText, every, normalizeStyle, splitStyle, splitProps, throwReactWarning, transformTextStyle } from './utils'
|
|
14
15
|
export interface _ViewProps extends ViewProps {
|
|
15
16
|
style?: ExtendedViewStyle
|
|
16
17
|
children?: ReactNode | ReactNode[]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'enable-
|
|
21
|
-
'enable-
|
|
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
|
|
22
27
|
bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
23
28
|
bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
24
29
|
bindtouchend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
@@ -31,7 +36,7 @@ type Size = {
|
|
|
31
36
|
height: number
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
type DimensionValue = number | 'auto' |
|
|
39
|
+
type DimensionValue = number | `${number}%` | 'auto' | 'contain' | 'cover'
|
|
35
40
|
|
|
36
41
|
type Position = {
|
|
37
42
|
left?: number
|
|
@@ -48,35 +53,94 @@ type PositionVal = PositionKey | NumberVal
|
|
|
48
53
|
|
|
49
54
|
type backgroundPositionList = ['left' | 'right', NumberVal, 'top' | 'bottom', NumberVal] | []
|
|
50
55
|
|
|
56
|
+
type LinearInfo = {
|
|
57
|
+
colors: Array<string>,
|
|
58
|
+
locations: Array<number>,
|
|
59
|
+
direction?: string
|
|
60
|
+
}
|
|
61
|
+
|
|
51
62
|
type PreImageInfo = {
|
|
52
63
|
src?: string,
|
|
53
64
|
sizeList: DimensionValue[]
|
|
54
|
-
|
|
65
|
+
type?: 'image' | 'linear'
|
|
66
|
+
linearInfo?: LinearInfo
|
|
67
|
+
// containPercentSymbol?: boolean
|
|
55
68
|
backgroundPosition: backgroundPositionList
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
type ImageProps = {
|
|
59
72
|
style: ImageStyle,
|
|
60
|
-
src?: string
|
|
73
|
+
src?: string,
|
|
74
|
+
colors: Array<string>,
|
|
75
|
+
locations?: Array<number>
|
|
76
|
+
angle?: number
|
|
77
|
+
}
|
|
78
|
+
|
|
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
|
+
}
|
|
105
|
+
|
|
106
|
+
// 弧度转化为角度的公式
|
|
107
|
+
function radToAngle (r: number) {
|
|
108
|
+
return r * 180 / Math.PI
|
|
61
109
|
}
|
|
62
110
|
|
|
63
111
|
const applyHandlers = (handlers: Handler[], args: any[]) => {
|
|
64
|
-
for (
|
|
112
|
+
for (const handler of handlers) {
|
|
65
113
|
handler(...args)
|
|
66
114
|
}
|
|
67
115
|
}
|
|
68
116
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
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
|
+
|
|
72
126
|
// 含有百分号,center 需计算布局
|
|
73
|
-
|
|
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
|
+
}
|
|
74
134
|
|
|
135
|
+
const checkNeedLayout = (preImageInfo: PreImageInfo) => {
|
|
136
|
+
const { sizeList } = preImageInfo
|
|
137
|
+
const [width] = sizeList
|
|
138
|
+
// 在渐变的时候,background-size的cover,contain, auto属性值,转化为100%, needLayout计算逻辑和原来保持一致,needImageSize始终为false
|
|
75
139
|
return {
|
|
76
140
|
// 是否开启layout的计算
|
|
77
|
-
needLayout:
|
|
141
|
+
needLayout: isNeedLayout(preImageInfo),
|
|
78
142
|
// 是否开启原始宽度的计算
|
|
79
|
-
needImageSize:
|
|
143
|
+
needImageSize: isBackgroundSizeKeyword(width) || sizeList.includes('auto')
|
|
80
144
|
}
|
|
81
145
|
}
|
|
82
146
|
|
|
@@ -85,14 +149,14 @@ const checkNeedLayout = (style: PreImageInfo) => {
|
|
|
85
149
|
* lh - 容器的高度
|
|
86
150
|
* ratio - 原始图片的宽高比
|
|
87
151
|
* **/
|
|
88
|
-
function calculateSize(h: number, ratio: number, lh?: number | boolean, reverse
|
|
89
|
-
let height = 0
|
|
152
|
+
function calculateSize (h: number, ratio: number, lh?: number | boolean, reverse = false): Size | null {
|
|
153
|
+
let height = 0; let width = 0
|
|
90
154
|
|
|
91
155
|
if (typeof lh === 'boolean') {
|
|
92
156
|
reverse = lh
|
|
93
157
|
}
|
|
94
158
|
|
|
95
|
-
if (
|
|
159
|
+
if (isPercent(h)) { // auto px/rpx
|
|
96
160
|
if (!lh) return null
|
|
97
161
|
height = (parseFloat(h) / 100) * (lh as number)
|
|
98
162
|
width = height * ratio
|
|
@@ -112,11 +176,11 @@ function calculateSize(h: number, ratio: number, lh?: number | boolean, reverse:
|
|
|
112
176
|
* ch - 容器的高度
|
|
113
177
|
* val - 用户设置的百分比
|
|
114
178
|
* **/
|
|
115
|
-
function calculateSizePosition(h: number, ch: number, val: string): number {
|
|
179
|
+
function calculateSizePosition (h: number, ch: number, val: string): number {
|
|
116
180
|
if (!h || !ch) return 0
|
|
117
181
|
|
|
118
182
|
// 百分比需要单独的计算
|
|
119
|
-
if (
|
|
183
|
+
if (isPercent(h)) {
|
|
120
184
|
h = ch * parseFloat(h) / 100
|
|
121
185
|
}
|
|
122
186
|
|
|
@@ -124,16 +188,25 @@ function calculateSizePosition(h: number, ch: number, val: string): number {
|
|
|
124
188
|
return (ch - h) * parseFloat(val) / 100
|
|
125
189
|
}
|
|
126
190
|
|
|
127
|
-
|
|
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) {
|
|
128
201
|
const bps = preImageInfo.backgroundPosition
|
|
129
202
|
if (bps.length === 0) return
|
|
130
|
-
|
|
131
|
-
|
|
203
|
+
const style: Position = {}
|
|
204
|
+
const imageStyle: ImageStyle = imageProps.style || {}
|
|
132
205
|
|
|
133
206
|
for (let i = 0; i < bps.length; i += 2) {
|
|
134
|
-
|
|
207
|
+
const key = bps[i] as PositionKey; const val = bps[i + 1]
|
|
135
208
|
// 需要获取 图片宽度 和 容器的宽度 进行计算
|
|
136
|
-
if (
|
|
209
|
+
if (isPercent(val)) {
|
|
137
210
|
if (i === 0) {
|
|
138
211
|
style[key] = calculateSizePosition(imageStyle.width as number, layoutInfo?.width, val)
|
|
139
212
|
} else {
|
|
@@ -148,12 +221,11 @@ function backgroundPosition(imageProps: ImageProps, preImageInfo: PreImageInfo,
|
|
|
148
221
|
...imageProps.style as ImageStyle,
|
|
149
222
|
...style
|
|
150
223
|
}
|
|
151
|
-
|
|
152
224
|
}
|
|
153
225
|
|
|
154
226
|
// background-size 转换
|
|
155
|
-
function backgroundSize(imageProps: ImageProps, preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) {
|
|
156
|
-
|
|
227
|
+
function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) {
|
|
228
|
+
const sizeList = preImageInfo.sizeList
|
|
157
229
|
if (!sizeList) return
|
|
158
230
|
const { width: layoutWidth, height: layoutHeight } = layoutInfo || {}
|
|
159
231
|
const { width: imageSizeWidth, height: imageSizeHeight } = imageSize || {}
|
|
@@ -166,12 +238,12 @@ function backgroundSize(imageProps: ImageProps, preImageInfo: PreImageInfo, imag
|
|
|
166
238
|
// 枚举值
|
|
167
239
|
if (typeof width === 'string' && ['cover', 'contain'].includes(width)) {
|
|
168
240
|
if (layoutInfo && imageSize) {
|
|
169
|
-
|
|
170
|
-
|
|
241
|
+
const layoutRatio = layoutWidth / imageSizeWidth
|
|
242
|
+
const eleRatio = imageSizeWidth / imageSizeHeight
|
|
171
243
|
// 容器宽高比 大于 图片的宽高比,依据宽度作为基准,否则以高度为基准
|
|
172
|
-
if (layoutRatio <= eleRatio && (width as string) === 'contain' || layoutRatio >= eleRatio && (width as string) === 'cover') {
|
|
244
|
+
if ((layoutRatio <= eleRatio && (width as string) === 'contain') || (layoutRatio >= eleRatio && (width as string) === 'cover')) {
|
|
173
245
|
dimensions = calculateSize(layoutWidth as number, imageSizeHeight / imageSizeWidth, true) as Size
|
|
174
|
-
} else if (layoutRatio > eleRatio && (width as string) === 'contain' || layoutRatio < eleRatio && (width as string) === 'cover') {
|
|
246
|
+
} else if ((layoutRatio > eleRatio && (width as string) === 'contain') || (layoutRatio < eleRatio && (width as string) === 'cover')) {
|
|
175
247
|
dimensions = calculateSize(layoutHeight as number, imageSizeWidth / imageSizeHeight) as Size
|
|
176
248
|
}
|
|
177
249
|
}
|
|
@@ -194,9 +266,9 @@ function backgroundSize(imageProps: ImageProps, preImageInfo: PreImageInfo, imag
|
|
|
194
266
|
// 数值类型设置为 stretch
|
|
195
267
|
(imageProps.style as ImageStyle).resizeMode = 'stretch'
|
|
196
268
|
dimensions = {
|
|
197
|
-
width:
|
|
198
|
-
height:
|
|
199
|
-
}
|
|
269
|
+
width: isPercent(width) ? width : +width,
|
|
270
|
+
height: isPercent(height) ? height : +height
|
|
271
|
+
} as { width: NumberVal, height: NumberVal }
|
|
200
272
|
}
|
|
201
273
|
}
|
|
202
274
|
// 样式合并
|
|
@@ -207,8 +279,32 @@ function backgroundSize(imageProps: ImageProps, preImageInfo: PreImageInfo, imag
|
|
|
207
279
|
}
|
|
208
280
|
|
|
209
281
|
// background-image转换为source
|
|
210
|
-
function backgroundImage(imageProps: ImageProps, preImageInfo: PreImageInfo) {
|
|
211
|
-
|
|
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
|
|
212
308
|
}
|
|
213
309
|
|
|
214
310
|
const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) => {
|
|
@@ -218,23 +314,23 @@ const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutIn
|
|
|
218
314
|
resizeMode: 'cover' as ImageResizeMode,
|
|
219
315
|
position: 'absolute'
|
|
220
316
|
// ...StyleSheet.absoluteFillObject
|
|
221
|
-
}
|
|
317
|
+
},
|
|
318
|
+
colors: []
|
|
222
319
|
}
|
|
223
|
-
applyHandlers([backgroundSize, backgroundImage, backgroundPosition], [imageProps, preImageInfo, imageSize, layoutInfo])
|
|
224
|
-
|
|
320
|
+
applyHandlers([backgroundSize, backgroundImage, backgroundPosition, linearGradient], [imageProps, preImageInfo, imageSize, layoutInfo])
|
|
321
|
+
|
|
225
322
|
return imageProps
|
|
226
323
|
}
|
|
227
324
|
|
|
228
|
-
function isHorizontal(val: PositionVal): val is 'left' | 'right' {
|
|
325
|
+
function isHorizontal (val: PositionVal): val is 'left' | 'right' {
|
|
229
326
|
return typeof val === 'string' && /^(left|right)$/.test(val)
|
|
230
327
|
}
|
|
231
328
|
|
|
232
|
-
function isVertical(val: PositionVal): val is 'top' | 'bottom' {
|
|
329
|
+
function isVertical (val: PositionVal): val is 'top' | 'bottom' {
|
|
233
330
|
return typeof val === 'string' && /^(top|bottom)$/.test(val)
|
|
234
331
|
}
|
|
235
332
|
|
|
236
|
-
function normalizeBackgroundPosition(parts: PositionVal[]): backgroundPositionList {
|
|
237
|
-
|
|
333
|
+
function normalizeBackgroundPosition (parts: PositionVal[]): backgroundPositionList {
|
|
238
334
|
if (parts.length === 0) return []
|
|
239
335
|
|
|
240
336
|
// 定义默认值
|
|
@@ -299,71 +395,184 @@ function normalizeBackgroundPosition(parts: PositionVal[]): backgroundPositionLi
|
|
|
299
395
|
return [hStart, hOffset, vStart, vOffset] as backgroundPositionList
|
|
300
396
|
}
|
|
301
397
|
|
|
302
|
-
|
|
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
|
|
420
|
+
|
|
421
|
+
// 添加默认的角度
|
|
422
|
+
if (!/^to|^-?\d+deg/.test(linearText)) {
|
|
423
|
+
linearText = '180deg ,' + linearText
|
|
424
|
+
} else {
|
|
425
|
+
linearText = linearText.replace('to', '')
|
|
426
|
+
}
|
|
427
|
+
|
|
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
|
+
}
|
|
445
|
+
|
|
446
|
+
// 出现缺省值时进行填充
|
|
447
|
+
if (idx - startIdx > 1 && !isNaN(numberVal)) {
|
|
448
|
+
locations.push(...calcSteps(startVal, numberVal, idx - startIdx))
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (!isNaN(numberVal)) {
|
|
452
|
+
startIdx = idx
|
|
453
|
+
startVal = numberVal
|
|
454
|
+
}
|
|
303
455
|
|
|
304
|
-
|
|
305
|
-
|
|
456
|
+
// 添加color的数组
|
|
457
|
+
colors.push(color.trim())
|
|
306
458
|
|
|
307
|
-
|
|
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 {}
|
|
308
476
|
|
|
309
|
-
|
|
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)
|
|
310
506
|
|
|
311
507
|
return {
|
|
312
508
|
src,
|
|
313
|
-
|
|
509
|
+
linearInfo,
|
|
510
|
+
type,
|
|
511
|
+
sizeList: normalizeBackgroundSize(backgroundSize, type),
|
|
314
512
|
backgroundPosition: normalizeBackgroundPosition(backgroundPosition)
|
|
315
513
|
}
|
|
316
514
|
}
|
|
317
515
|
|
|
318
|
-
function
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const [, setImageSizeHeight] = useState<number | null>(null)
|
|
322
|
-
const [, setLayoutInfoWidth] = useState<number | null>(null)
|
|
323
|
-
const [, setLayoutInfoHeight] = useState<number | null>(null)
|
|
324
|
-
const sizeInfo = useRef<Size | null>(null)
|
|
325
|
-
const layoutInfo = useRef<Size | null>(null)
|
|
516
|
+
function isDiagonalAngle (linearInfo?: LinearInfo): boolean {
|
|
517
|
+
return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction])
|
|
518
|
+
}
|
|
326
519
|
|
|
327
|
-
|
|
520
|
+
function wrapImage (imageStyle?: ExtendedViewStyle) {
|
|
521
|
+
// 预处理数据
|
|
328
522
|
const preImageInfo: PreImageInfo = preParseImage(imageStyle)
|
|
523
|
+
// 预解析
|
|
524
|
+
const { src, sizeList, type } = preImageInfo
|
|
329
525
|
|
|
330
526
|
// 判断是否可挂载onLayout
|
|
331
527
|
const { needLayout, needImageSize } = checkNeedLayout(preImageInfo)
|
|
332
|
-
const { src } = preImageInfo
|
|
333
528
|
|
|
529
|
+
const [show, setShow] = useState<boolean>(((type === 'image' && !!src) || type === 'linear') && !needLayout && !needImageSize)
|
|
530
|
+
const [, setImageSizeWidth] = useState<number | null>(null)
|
|
531
|
+
const [, setImageSizeHeight] = useState<number | null>(null)
|
|
532
|
+
const [, setLayoutInfoWidth] = useState<number | null>(null)
|
|
533
|
+
const [, setLayoutInfoHeight] = useState<number | null>(null)
|
|
534
|
+
const sizeInfo = useRef<Size | null>(null)
|
|
535
|
+
const layoutInfo = useRef<Size | null>(null)
|
|
334
536
|
useEffect(() => {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
return
|
|
537
|
+
sizeInfo.current = null
|
|
538
|
+
if (type === 'linear') {
|
|
539
|
+
if (!needLayout) setShow(true)
|
|
540
|
+
return
|
|
340
541
|
}
|
|
341
542
|
|
|
342
|
-
if (!
|
|
543
|
+
if (!src) {
|
|
544
|
+
setShow(false)
|
|
545
|
+
return
|
|
546
|
+
// 一开始未出现,数据改变时出现
|
|
547
|
+
} else if (!(needLayout || needImageSize)) {
|
|
343
548
|
setShow(true)
|
|
344
549
|
return
|
|
345
550
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (!needLayout || layoutInfo.current) {
|
|
353
|
-
setImageSizeWidth(width)
|
|
354
|
-
setImageSizeHeight(height)
|
|
355
|
-
if(layoutInfo.current) {
|
|
356
|
-
setLayoutInfoWidth(layoutInfo.current.width)
|
|
357
|
-
setLayoutInfoHeight(layoutInfo.current.height)
|
|
551
|
+
|
|
552
|
+
if (needImageSize) {
|
|
553
|
+
Image.getSize(src, (width, height) => {
|
|
554
|
+
sizeInfo.current = {
|
|
555
|
+
width,
|
|
556
|
+
height
|
|
358
557
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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])
|
|
363
572
|
|
|
364
|
-
if (!
|
|
573
|
+
if (!type) return null
|
|
365
574
|
|
|
366
|
-
const onLayout = (res: LayoutChangeEvent
|
|
575
|
+
const onLayout = (res: LayoutChangeEvent) => {
|
|
367
576
|
const { width, height } = res?.nativeEvent?.layout || {}
|
|
368
577
|
layoutInfo.current = {
|
|
369
578
|
width,
|
|
@@ -372,90 +581,75 @@ function wrapImage(imageStyle?: ExtendedViewStyle) {
|
|
|
372
581
|
if (!needImageSize) {
|
|
373
582
|
setLayoutInfoWidth(width)
|
|
374
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
|
+
}
|
|
375
594
|
} else if (sizeInfo.current) {
|
|
376
595
|
setLayoutInfoWidth(width)
|
|
377
596
|
setLayoutInfoHeight(height)
|
|
378
597
|
setImageSizeWidth(sizeInfo.current.width)
|
|
379
|
-
setImageSizeHeight(sizeInfo.current.height)
|
|
598
|
+
setImageSizeHeight(sizeInfo.current.height)
|
|
380
599
|
setShow(true)
|
|
381
600
|
}
|
|
382
601
|
}
|
|
383
602
|
|
|
384
|
-
return <View key='
|
|
385
|
-
{show && <
|
|
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)} />}
|
|
386
606
|
</View>
|
|
387
607
|
}
|
|
388
608
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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>
|
|
616
|
+
}
|
|
392
617
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
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
|
+
})
|
|
401
625
|
|
|
402
626
|
return [
|
|
403
|
-
|
|
627
|
+
enableBackground ? wrapImage(backgroundStyle) : null,
|
|
404
628
|
children
|
|
405
629
|
]
|
|
406
630
|
}
|
|
407
631
|
|
|
408
|
-
const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
rules: {
|
|
412
|
-
width: 'translateX',
|
|
413
|
-
height: 'translateY'
|
|
414
|
-
}
|
|
415
|
-
}, {
|
|
416
|
-
key: 'borderTopLeftRadius',
|
|
417
|
-
rules: {
|
|
418
|
-
width: 'borderTopLeftRadius'
|
|
419
|
-
}
|
|
420
|
-
}, {
|
|
421
|
-
key: 'borderBottomLeftRadius',
|
|
422
|
-
rules: {
|
|
423
|
-
width: 'borderBottomLeftRadius'
|
|
424
|
-
}
|
|
425
|
-
}, {
|
|
426
|
-
key: 'borderBottomRightRadius',
|
|
427
|
-
rules: {
|
|
428
|
-
height: 'borderBottomRightRadius'
|
|
429
|
-
}
|
|
430
|
-
}, {
|
|
431
|
-
key: 'borderTopRightRadius',
|
|
432
|
-
rules: {
|
|
433
|
-
height: 'borderTopRightRadius'
|
|
434
|
-
}
|
|
435
|
-
}]
|
|
436
|
-
const {
|
|
632
|
+
const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, ref): JSX.Element => {
|
|
633
|
+
const { textProps, innerProps: props = {} } = splitProps(viewProps)
|
|
634
|
+
let {
|
|
437
635
|
style = {},
|
|
438
|
-
|
|
439
|
-
hoverStyle,
|
|
636
|
+
'hover-style': hoverStyle,
|
|
440
637
|
'hover-start-time': hoverStartTime = 50,
|
|
441
638
|
'hover-stay-time': hoverStayTime = 400,
|
|
442
|
-
'enable-
|
|
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
|
|
443
645
|
} = props
|
|
444
646
|
|
|
445
647
|
const [isHover, setIsHover] = useState(false)
|
|
446
|
-
let transformStyle = {}
|
|
447
|
-
|
|
448
|
-
const [containerWidth, setContainerWidth] = useState(0)
|
|
449
|
-
const [containerHeight, setContainerHeight] = useState(0)
|
|
450
|
-
|
|
451
|
-
const layoutRef = useRef({})
|
|
452
648
|
|
|
453
|
-
// 打平 style 数组
|
|
454
|
-
const styleObj: ExtendedViewStyle = normalizeStyle(style)
|
|
455
649
|
// 默认样式
|
|
456
650
|
const defaultStyle: ExtendedViewStyle = {
|
|
457
651
|
// flex 布局相关的默认样式
|
|
458
|
-
...
|
|
652
|
+
...style.display === 'flex' && {
|
|
459
653
|
flexDirection: 'row',
|
|
460
654
|
flexBasis: 'auto',
|
|
461
655
|
flexShrink: 1,
|
|
@@ -463,22 +657,33 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
|
|
|
463
657
|
}
|
|
464
658
|
}
|
|
465
659
|
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
|
478
679
|
})
|
|
479
680
|
|
|
480
|
-
|
|
481
|
-
|
|
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.')
|
|
482
687
|
}
|
|
483
688
|
|
|
484
689
|
const { nodeRef } = useNodesRef<View, _ViewProps>(props, ref, {
|
|
@@ -512,104 +717,37 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
|
|
|
512
717
|
}, +hoverStayTime)
|
|
513
718
|
}
|
|
514
719
|
|
|
515
|
-
function onTouchStart(e: NativeSyntheticEvent<TouchEvent>) {
|
|
516
|
-
const { bindtouchstart } = props
|
|
720
|
+
function onTouchStart (e: NativeSyntheticEvent<TouchEvent>) {
|
|
721
|
+
const { bindtouchstart } = props
|
|
517
722
|
bindtouchstart && bindtouchstart(e)
|
|
518
723
|
setStartTimer()
|
|
519
724
|
}
|
|
520
725
|
|
|
521
|
-
function onTouchEnd(e: NativeSyntheticEvent<TouchEvent>) {
|
|
522
|
-
const { bindtouchend } = props
|
|
726
|
+
function onTouchEnd (e: NativeSyntheticEvent<TouchEvent>) {
|
|
727
|
+
const { bindtouchend } = props
|
|
523
728
|
bindtouchend && bindtouchend(e)
|
|
524
729
|
setStayTimer()
|
|
525
730
|
}
|
|
526
731
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
if (Array.isArray(transformItemValue)) {
|
|
533
|
-
const transformStyle: Record<string, any>[] = []
|
|
534
|
-
styleObj[styleItem.key].forEach((transformItem: Record<string, any>) => {
|
|
535
|
-
const rules = styleItem.rules
|
|
536
|
-
for (const type in rules) {
|
|
537
|
-
const value = transformItem[rules[type]]
|
|
538
|
-
if (value !== undefined) {
|
|
539
|
-
if (PERCENT_REGEX.test(value)) {
|
|
540
|
-
const percentage = parseFloat(value) / 100;
|
|
541
|
-
if (type === 'height' && height) {
|
|
542
|
-
transformStyle.push({ [rules[type]]: percentage * height });
|
|
543
|
-
} else if (type === 'width' && width) {
|
|
544
|
-
transformStyle.push({ [rules[type]]: percentage * width });
|
|
545
|
-
} else {
|
|
546
|
-
transformStyle.push({ [rules[type]]: 0 });
|
|
547
|
-
}
|
|
548
|
-
} else {
|
|
549
|
-
transformStyle.push(transformItem);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
})
|
|
554
|
-
styleMap[styleItem.key] = transformStyle
|
|
555
|
-
} else if (typeof transformItemValue === 'string') {
|
|
556
|
-
const rules = styleItem.rules
|
|
557
|
-
for (const type in rules) {
|
|
558
|
-
if (transformItemValue) {
|
|
559
|
-
if (PERCENT_REGEX.test(transformItemValue)) {
|
|
560
|
-
const percentage = parseFloat(transformItemValue) / 100;
|
|
561
|
-
if (type === 'height' && height) {
|
|
562
|
-
styleMap[styleItem.key] = percentage * height
|
|
563
|
-
} else if (type === 'width' && width) {
|
|
564
|
-
styleMap[styleItem.key] = percentage * width
|
|
565
|
-
} else {
|
|
566
|
-
styleMap[styleItem.key] = 0
|
|
567
|
-
}
|
|
568
|
-
} else {
|
|
569
|
-
styleMap[styleItem.key] = transformItemValue
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
})
|
|
575
|
-
return styleMap
|
|
576
|
-
}
|
|
577
|
-
const onLayout = (res: LayoutChangeEvent) => {
|
|
578
|
-
if (hasPercentStyle) {
|
|
579
|
-
const { width, height } = res?.nativeEvent?.layout || {}
|
|
580
|
-
setContainerWidth(width || 0)
|
|
581
|
-
setContainerHeight(height || 0)
|
|
582
|
-
}
|
|
583
|
-
if (enableOffset) {
|
|
584
|
-
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
|
|
585
|
-
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
|
|
586
|
-
})
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
const { textStyle, imageStyle, innerStyle } = splitStyle({
|
|
590
|
-
...defaultStyle,
|
|
591
|
-
...styleObj,
|
|
592
|
-
...(isHover ? hoverStyle : null)
|
|
593
|
-
})
|
|
594
|
-
|
|
595
|
-
const needLayout = enableOffset || hasPercentStyle
|
|
732
|
+
const {
|
|
733
|
+
layoutRef,
|
|
734
|
+
layoutStyle,
|
|
735
|
+
layoutProps
|
|
736
|
+
} = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
|
|
596
737
|
|
|
597
738
|
const innerProps = useInnerProps(props, {
|
|
598
739
|
ref: nodeRef,
|
|
599
|
-
|
|
740
|
+
style: { ...innerStyle, ...layoutStyle },
|
|
741
|
+
...layoutProps,
|
|
600
742
|
...(hoverStyle && {
|
|
601
743
|
bindtouchstart: onTouchStart,
|
|
602
744
|
bindtouchend: onTouchEnd
|
|
603
745
|
})
|
|
604
746
|
}, [
|
|
605
|
-
'style',
|
|
606
|
-
'children',
|
|
607
747
|
'hover-start-time',
|
|
608
748
|
'hover-stay-time',
|
|
609
|
-
'
|
|
610
|
-
'hover-class'
|
|
611
|
-
'enable-offset',
|
|
612
|
-
'enable-background-image'
|
|
749
|
+
'hover-style',
|
|
750
|
+
'hover-class'
|
|
613
751
|
], {
|
|
614
752
|
layoutRef
|
|
615
753
|
})
|
|
@@ -617,9 +755,20 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
|
|
|
617
755
|
return (
|
|
618
756
|
<View
|
|
619
757
|
{...innerProps}
|
|
620
|
-
style={{ ...innerStyle, ...transformStyle }}
|
|
621
758
|
>
|
|
622
|
-
{
|
|
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
|
+
}
|
|
623
772
|
</View>
|
|
624
773
|
)
|
|
625
774
|
})
|
|
@@ -627,4 +776,3 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):
|
|
|
627
776
|
_View.displayName = 'mpx-view'
|
|
628
777
|
|
|
629
778
|
export default _View
|
|
630
|
-
|