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