@mpxjs/webpack-plugin 2.10.24 → 2.11.0
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 +4 -1
- package/lib/platform/style/wx/index.js +417 -120
- package/lib/platform/template/wx/component-config/picker.js +0 -6
- package/lib/react/style-helper.js +6 -6
- package/lib/resolver/AddEnvPlugin.js +1 -1
- package/lib/resolver/AddModePlugin.js +1 -1
- package/lib/resolver/ExtendComponentsPlugin.js +68 -0
- package/lib/runtime/components/extends/section-list.mpx +14 -0
- package/lib/runtime/components/react/animationHooks/index.ts +7 -3
- package/lib/runtime/components/react/dist/animationHooks/index.d.ts +0 -2
- package/lib/runtime/components/react/dist/animationHooks/index.js +6 -1
- package/lib/runtime/components/react/dist/event.config.d.ts +2 -6
- package/lib/runtime/components/react/dist/event.config.js +28 -24
- package/lib/runtime/components/react/dist/getInnerListeners.d.ts +1 -1
- package/lib/runtime/components/react/dist/getInnerListeners.js +74 -56
- package/lib/runtime/components/react/dist/mpx-button.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-button.jsx +16 -9
- package/lib/runtime/components/react/dist/mpx-camera.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-camera.jsx +36 -5
- package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +1 -3
- package/lib/runtime/components/react/dist/mpx-canvas/utils.d.ts +1 -1
- package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +3 -4
- package/lib/runtime/components/react/dist/mpx-checkbox.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +8 -9
- package/lib/runtime/components/react/dist/mpx-form.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-form.jsx +5 -5
- package/lib/runtime/components/react/dist/mpx-icon/index.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-image.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-image.jsx +59 -43
- package/lib/runtime/components/react/dist/mpx-inline-text.jsx +13 -4
- package/lib/runtime/components/react/dist/mpx-input.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-input.jsx +16 -8
- package/lib/runtime/components/react/dist/mpx-label.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-label.jsx +5 -6
- package/lib/runtime/components/react/dist/mpx-movable-area.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-movable-view.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +6 -6
- package/lib/runtime/components/react/dist/mpx-nav.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +72 -23
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +4 -0
- package/lib/runtime/components/react/dist/mpx-picker-view/index.d.ts +1 -1
- package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +10 -14
- package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.js +0 -5
- package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts +1 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +34 -14
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.jsx +4 -5
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +3 -5
- package/lib/runtime/components/react/dist/mpx-popup/index.d.ts +5 -4
- package/lib/runtime/components/react/dist/mpx-popup/index.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-progress.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-progress.jsx +1 -3
- package/lib/runtime/components/react/dist/mpx-radio-group.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +3 -4
- package/lib/runtime/components/react/dist/mpx-radio.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-radio.jsx +8 -9
- package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +1 -3
- package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +6 -6
- package/lib/runtime/components/react/dist/mpx-section-list.d.ts +51 -0
- package/lib/runtime/components/react/dist/mpx-section-list.jsx +376 -0
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +37 -19
- package/lib/runtime/components/react/dist/mpx-simple-view.d.ts +4 -1
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -4
- package/lib/runtime/components/react/dist/mpx-slider.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-slider.jsx +6 -7
- package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +5 -5
- package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +6 -6
- package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +5 -5
- package/lib/runtime/components/react/dist/mpx-swiper.d.ts +1 -2
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +4 -8
- package/lib/runtime/components/react/dist/mpx-switch.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-switch.jsx +1 -3
- package/lib/runtime/components/react/dist/mpx-text.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-text.jsx +43 -25
- package/lib/runtime/components/react/dist/mpx-video.d.ts +0 -2
- package/lib/runtime/components/react/dist/mpx-video.jsx +4 -5
- package/lib/runtime/components/react/dist/mpx-view.d.ts +2 -2
- package/lib/runtime/components/react/dist/mpx-view.jsx +214 -114
- package/lib/runtime/components/react/dist/mpx-web-view.d.ts +2 -1
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +5 -1
- package/lib/runtime/components/react/dist/namedColorSet.d.ts +2 -0
- package/lib/runtime/components/react/dist/namedColorSet.js +149 -0
- package/lib/runtime/components/react/dist/utils.d.ts +71 -70
- package/lib/runtime/components/react/dist/utils.jsx +1295 -456
- package/lib/runtime/components/react/event.config.ts +32 -25
- package/lib/runtime/components/react/getInnerListeners.ts +84 -60
- package/lib/runtime/components/react/mpx-button.tsx +18 -18
- package/lib/runtime/components/react/mpx-camera.tsx +40 -8
- package/lib/runtime/components/react/mpx-canvas/index.tsx +5 -7
- package/lib/runtime/components/react/mpx-canvas/utils.tsx +3 -1
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +2 -8
- package/lib/runtime/components/react/mpx-checkbox.tsx +9 -13
- package/lib/runtime/components/react/mpx-form.tsx +6 -8
- package/lib/runtime/components/react/mpx-icon/index.tsx +1 -5
- package/lib/runtime/components/react/mpx-image.tsx +66 -58
- package/lib/runtime/components/react/mpx-inline-text.tsx +13 -4
- package/lib/runtime/components/react/mpx-input.tsx +19 -12
- package/lib/runtime/components/react/mpx-label.tsx +6 -10
- package/lib/runtime/components/react/mpx-movable-area.tsx +3 -5
- package/lib/runtime/components/react/mpx-movable-view.tsx +7 -9
- package/lib/runtime/components/react/mpx-nav.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker/index.tsx +100 -29
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +3 -3
- package/lib/runtime/components/react/mpx-picker/selector.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker/type.ts +4 -0
- package/lib/runtime/components/react/mpx-picker-view/index.tsx +17 -24
- package/lib/runtime/components/react/mpx-picker-view/pickerVIewContext.ts +0 -9
- package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +44 -23
- package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItem.tsx +1 -9
- package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItemLite.tsx +0 -9
- package/lib/runtime/components/react/mpx-popup/index.tsx +7 -3
- package/lib/runtime/components/react/mpx-popup/popupBase.tsx +3 -2
- package/lib/runtime/components/react/mpx-progress.tsx +0 -6
- package/lib/runtime/components/react/mpx-radio-group.tsx +2 -8
- package/lib/runtime/components/react/mpx-radio.tsx +9 -13
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +0 -6
- package/lib/runtime/components/react/mpx-scroll-view.tsx +7 -9
- package/lib/runtime/components/react/mpx-section-list.tsx +557 -0
- package/lib/runtime/components/react/mpx-simple-text.tsx +36 -25
- package/lib/runtime/components/react/mpx-simple-view.tsx +17 -5
- package/lib/runtime/components/react/mpx-slider.tsx +15 -13
- package/lib/runtime/components/react/mpx-sticky-header.tsx +6 -8
- package/lib/runtime/components/react/mpx-sticky-section.tsx +7 -9
- package/lib/runtime/components/react/mpx-swiper-item.tsx +6 -7
- package/lib/runtime/components/react/mpx-swiper.tsx +5 -11
- package/lib/runtime/components/react/mpx-switch.tsx +0 -6
- package/lib/runtime/components/react/mpx-text.tsx +45 -36
- package/lib/runtime/components/react/mpx-video.tsx +3 -8
- package/lib/runtime/components/react/mpx-view.tsx +235 -129
- package/lib/runtime/components/react/mpx-web-view.tsx +12 -6
- package/lib/runtime/components/react/namedColorSet.ts +150 -0
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +21 -1
- package/lib/runtime/components/react/types/global.d.ts +1 -0
- package/lib/runtime/components/react/utils.tsx +1352 -550
- package/lib/runtime/i18n.wxs +15 -9
- package/lib/style-compiler/strip-conditional.js +19 -4
- package/lib/template-compiler/compiler.js +6 -0
- package/package.json +6 -6
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
* ✔ hover-start-time
|
|
5
5
|
* ✔ hover-stay-time
|
|
6
6
|
*/
|
|
7
|
-
import { View,
|
|
8
|
-
import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, createElement } from 'react'
|
|
7
|
+
import { View, NativeSyntheticEvent, ViewProps, ImageStyle, StyleSheet, Image, LayoutChangeEvent } from 'react-native'
|
|
8
|
+
import { useRef, useState, useEffect, useMemo, forwardRef, ReactNode, JSX, createElement } from 'react'
|
|
9
9
|
import useInnerProps from './getInnerListeners'
|
|
10
10
|
import Animated from 'react-native-reanimated'
|
|
11
11
|
import useAnimationHooks, { AnimationType } from './animationHooks/index'
|
|
12
12
|
import type { AnimationProp } from './animationHooks/utils'
|
|
13
13
|
import { ExtendedViewStyle } from './types/common'
|
|
14
14
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
15
|
-
import { parseUrl,
|
|
16
|
-
import {
|
|
15
|
+
import { parseUrl, percentRegExp, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHover, useTextPassThrough } from './utils'
|
|
16
|
+
import { TextPassThroughContextValue } from './context'
|
|
17
|
+
import { error, warn, hasOwn } from '@mpxjs/utils'
|
|
17
18
|
import * as perf from '@mpxjs/perf'
|
|
18
19
|
import LinearGradient from 'react-native-linear-gradient'
|
|
19
20
|
import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
|
|
@@ -27,10 +28,9 @@ export interface _ViewProps extends ViewProps {
|
|
|
27
28
|
'hover-start-time'?: number
|
|
28
29
|
'hover-stay-time'?: number
|
|
29
30
|
'enable-background'?: boolean
|
|
31
|
+
'enable-text-pass-through'?: boolean
|
|
30
32
|
'enable-var'?: boolean
|
|
31
33
|
'enable-fast-image'?: boolean
|
|
32
|
-
'external-var-context'?: Record<string, any>
|
|
33
|
-
'parent-font-size'?: number
|
|
34
34
|
'parent-width'?: number
|
|
35
35
|
'parent-height'?: number
|
|
36
36
|
'enable-animation'?: boolean | AnimationType
|
|
@@ -41,8 +41,6 @@ export interface _ViewProps extends ViewProps {
|
|
|
41
41
|
catchtransitionend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
type Handler = (...args: any[]) => void
|
|
45
|
-
|
|
46
44
|
type Size = {
|
|
47
45
|
width: number
|
|
48
46
|
height: number
|
|
@@ -84,12 +82,16 @@ type ImageProps = {
|
|
|
84
82
|
style: ImageStyle,
|
|
85
83
|
src?: string,
|
|
86
84
|
source?: { uri: string },
|
|
87
|
-
colors
|
|
85
|
+
colors?: Array<string>,
|
|
88
86
|
locations?: Array<number>
|
|
89
87
|
angle?: number
|
|
90
88
|
resizeMode?: 'cover' | 'stretch'
|
|
91
89
|
}
|
|
92
90
|
|
|
91
|
+
type LinearImageProps = ImageProps & {
|
|
92
|
+
colors: Array<string>
|
|
93
|
+
}
|
|
94
|
+
|
|
93
95
|
const linearMap = new Map([
|
|
94
96
|
['top', 0],
|
|
95
97
|
['bottom', 180],
|
|
@@ -97,6 +99,19 @@ const linearMap = new Map([
|
|
|
97
99
|
['right', 90]
|
|
98
100
|
])
|
|
99
101
|
|
|
102
|
+
const FLEX_DEFAULT_STYLE: ExtendedViewStyle = {
|
|
103
|
+
flexDirection: 'row',
|
|
104
|
+
flexBasis: 'auto',
|
|
105
|
+
flexShrink: 1,
|
|
106
|
+
flexWrap: 'nowrap'
|
|
107
|
+
}
|
|
108
|
+
// 用户传入 flex shorthand 时使用的精简版(裁掉 flexBasis/flexShrink)
|
|
109
|
+
// 避免 number 形式 flex:1 被 default flexBasis:'auto' 反向覆盖
|
|
110
|
+
const FLEX_DEFAULT_STYLE_TRIMMED: ExtendedViewStyle = {
|
|
111
|
+
flexDirection: 'row',
|
|
112
|
+
flexWrap: 'nowrap'
|
|
113
|
+
}
|
|
114
|
+
|
|
100
115
|
// 对角线角度
|
|
101
116
|
const diagonalAngleMap: Record<string, (width: number, height: number) => any> = {
|
|
102
117
|
'top right': (width: number, height: number) => {
|
|
@@ -122,24 +137,36 @@ function radToAngle (r: number) {
|
|
|
122
137
|
return r * 180 / Math.PI
|
|
123
138
|
}
|
|
124
139
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
140
|
+
// === linear-gradient 解析相关正则(模块级,一次创建) ===
|
|
141
|
+
// CSS <angle> 支持 deg/turn/rad/grad 四种单位,统一归一为 deg
|
|
142
|
+
// https://www.w3.org/TR/css-values-3/#angles
|
|
143
|
+
const angleRegExp = /^\s*(-?\d+(?:\.\d+)?)(deg|turn|rad|grad)\b/
|
|
144
|
+
const gradientToRegExp = /^to\b\s*/
|
|
145
|
+
// 入口形态:仅在含 linear-gradient 时走解析;提取括号内内容
|
|
146
|
+
const linearGradientRegExp = /linear-gradient\((.*)\)/
|
|
147
|
+
// 顶层逗号切分(忽略 () / # 内部的逗号)
|
|
148
|
+
const topLevelCommaRegExp = /,(?![^(#]*\))/
|
|
149
|
+
// 色标内空白切分(忽略色函数里的逗号边界)
|
|
150
|
+
const stopWhitespaceRegExp = /(?<!,)\s+/
|
|
151
|
+
// 色标位置仅支持 `<n>%` 或裸 `0`(CSS 允许 0 作为唯一无单位 length)
|
|
152
|
+
// 其它单位(px/rpx/em/vw/...)当前无法在不依赖 layout 的情况下归一为百分比,统一拒绝
|
|
153
|
+
const validStopPosRegExp = /^-?\d+(?:\.\d+)?%$|^0$/
|
|
154
|
+
// color hint 检测:色标 token 仅含一个分量且以数字/正负号/小数点开头
|
|
155
|
+
const colorHintLeadingRegExp = /^[-+.\d]/
|
|
156
|
+
|
|
157
|
+
function normalizeAngle (raw: string): number | undefined {
|
|
158
|
+
const m = raw.match(angleRegExp)
|
|
159
|
+
if (!m) return undefined
|
|
160
|
+
const n = +m[1]
|
|
161
|
+
switch (m[2]) {
|
|
162
|
+
case 'turn': return n * 360
|
|
163
|
+
case 'rad': return radToAngle(n)
|
|
164
|
+
case 'grad': return n * 0.9
|
|
165
|
+
default: return n // deg
|
|
128
166
|
}
|
|
129
167
|
}
|
|
130
168
|
|
|
131
|
-
const
|
|
132
|
-
['backgroundSize', 'backgroundPosition'].forEach(name => {
|
|
133
|
-
if (style[name] && typeof style[name] === 'string') {
|
|
134
|
-
if (style[name].trim()) {
|
|
135
|
-
style[name] = style[name].split(' ')
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
return style
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const isPercent = (val: string | number | undefined): val is string => typeof val === 'string' && PERCENT_REGEX.test(val)
|
|
169
|
+
const isPercent = (val: string | number | undefined): val is string => typeof val === 'string' && percentRegExp.test(val)
|
|
143
170
|
|
|
144
171
|
const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val)
|
|
145
172
|
|
|
@@ -261,12 +288,12 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
|
|
|
261
288
|
// 枚举值
|
|
262
289
|
if (typeof width === 'string' && ['cover', 'contain'].includes(width)) {
|
|
263
290
|
if (layoutInfo && imageSize) {
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
// 容器宽高比
|
|
267
|
-
if ((
|
|
291
|
+
const containerRatio = layoutWidth / layoutHeight
|
|
292
|
+
const imageRatio = imageSizeWidth / imageSizeHeight
|
|
293
|
+
// 容器宽高比 小于等于 图片宽高比:contain 按宽缩放,cover 按高缩放
|
|
294
|
+
if ((containerRatio <= imageRatio && (width as string) === 'contain') || (containerRatio >= imageRatio && (width as string) === 'cover')) {
|
|
268
295
|
dimensions = calculateSize(layoutWidth as number, imageSizeHeight / imageSizeWidth, true) as Size
|
|
269
|
-
} else if ((
|
|
296
|
+
} else if ((containerRatio > imageRatio && (width as string) === 'contain') || (containerRatio < imageRatio && (width as string) === 'cover')) {
|
|
270
297
|
dimensions = calculateSize(layoutHeight as number, imageSizeWidth / imageSizeHeight) as Size
|
|
271
298
|
}
|
|
272
299
|
}
|
|
@@ -325,7 +352,16 @@ function linearGradient (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
|
|
|
325
352
|
if (type !== 'linear') return
|
|
326
353
|
|
|
327
354
|
// 角度计算
|
|
328
|
-
|
|
355
|
+
// 注意:不要用 `linearMap.get(direction) || ...`,因为 'top' 映射为 0 是 falsy 值,
|
|
356
|
+
// 会被误判为未命中并落到默认 180deg
|
|
357
|
+
let angle: number
|
|
358
|
+
if (linearMap.has(direction)) {
|
|
359
|
+
angle = linearMap.get(direction) as number
|
|
360
|
+
} else {
|
|
361
|
+
const normalized = normalizeAngle(direction)
|
|
362
|
+
angle = normalized !== undefined ? normalized : 180
|
|
363
|
+
}
|
|
364
|
+
angle = angle % 360
|
|
329
365
|
|
|
330
366
|
// 对角线角度计算
|
|
331
367
|
if (layoutInfo && diagonalAngleMap[direction] && imageSize && linearInfo) {
|
|
@@ -339,16 +375,29 @@ function linearGradient (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
|
|
|
339
375
|
}
|
|
340
376
|
|
|
341
377
|
const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) => {
|
|
342
|
-
|
|
378
|
+
const { type } = preImageInfo
|
|
343
379
|
const imageProps: ImageProps = {
|
|
344
|
-
resizeMode: 'cover',
|
|
345
380
|
style: {
|
|
346
381
|
position: 'absolute'
|
|
347
382
|
// ...StyleSheet.absoluteFillObject
|
|
348
|
-
}
|
|
349
|
-
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (type === 'image') {
|
|
387
|
+
imageProps.resizeMode = 'cover'
|
|
388
|
+
} else {
|
|
389
|
+
imageProps.colors = []
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo)
|
|
393
|
+
if (preImageInfo.backgroundPosition.length) {
|
|
394
|
+
backgroundPosition(imageProps, preImageInfo, imageSize, layoutInfo)
|
|
395
|
+
}
|
|
396
|
+
if (type === 'image') {
|
|
397
|
+
backgroundImage(imageProps, preImageInfo)
|
|
398
|
+
} else {
|
|
399
|
+
linearGradient(imageProps, preImageInfo, imageSize, layoutInfo)
|
|
350
400
|
}
|
|
351
|
-
applyHandlers([backgroundSize, backgroundImage, backgroundPosition, linearGradient], [imageProps, preImageInfo, imageSize, layoutInfo])
|
|
352
401
|
|
|
353
402
|
return imageProps
|
|
354
403
|
}
|
|
@@ -456,23 +505,58 @@ function calcSteps (startVal: number, endVal: number, len: number) {
|
|
|
456
505
|
return newArr
|
|
457
506
|
}
|
|
458
507
|
|
|
459
|
-
|
|
460
|
-
|
|
508
|
+
// 返回值约定:
|
|
509
|
+
// - LinearInfo 解析成功
|
|
510
|
+
// - null 已识别为 linear-gradient 但内部已通过 error/warn 报错,外部不要再报
|
|
511
|
+
// - undefined 不是 linear-gradient 形态,外部按"不支持的 background-image"处理
|
|
512
|
+
function parseLinearGradient (text: string): LinearInfo | null | undefined {
|
|
513
|
+
let linearText = text.trim().match(linearGradientRegExp)?.[1]
|
|
461
514
|
if (!linearText) return
|
|
462
515
|
|
|
463
|
-
//
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
516
|
+
// 多重渐变 / 多重背景:linearGradientRegExp 用了贪婪 `.*`,多渐变时括号内
|
|
517
|
+
// 会贪到下一段 `linear-gradient(`,单段则一定不含;用 includes 一次判断即可
|
|
518
|
+
if (linearText.includes('linear-gradient(')) {
|
|
519
|
+
error(`[mpx-view] background-image 暂不支持多重渐变 (multi gradients),已丢弃,原值: ${text}`)
|
|
520
|
+
return null
|
|
468
521
|
}
|
|
469
522
|
|
|
470
523
|
// 把 0deg, red 10%, blue 20% 解析为 ['0deg', 'red, 10%', 'blue, 20%']
|
|
471
|
-
|
|
524
|
+
if (gradientToRegExp.test(linearText)) {
|
|
525
|
+
linearText = linearText.replace(gradientToRegExp, '')
|
|
526
|
+
} else if (!angleRegExp.test(linearText)) {
|
|
527
|
+
linearText = '180deg ,' + linearText
|
|
528
|
+
}
|
|
529
|
+
const [direction, ...colorList] = linearText.split(topLevelCommaRegExp)
|
|
472
530
|
// 记录需要填充起点的起始位置
|
|
473
531
|
let startIdx = 0; let startVal = 0
|
|
474
532
|
// 把 ['red, 10%', 'blue, 20%']解析为 [[red, 10%], [blue, 20%]]
|
|
475
|
-
|
|
533
|
+
// 双位置语法展开:['red', '0%', '50%'] → [['red', '0%'], ['red', '50%']]
|
|
534
|
+
// 等价于 CSS Images Level 4 中 `red 0% 50%` ≡ `red 0%, red 50%`
|
|
535
|
+
// 同步对不支持的写法做拦截:color hint(仅一个位置 token)、非百分比位置(px/rpx 等)
|
|
536
|
+
const linearInfo = colorList
|
|
537
|
+
.map(item => item.trim().split(stopWhitespaceRegExp))
|
|
538
|
+
.reduce<string[][]>((acc, parts) => {
|
|
539
|
+
// color hint: 例如 `linear-gradient(red, 30%, blue)` 中的 `30%`
|
|
540
|
+
// 该 token 仅含一个位置值、无颜色;当前实现无法做颜色采样,直接丢弃
|
|
541
|
+
if (parts.length === 1 && colorHintLeadingRegExp.test(parts[0])) {
|
|
542
|
+
warn(`[mpx-view] linear-gradient 暂不支持 color hint 写法 [${parts[0]}],已丢弃该色标`)
|
|
543
|
+
return acc
|
|
544
|
+
}
|
|
545
|
+
const [color, ...positions] = parts
|
|
546
|
+
if (positions.length === 0) {
|
|
547
|
+
acc.push([color])
|
|
548
|
+
} else {
|
|
549
|
+
for (const pos of positions) {
|
|
550
|
+
if (!validStopPosRegExp.test(pos)) {
|
|
551
|
+
warn(`[mpx-view] linear-gradient 色标位置仅支持百分比 [${color} ${pos}] 已丢弃位置,仅保留颜色`)
|
|
552
|
+
acc.push([color])
|
|
553
|
+
} else {
|
|
554
|
+
acc.push([color, pos])
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return acc
|
|
559
|
+
}, [])
|
|
476
560
|
.reduce<LinearInfo>((prev, cur, idx, self) => {
|
|
477
561
|
const { colors, locations } = prev
|
|
478
562
|
const [color, val] = cur
|
|
@@ -502,12 +586,18 @@ function parseLinearGradient (text: string): LinearInfo | undefined {
|
|
|
502
586
|
return prev
|
|
503
587
|
}, { colors: [], locations: [] })
|
|
504
588
|
|
|
589
|
+
// 色标全部被丢弃或不足以构成渐变(至少 2 个颜色),降级返回
|
|
590
|
+
if (linearInfo.colors.length < 2) {
|
|
591
|
+
error(`[mpx-view] linear-gradient 至少需要 2 个有效色标,已丢弃,原值: ${text}`)
|
|
592
|
+
return null
|
|
593
|
+
}
|
|
594
|
+
|
|
505
595
|
return extendObject({}, linearInfo, {
|
|
506
596
|
direction: direction.trim()
|
|
507
597
|
})
|
|
508
598
|
}
|
|
509
599
|
|
|
510
|
-
function parseBgImage (text
|
|
600
|
+
function parseBgImage (text?: string): {
|
|
511
601
|
linearInfo?: LinearInfo
|
|
512
602
|
direction?: string
|
|
513
603
|
type?: 'image' | 'linear'
|
|
@@ -519,13 +609,21 @@ function parseBgImage (text: string): {
|
|
|
519
609
|
if (src) return { src, type: 'image' }
|
|
520
610
|
|
|
521
611
|
const linearInfo = parseLinearGradient(text)
|
|
522
|
-
if (!linearInfo)
|
|
612
|
+
if (!linearInfo) {
|
|
613
|
+
// null 表示 parseLinearGradient 内部已报错,外部不要重复;undefined 才属于未识别形态
|
|
614
|
+
if (linearInfo === undefined) {
|
|
615
|
+
error(`[mpx-view] background-image 暂不支持 ${text},已丢弃,仅支持 url(...) / linear-gradient(...)。`)
|
|
616
|
+
}
|
|
617
|
+
return {}
|
|
618
|
+
}
|
|
523
619
|
return {
|
|
524
620
|
linearInfo,
|
|
525
621
|
type: 'linear'
|
|
526
622
|
}
|
|
527
623
|
}
|
|
528
624
|
|
|
625
|
+
export const __parseBgImageForTest = (text?: string): any => parseBgImage(text)
|
|
626
|
+
|
|
529
627
|
function normalizeBackgroundSize (
|
|
530
628
|
backgroundSize: NonNullable<ExtendedViewStyle['backgroundSize']>,
|
|
531
629
|
type: 'image' | 'linear' | undefined
|
|
@@ -546,19 +644,6 @@ function normalizeBackgroundSize (
|
|
|
546
644
|
})
|
|
547
645
|
}
|
|
548
646
|
|
|
549
|
-
function preParseImage (imageStyle?: ExtendedViewStyle) {
|
|
550
|
-
const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = normalizeStyle(imageStyle) || {}
|
|
551
|
-
const { type, src, linearInfo } = parseBgImage(backgroundImage)
|
|
552
|
-
|
|
553
|
-
return {
|
|
554
|
-
src,
|
|
555
|
-
linearInfo,
|
|
556
|
-
type,
|
|
557
|
-
sizeList: normalizeBackgroundSize(backgroundSize, type),
|
|
558
|
-
backgroundPosition: normalizeBackgroundPosition(backgroundPosition)
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
647
|
function isDiagonalAngle (linearInfo?: LinearInfo): boolean {
|
|
563
648
|
return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction])
|
|
564
649
|
}
|
|
@@ -583,21 +668,48 @@ function inheritStyle (innerStyle: ExtendedViewStyle = {}) {
|
|
|
583
668
|
}
|
|
584
669
|
|
|
585
670
|
function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<string, any>, enableFastImage?: boolean) {
|
|
586
|
-
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
const
|
|
671
|
+
const backgroundImage = imageStyle?.backgroundImage
|
|
672
|
+
const backgroundSize = imageStyle?.backgroundSize
|
|
673
|
+
const backgroundPosition = imageStyle?.backgroundPosition
|
|
674
|
+
const parsedImageInfo = useMemo(() => parseBgImage(backgroundImage), [backgroundImage])
|
|
675
|
+
const { src, type } = parsedImageInfo
|
|
676
|
+
const backgroundSizeKey = Array.isArray(backgroundSize) ? backgroundSize.join('|') : backgroundSize
|
|
677
|
+
const sizeList = useMemo(
|
|
678
|
+
() => normalizeBackgroundSize(backgroundSize ?? ['auto'], type),
|
|
679
|
+
[backgroundSizeKey, type]
|
|
680
|
+
)
|
|
681
|
+
const backgroundPositionKey = Array.isArray(backgroundPosition) ? backgroundPosition.join('|') : backgroundPosition
|
|
682
|
+
const bgPosition = useMemo(
|
|
683
|
+
() => normalizeBackgroundPosition(backgroundPosition ?? [0, 0]),
|
|
684
|
+
[backgroundPositionKey]
|
|
685
|
+
)
|
|
686
|
+
const preImageInfo: PreImageInfo = useMemo(
|
|
687
|
+
() => extendObject({}, parsedImageInfo, { sizeList, backgroundPosition: bgPosition }),
|
|
688
|
+
[parsedImageInfo, sizeList, bgPosition]
|
|
689
|
+
)
|
|
590
690
|
|
|
591
691
|
// 判断是否可挂载onLayout
|
|
592
692
|
const { needLayout, needImageSize } = checkNeedLayout(preImageInfo)
|
|
593
693
|
|
|
594
694
|
const [show, setShow] = useState<boolean>(((type === 'image' && !!src) || type === 'linear') && !needLayout && !needImageSize)
|
|
595
|
-
const [,
|
|
596
|
-
const [, setImageSizeHeight] = useState<number | null>(null)
|
|
597
|
-
const [, setLayoutInfoWidth] = useState<number | null>(null)
|
|
598
|
-
const [, setLayoutInfoHeight] = useState<number | null>(null)
|
|
695
|
+
const [version, setVersion] = useState(0)
|
|
599
696
|
const sizeInfo = useRef<Size | null>(null)
|
|
600
697
|
const layoutInfo = useRef<Size | null>(null)
|
|
698
|
+
const sizeCacheRef = useRef<Map<string, Size>>(new Map())
|
|
699
|
+
// sizeInfo / layoutInfo / setVersion 都是稳定引用,闭包整个生命周期只分配一次
|
|
700
|
+
const { bumpVersion, setImageSize, setLayoutInfo } = useMemo(() => ({
|
|
701
|
+
bumpVersion: () => setVersion(version => version + 1),
|
|
702
|
+
setImageSize: (width: number, height: number) => {
|
|
703
|
+
if (sizeInfo.current?.width === width && sizeInfo.current?.height === height) return false
|
|
704
|
+
sizeInfo.current = { width, height }
|
|
705
|
+
return true
|
|
706
|
+
},
|
|
707
|
+
setLayoutInfo: (width: number, height: number) => {
|
|
708
|
+
if (layoutInfo.current?.width === width && layoutInfo.current?.height === height) return false
|
|
709
|
+
layoutInfo.current = { width, height }
|
|
710
|
+
return true
|
|
711
|
+
}
|
|
712
|
+
}), [])
|
|
601
713
|
useEffect(() => {
|
|
602
714
|
sizeInfo.current = null
|
|
603
715
|
if (type === 'linear') {
|
|
@@ -615,54 +727,55 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
|
|
|
615
727
|
}
|
|
616
728
|
|
|
617
729
|
if (needImageSize) {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
730
|
+
const cached = sizeCacheRef.current.get(src)
|
|
731
|
+
if (cached) {
|
|
732
|
+
const imageSizeChanged = setImageSize(cached.width, cached.height)
|
|
733
|
+
if (!needLayout || layoutInfo.current) {
|
|
734
|
+
imageSizeChanged && bumpVersion()
|
|
735
|
+
setShow(true)
|
|
622
736
|
}
|
|
737
|
+
return
|
|
738
|
+
}
|
|
739
|
+
let cancelled = false
|
|
740
|
+
Image.getSize(src, (width, height) => {
|
|
741
|
+
// cache 仍然填上,避免下次同 src 再发一次请求
|
|
742
|
+
sizeCacheRef.current.set(src, { width, height })
|
|
743
|
+
if (cancelled) return
|
|
744
|
+
const imageSizeChanged = setImageSize(width, height)
|
|
623
745
|
// 1. 当需要绑定onLayout 2. 获取到布局信息
|
|
624
746
|
if (!needLayout || layoutInfo.current) {
|
|
625
|
-
|
|
626
|
-
setImageSizeHeight(height)
|
|
627
|
-
if (layoutInfo.current) {
|
|
628
|
-
setLayoutInfoWidth(layoutInfo.current.width)
|
|
629
|
-
setLayoutInfoHeight(layoutInfo.current.height)
|
|
630
|
-
}
|
|
747
|
+
imageSizeChanged && bumpVersion()
|
|
631
748
|
setShow(true)
|
|
632
749
|
}
|
|
633
750
|
})
|
|
751
|
+
return () => { cancelled = true }
|
|
634
752
|
}
|
|
635
753
|
// type 添加type 处理无渐变 有渐变的场景
|
|
636
|
-
}, [src, type])
|
|
754
|
+
}, [src, type, needLayout, needImageSize])
|
|
755
|
+
|
|
756
|
+
const imageProps = useMemo(
|
|
757
|
+
() => imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size),
|
|
758
|
+
[preImageInfo, version]
|
|
759
|
+
)
|
|
637
760
|
|
|
638
761
|
if (!type) return null
|
|
639
762
|
|
|
640
763
|
const onLayout = (res: LayoutChangeEvent) => {
|
|
641
764
|
const { width, height } = res?.nativeEvent?.layout || {}
|
|
642
|
-
layoutInfo.current
|
|
643
|
-
|
|
644
|
-
height
|
|
645
|
-
}
|
|
765
|
+
// layoutInfo 总是更新,Image.getSize 回调要靠 layoutInfo.current 决定是否 setShow
|
|
766
|
+
let changed = setLayoutInfo(width, height)
|
|
646
767
|
if (!needImageSize) {
|
|
647
|
-
setLayoutInfoWidth(width)
|
|
648
|
-
setLayoutInfoHeight(height)
|
|
649
768
|
// 有渐变角度的时候,才触发渲染组件
|
|
650
769
|
if (type === 'linear') {
|
|
651
|
-
|
|
652
|
-
width: calcPercent(sizeList[0] as NumberVal, width),
|
|
653
|
-
height: calcPercent(sizeList[1] as NumberVal, height)
|
|
654
|
-
}
|
|
655
|
-
setImageSizeWidth(sizeInfo.current.width)
|
|
656
|
-
setImageSizeHeight(sizeInfo.current.height)
|
|
770
|
+
changed = setImageSize(calcPercent(sizeList[0] as NumberVal, width), calcPercent(sizeList[1] as NumberVal, height)) || changed
|
|
657
771
|
}
|
|
772
|
+
changed && bumpVersion()
|
|
658
773
|
setShow(true)
|
|
659
774
|
} else if (sizeInfo.current) {
|
|
660
|
-
|
|
661
|
-
setLayoutInfoHeight(height)
|
|
662
|
-
setImageSizeWidth(sizeInfo.current.width)
|
|
663
|
-
setImageSizeHeight(sizeInfo.current.height)
|
|
775
|
+
changed && bumpVersion()
|
|
664
776
|
setShow(true)
|
|
665
777
|
}
|
|
778
|
+
// needImageSize && !sizeInfo.current:等 Image.getSize 回调里 setShow(true),此处不触发渲染
|
|
666
779
|
}
|
|
667
780
|
|
|
668
781
|
const backgroundProps: ViewProps = extendObject({ key: 'backgroundImage' }, needLayout ? { onLayout } : {},
|
|
@@ -670,33 +783,33 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
|
|
|
670
783
|
)
|
|
671
784
|
|
|
672
785
|
return createElement(View, backgroundProps,
|
|
673
|
-
show && type === 'linear' && createElement(LinearGradient, extendObject({ useAngle: true },
|
|
674
|
-
show && type === 'image' && renderImage(
|
|
786
|
+
show && type === 'linear' && createElement(LinearGradient, extendObject({ useAngle: true }, imageProps as LinearImageProps)),
|
|
787
|
+
show && type === 'image' && renderImage(imageProps, enableFastImage)
|
|
675
788
|
)
|
|
676
789
|
}
|
|
677
790
|
|
|
678
791
|
interface WrapChildrenConfig {
|
|
679
792
|
hasVarDec: boolean
|
|
680
793
|
enableBackground?: boolean
|
|
681
|
-
textStyle?: TextStyle
|
|
682
794
|
backgroundStyle?: ExtendedViewStyle
|
|
683
795
|
varContext?: Record<string, any>
|
|
684
|
-
|
|
685
|
-
textPassThrough?: ReturnType<typeof useTextPassThroughValue>
|
|
796
|
+
textPassThrough?: TextPassThroughContextValue | null
|
|
686
797
|
innerStyle?: Record<string, any>
|
|
687
798
|
enableFastImage?: boolean
|
|
688
799
|
}
|
|
689
800
|
|
|
690
801
|
function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, backgroundStyle, varContext, textPassThrough, innerStyle, enableFastImage }: WrapChildrenConfig) {
|
|
691
|
-
const children = wrapChildren(props, {
|
|
802
|
+
const children = wrapChildren(props.children, {
|
|
692
803
|
hasVarDec,
|
|
693
804
|
varContext,
|
|
694
805
|
textPassThrough
|
|
695
806
|
})
|
|
696
807
|
|
|
808
|
+
if (!enableBackground) return children
|
|
809
|
+
|
|
697
810
|
return [
|
|
698
811
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
699
|
-
|
|
812
|
+
useWrapImage(backgroundStyle, innerStyle, enableFastImage),
|
|
700
813
|
children
|
|
701
814
|
]
|
|
702
815
|
}
|
|
@@ -716,11 +829,10 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
716
829
|
'hover-start-time': hoverStartTime = 50,
|
|
717
830
|
'hover-stay-time': hoverStayTime = 400,
|
|
718
831
|
'enable-var': enableVar,
|
|
719
|
-
'external-var-context': externalVarContext,
|
|
720
832
|
'enable-background': enableBackground,
|
|
833
|
+
'enable-text-pass-through': enableTextPassThrough,
|
|
721
834
|
'enable-fast-image': enableFastImage,
|
|
722
835
|
'enable-animation': enableAnimation,
|
|
723
|
-
'parent-font-size': parentFontSize,
|
|
724
836
|
'parent-width': parentWidth,
|
|
725
837
|
'parent-height': parentHeight,
|
|
726
838
|
animation,
|
|
@@ -728,20 +840,12 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
728
840
|
bindtransitionend
|
|
729
841
|
} = props
|
|
730
842
|
|
|
731
|
-
// 默认样式
|
|
732
|
-
const defaultStyle: ExtendedViewStyle = style.display === 'flex'
|
|
733
|
-
? {
|
|
734
|
-
flexDirection: 'row',
|
|
735
|
-
flexBasis: 'auto',
|
|
736
|
-
flexShrink: 1,
|
|
737
|
-
flexWrap: 'nowrap'
|
|
738
|
-
}
|
|
739
|
-
: {}
|
|
740
|
-
|
|
741
843
|
const enableHover = !!hoverStyle
|
|
742
844
|
const { isHover, gesture } = useHover({ enableHover, hoverStartTime, hoverStayTime })
|
|
743
845
|
|
|
744
|
-
const styleObj: ExtendedViewStyle =
|
|
846
|
+
const styleObj: ExtendedViewStyle = isHover
|
|
847
|
+
? extendObject({}, style, hoverStyle as ExtendedViewStyle)
|
|
848
|
+
: style
|
|
745
849
|
if (__mpx_perf_framework__) perf.scopeEnd(idProps)
|
|
746
850
|
|
|
747
851
|
// ───── style 阶段 ─────
|
|
@@ -757,14 +861,17 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
757
861
|
setHeight
|
|
758
862
|
} = useTransformStyle(styleObj, {
|
|
759
863
|
enableVar,
|
|
760
|
-
externalVarContext,
|
|
761
|
-
parentFontSize,
|
|
762
864
|
parentWidth,
|
|
763
|
-
parentHeight
|
|
865
|
+
parentHeight,
|
|
866
|
+
// 基于合并后的 styleObj 判断(hover 状态切换 display 也能触发)
|
|
867
|
+
// 用户传 flex shorthand 时使用精简 default,避免 flexBasis/flexShrink 反向覆盖
|
|
868
|
+
defaultStyle: styleObj.display === 'flex'
|
|
869
|
+
? (hasOwn(styleObj, 'flex') ? FLEX_DEFAULT_STYLE_TRIMMED : FLEX_DEFAULT_STYLE)
|
|
870
|
+
: undefined
|
|
764
871
|
})
|
|
765
872
|
|
|
766
873
|
const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle)
|
|
767
|
-
const textPassThrough =
|
|
874
|
+
const textPassThrough = useTextPassThrough(textStyle, textProps, { enableTextPassThrough })
|
|
768
875
|
|
|
769
876
|
enableBackground = enableBackground || !!backgroundStyle
|
|
770
877
|
const enableBackgroundRef = useRef(enableBackground)
|
|
@@ -783,18 +890,16 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
783
890
|
layoutProps
|
|
784
891
|
} = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
|
|
785
892
|
|
|
786
|
-
const viewStyle =
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
: isFunction(bindtransitionend)
|
|
790
|
-
? bindtransitionend
|
|
791
|
-
: undefined
|
|
893
|
+
const viewStyle = layoutStyle
|
|
894
|
+
? extendObject({}, innerStyle, layoutStyle)
|
|
895
|
+
: innerStyle
|
|
792
896
|
const { enableStyleAnimation, animationStyle } = useAnimationHooks({
|
|
793
897
|
layoutRef,
|
|
794
898
|
animation,
|
|
795
899
|
enableAnimation,
|
|
796
900
|
style: viewStyle,
|
|
797
|
-
|
|
901
|
+
catchtransitionend,
|
|
902
|
+
bindtransitionend
|
|
798
903
|
})
|
|
799
904
|
if (__mpx_perf_framework__) perf.scopeEnd(idStyle)
|
|
800
905
|
|
|
@@ -812,15 +917,16 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
812
917
|
}
|
|
813
918
|
),
|
|
814
919
|
[
|
|
815
|
-
'animation',
|
|
816
920
|
'hover-start-time',
|
|
817
921
|
'hover-stay-time',
|
|
818
922
|
'hover-style',
|
|
819
923
|
'hover-class',
|
|
820
|
-
'enable-
|
|
924
|
+
'enable-background',
|
|
821
925
|
'enable-animation',
|
|
822
|
-
'
|
|
823
|
-
'
|
|
926
|
+
'enable-fast-image',
|
|
927
|
+
'animation',
|
|
928
|
+
'catchtransitionend',
|
|
929
|
+
'bindtransitionend'
|
|
824
930
|
],
|
|
825
931
|
{
|
|
826
932
|
layoutRef
|