@mpxjs/webpack-plugin 2.10.17-beta.6 → 2.10.17-beta.7
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/platform/style/wx/index.js +1 -17
- package/lib/runtime/components/react/animationHooks/useTransitionHooks.ts +34 -30
- package/lib/runtime/components/react/animationHooks/utils.ts +3 -2
- package/lib/runtime/components/react/dist/animationHooks/useTransitionHooks.js +38 -33
- package/lib/runtime/components/react/dist/animationHooks/utils.js +3 -2
- package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +6 -5
- package/lib/runtime/components/react/dist/utils.d.ts +2 -1
- package/lib/runtime/components/react/dist/utils.jsx +15 -21
- package/lib/runtime/components/react/mpx-image.tsx +2 -2
- package/lib/runtime/components/react/mpx-swiper.tsx +6 -5
- package/lib/runtime/components/react/utils.tsx +18 -23
- package/package.json +1 -1
|
@@ -139,11 +139,10 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
139
139
|
const type = getValueType(prop)
|
|
140
140
|
const tipsType = (type) => {
|
|
141
141
|
const info = {
|
|
142
|
-
[ValueType.number]: '2rpx,10%,30rpx',
|
|
143
142
|
[ValueType.color]: 'rgb,rgba,hsl,hsla,hwb,named color,#000000',
|
|
144
143
|
[ValueType.enum]: `${SUPPORTED_PROP_VAL_ARR[prop]?.join(',')}`
|
|
145
144
|
}
|
|
146
|
-
tips(`Value of ${prop} in ${selector} should be ${type}
|
|
145
|
+
tips(`Value of ${prop} in ${selector} should be ${type}${info[type] ? `, eg ${info[type]}` : ''}, received [${value}], please check again!`)
|
|
147
146
|
}
|
|
148
147
|
switch (type) {
|
|
149
148
|
case ValueType.number: {
|
|
@@ -549,15 +548,6 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
549
548
|
return { prop, value: values[0].trim() }
|
|
550
549
|
}
|
|
551
550
|
|
|
552
|
-
const formatZIndex = ({ prop, value, selector }, { mode }) => {
|
|
553
|
-
// z-index auto 报错
|
|
554
|
-
if (value === 'auto') {
|
|
555
|
-
error(`Property [${prop}] does not supported [${value}] on ${selector} in ${mode} environment, please check again!`)
|
|
556
|
-
return { prop, value: 0 }
|
|
557
|
-
}
|
|
558
|
-
return { prop, value: value }
|
|
559
|
-
}
|
|
560
|
-
|
|
561
551
|
// const formatBoxShadow = ({ prop, value, selector }, { mode }) => {
|
|
562
552
|
// value = value.trim()
|
|
563
553
|
// if (value === 'none') {
|
|
@@ -623,12 +613,6 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
623
613
|
android: formatFontFamily,
|
|
624
614
|
harmony: formatFontFamily
|
|
625
615
|
},
|
|
626
|
-
{
|
|
627
|
-
test: 'z-index',
|
|
628
|
-
ios: formatZIndex,
|
|
629
|
-
android: formatZIndex,
|
|
630
|
-
harmony: formatZIndex
|
|
631
|
-
},
|
|
632
616
|
// {
|
|
633
617
|
// test: 'box-shadow',
|
|
634
618
|
// ios: formatBoxShadow,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasOwn, dash2hump, error } from '@mpxjs/utils'
|
|
1
|
+
import { hasOwn, dash2hump, error, warn } from '@mpxjs/utils'
|
|
2
2
|
import { useMemo, useRef, useEffect } from 'react'
|
|
3
3
|
import {
|
|
4
4
|
Easing,
|
|
@@ -169,10 +169,11 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
|
|
|
169
169
|
return parseTransitionStyle(originalStyle)
|
|
170
170
|
}, [])
|
|
171
171
|
// ** style prop sharedValue interpolateOutput: SharedValue<InterpolateOutput>
|
|
172
|
-
const { shareValMap, animatedKeys,
|
|
172
|
+
const { shareValMap, animatedKeys, animatedStyleKeys } = useMemo(() => {
|
|
173
173
|
// 记录需要执行动画的 propName
|
|
174
174
|
const animatedKeys = [] as string[]
|
|
175
|
-
|
|
175
|
+
// 有动画样式的 style key(useAnimatedStyle使用)
|
|
176
|
+
const animatedStyleKeys = [] as (string|string[])[]
|
|
176
177
|
const transforms = [] as string[]
|
|
177
178
|
const shareValMap = Object.keys(transitionMap).reduce((valMap, property) => {
|
|
178
179
|
// const { property } = transition || {}
|
|
@@ -189,20 +190,18 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
|
|
|
189
190
|
// console.log(`shareValMap property=${property} defaultVal=${defaultVal}`)
|
|
190
191
|
valMap[property] = makeMutable(defaultVal)
|
|
191
192
|
animatedKeys.push(property)
|
|
192
|
-
|
|
193
|
+
animatedStyleKeys.push(property)
|
|
193
194
|
}
|
|
194
195
|
// console.log('shareValMap = ', valMap)
|
|
195
196
|
return valMap
|
|
196
197
|
}, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
|
|
197
|
-
if (transforms.length)
|
|
198
|
+
if (transforms.length) animatedStyleKeys.push(transforms)
|
|
198
199
|
return {
|
|
199
200
|
shareValMap,
|
|
200
201
|
animatedKeys,
|
|
201
|
-
|
|
202
|
+
animatedStyleKeys
|
|
202
203
|
}
|
|
203
204
|
}, [])
|
|
204
|
-
// 有动画样式的 style key(useAnimatedStyle使用)
|
|
205
|
-
const animatedStyleKeys = useSharedValue(animatedKeysShareVal)
|
|
206
205
|
const runOnJSCallbackRef = useRef({})
|
|
207
206
|
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
|
|
208
207
|
// 根据 animation action 创建&驱动动画
|
|
@@ -228,32 +227,37 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
|
|
|
228
227
|
toVal = `${toVal * 100}%`
|
|
229
228
|
} else if (typeof toVal !== typeof shareVal) {
|
|
230
229
|
// 动画起始值和终态值类型不一致报错提示一下
|
|
231
|
-
|
|
230
|
+
warn(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`)
|
|
232
231
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
232
|
+
if ((toVal === 'auto' && !isNaN(+shareVal)) || (shareVal === 'auto' && !isNaN(+toVal))) {
|
|
233
|
+
// 有 auto 直接赋值不做动画
|
|
234
|
+
shareValMap[key].value = toVal
|
|
235
|
+
} else {
|
|
236
|
+
// console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
|
|
237
|
+
const { delay = 0, duration, easing } = transitionMap[isTransformKey ? 'transform' : key]
|
|
238
|
+
// console.log('animationOptions=', { delay, duration, easing })
|
|
239
|
+
let callback
|
|
240
|
+
if (transitionend && (!isTransformKey || !transformTransitionendDone)) {
|
|
241
|
+
runOnJSCallbackRef.current = {
|
|
242
|
+
animationCallback: (duration: number, finished: boolean, current?: AnimatableValue) => {
|
|
243
|
+
transitionend(finished, current, duration)
|
|
244
|
+
}
|
|
241
245
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
callback = (finished?: boolean, current?: AnimatableValue) => {
|
|
247
|
+
'worklet'
|
|
248
|
+
// 动画结束后设置下一次transformOrigin
|
|
249
|
+
if (finished) {
|
|
250
|
+
runOnJS(runOnJSCallback)('animationCallback', duration, finished, current)
|
|
251
|
+
}
|
|
248
252
|
}
|
|
249
253
|
}
|
|
254
|
+
const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, callback)
|
|
255
|
+
// Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
|
|
256
|
+
if (isTransformKey) {
|
|
257
|
+
transformTransitionendDone = true
|
|
258
|
+
}
|
|
259
|
+
shareValMap[key].value = animation
|
|
250
260
|
}
|
|
251
|
-
const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, callback)
|
|
252
|
-
// Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
|
|
253
|
-
if (isTransformKey) {
|
|
254
|
-
transformTransitionendDone = true
|
|
255
|
-
}
|
|
256
|
-
shareValMap[key].value = animation
|
|
257
261
|
// console.log(`useTransitionHooks, ${key}=`, animation)
|
|
258
262
|
})
|
|
259
263
|
}
|
|
@@ -278,7 +282,7 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
|
|
|
278
282
|
// ** 生成动画样式
|
|
279
283
|
return useAnimatedStyle(() => {
|
|
280
284
|
// console.info(`useAnimatedStyle styles=`, originalStyle)
|
|
281
|
-
return animatedStyleKeys.
|
|
285
|
+
return animatedStyleKeys.reduce((styles, key) => {
|
|
282
286
|
if (Array.isArray(key)) {
|
|
283
287
|
const transformStyle = getTransformObj(originalStyle.transform || [])
|
|
284
288
|
key.forEach((transformKey) => {
|
|
@@ -94,8 +94,9 @@ export const transformInitial: ExtendedViewStyle = {
|
|
|
94
94
|
export const animationAPIInitialValue: ExtendedViewStyle = Object.assign({
|
|
95
95
|
opacity: 1,
|
|
96
96
|
backgroundColor: 'transparent',
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
// fixme 未设置 height 初始值定义了 transition-property height 时把动画高度值把原由子元素撑开的高度给覆盖的问题
|
|
98
|
+
width: 'auto',
|
|
99
|
+
height: 'auto',
|
|
99
100
|
top: 0,
|
|
100
101
|
right: 0,
|
|
101
102
|
bottom: 0,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { hasOwn, dash2hump, error } from '@mpxjs/utils';
|
|
1
|
+
import { hasOwn, dash2hump, error, warn } from '@mpxjs/utils';
|
|
2
2
|
import { useMemo, useRef, useEffect } from 'react';
|
|
3
|
-
import { Easing, makeMutable, runOnJS,
|
|
3
|
+
import { Easing, makeMutable, runOnJS, useAnimatedStyle, cancelAnimation } from 'react-native-reanimated';
|
|
4
4
|
import { easingKey, transitionSupportedProperty, transformInitial, cubicBezierExp, secondRegExp, percentExp, getTransformObj, getUnit, getInitialVal, getAnimation, isTransform } from './utils';
|
|
5
5
|
import { parseValues, useRunOnJSCallback } from '../utils';
|
|
6
6
|
const propName = {
|
|
@@ -141,10 +141,11 @@ export default function useTransitionHooks(props) {
|
|
|
141
141
|
return parseTransitionStyle(originalStyle);
|
|
142
142
|
}, []);
|
|
143
143
|
// ** style prop sharedValue interpolateOutput: SharedValue<InterpolateOutput>
|
|
144
|
-
const { shareValMap, animatedKeys,
|
|
144
|
+
const { shareValMap, animatedKeys, animatedStyleKeys } = useMemo(() => {
|
|
145
145
|
// 记录需要执行动画的 propName
|
|
146
146
|
const animatedKeys = [];
|
|
147
|
-
|
|
147
|
+
// 有动画样式的 style key(useAnimatedStyle使用)
|
|
148
|
+
const animatedStyleKeys = [];
|
|
148
149
|
const transforms = [];
|
|
149
150
|
const shareValMap = Object.keys(transitionMap).reduce((valMap, property) => {
|
|
150
151
|
// const { property } = transition || {}
|
|
@@ -162,21 +163,19 @@ export default function useTransitionHooks(props) {
|
|
|
162
163
|
// console.log(`shareValMap property=${property} defaultVal=${defaultVal}`)
|
|
163
164
|
valMap[property] = makeMutable(defaultVal);
|
|
164
165
|
animatedKeys.push(property);
|
|
165
|
-
|
|
166
|
+
animatedStyleKeys.push(property);
|
|
166
167
|
}
|
|
167
168
|
// console.log('shareValMap = ', valMap)
|
|
168
169
|
return valMap;
|
|
169
170
|
}, {});
|
|
170
171
|
if (transforms.length)
|
|
171
|
-
|
|
172
|
+
animatedStyleKeys.push(transforms);
|
|
172
173
|
return {
|
|
173
174
|
shareValMap,
|
|
174
175
|
animatedKeys,
|
|
175
|
-
|
|
176
|
+
animatedStyleKeys
|
|
176
177
|
};
|
|
177
178
|
}, []);
|
|
178
|
-
// 有动画样式的 style key(useAnimatedStyle使用)
|
|
179
|
-
const animatedStyleKeys = useSharedValue(animatedKeysShareVal);
|
|
180
179
|
const runOnJSCallbackRef = useRef({});
|
|
181
180
|
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
|
|
182
181
|
// 根据 animation action 创建&驱动动画
|
|
@@ -204,32 +203,38 @@ export default function useTransitionHooks(props) {
|
|
|
204
203
|
}
|
|
205
204
|
else if (typeof toVal !== typeof shareVal) {
|
|
206
205
|
// 动画起始值和终态值类型不一致报错提示一下
|
|
207
|
-
|
|
206
|
+
warn(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`);
|
|
208
207
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
let callback;
|
|
213
|
-
if (transitionend && (!isTransformKey || !transformTransitionendDone)) {
|
|
214
|
-
runOnJSCallbackRef.current = {
|
|
215
|
-
animationCallback: (duration, finished, current) => {
|
|
216
|
-
transitionend(finished, current, duration);
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
callback = (finished, current) => {
|
|
220
|
-
'worklet';
|
|
221
|
-
// 动画结束后设置下一次transformOrigin
|
|
222
|
-
if (finished) {
|
|
223
|
-
runOnJS(runOnJSCallback)('animationCallback', duration, finished, current);
|
|
224
|
-
}
|
|
225
|
-
};
|
|
208
|
+
if ((toVal === 'auto' && !isNaN(+shareVal)) || (shareVal === 'auto' && !isNaN(+toVal))) {
|
|
209
|
+
// 有 auto 直接赋值不做动画
|
|
210
|
+
shareValMap[key].value = toVal;
|
|
226
211
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
212
|
+
else {
|
|
213
|
+
// console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
|
|
214
|
+
const { delay = 0, duration, easing } = transitionMap[isTransformKey ? 'transform' : key];
|
|
215
|
+
// console.log('animationOptions=', { delay, duration, easing })
|
|
216
|
+
let callback;
|
|
217
|
+
if (transitionend && (!isTransformKey || !transformTransitionendDone)) {
|
|
218
|
+
runOnJSCallbackRef.current = {
|
|
219
|
+
animationCallback: (duration, finished, current) => {
|
|
220
|
+
transitionend(finished, current, duration);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
callback = (finished, current) => {
|
|
224
|
+
'worklet';
|
|
225
|
+
// 动画结束后设置下一次transformOrigin
|
|
226
|
+
if (finished) {
|
|
227
|
+
runOnJS(runOnJSCallback)('animationCallback', duration, finished, current);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, callback);
|
|
232
|
+
// Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
|
|
233
|
+
if (isTransformKey) {
|
|
234
|
+
transformTransitionendDone = true;
|
|
235
|
+
}
|
|
236
|
+
shareValMap[key].value = animation;
|
|
231
237
|
}
|
|
232
|
-
shareValMap[key].value = animation;
|
|
233
238
|
// console.log(`useTransitionHooks, ${key}=`, animation)
|
|
234
239
|
});
|
|
235
240
|
}
|
|
@@ -254,7 +259,7 @@ export default function useTransitionHooks(props) {
|
|
|
254
259
|
// ** 生成动画样式
|
|
255
260
|
return useAnimatedStyle(() => {
|
|
256
261
|
// console.info(`useAnimatedStyle styles=`, originalStyle)
|
|
257
|
-
return animatedStyleKeys.
|
|
262
|
+
return animatedStyleKeys.reduce((styles, key) => {
|
|
258
263
|
if (Array.isArray(key)) {
|
|
259
264
|
const transformStyle = getTransformObj(originalStyle.transform || []);
|
|
260
265
|
key.forEach((transformKey) => {
|
|
@@ -47,8 +47,9 @@ export const transformInitial = {
|
|
|
47
47
|
export const animationAPIInitialValue = Object.assign({
|
|
48
48
|
opacity: 1,
|
|
49
49
|
backgroundColor: 'transparent',
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
// fixme 未设置 height 初始值定义了 transition-property height 时把动画高度值把原由子元素撑开的高度给覆盖的问题
|
|
51
|
+
width: 'auto',
|
|
52
|
+
height: 'auto',
|
|
52
53
|
top: 0,
|
|
53
54
|
right: 0,
|
|
54
55
|
bottom: 0,
|
|
@@ -16,7 +16,7 @@ import { noop } from '@mpxjs/utils';
|
|
|
16
16
|
import { SvgCssUri } from 'react-native-svg/css';
|
|
17
17
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
18
18
|
import useNodesRef from './useNodesRef';
|
|
19
|
-
import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils';
|
|
19
|
+
import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject, isAndroid } from './utils';
|
|
20
20
|
import Portal from './mpx-portal';
|
|
21
21
|
const DEFAULT_IMAGE_WIDTH = 320;
|
|
22
22
|
const DEFAULT_IMAGE_HEIGHT = 240;
|
|
@@ -104,7 +104,7 @@ const Image = forwardRef((props, ref) => {
|
|
|
104
104
|
setLoaded(true);
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
|
-
const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
107
|
+
const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, isTransformBorderRadiusPercent: isAndroid && !isSvg && !isLayoutMode, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
108
108
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({
|
|
109
109
|
props,
|
|
110
110
|
hasSelfPercent,
|
|
@@ -128,6 +128,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
128
128
|
const moveTranstion = useSharedValue(0);
|
|
129
129
|
const timerId = useRef(0);
|
|
130
130
|
const intervalTimer = props.interval || 500;
|
|
131
|
+
// 记录是否首次
|
|
132
|
+
const isFirstRef = useRef(true);
|
|
131
133
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
132
134
|
const waitForHandlers = flatGesture(waitFor);
|
|
133
135
|
// 判断gesture手势是否需要协同处理、等待手势失败响应
|
|
@@ -355,10 +357,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
355
357
|
};
|
|
356
358
|
}, []);
|
|
357
359
|
function handleSwiperChange(current, pCurrent) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
bindchange && bindchange(eventData);
|
|
361
|
-
}
|
|
360
|
+
const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef });
|
|
361
|
+
bindchange && bindchange(eventData);
|
|
362
362
|
}
|
|
363
363
|
const runOnJSCallbackRef = useRef({
|
|
364
364
|
loop,
|
|
@@ -408,9 +408,10 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
408
408
|
// 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
|
|
409
409
|
useAnimatedReaction(() => currentIndex.value, (newIndex, preIndex) => {
|
|
410
410
|
// 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
|
|
411
|
-
if (newIndex !== preIndex && bindchange) {
|
|
411
|
+
if (newIndex !== preIndex && bindchange && !isFirstRef.current) {
|
|
412
412
|
runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent);
|
|
413
413
|
}
|
|
414
|
+
isFirstRef.current = false;
|
|
414
415
|
});
|
|
415
416
|
useEffect(() => {
|
|
416
417
|
let patchStep = 0;
|
|
@@ -39,8 +39,9 @@ interface TransformStyleConfig {
|
|
|
39
39
|
parentFontSize?: number;
|
|
40
40
|
parentWidth?: number;
|
|
41
41
|
parentHeight?: number;
|
|
42
|
+
isTransformBorderRadiusPercent?: boolean;
|
|
42
43
|
}
|
|
43
|
-
export declare function useTransformStyle(styleObj: Record<string, any> | undefined, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }: TransformStyleConfig): {
|
|
44
|
+
export declare function useTransformStyle(styleObj: Record<string, any> | undefined, { enableVar, isTransformBorderRadiusPercent, externalVarContext, parentFontSize, parentWidth, parentHeight }: TransformStyleConfig): {
|
|
44
45
|
hasVarDec: boolean;
|
|
45
46
|
varContextRef: MutableRefObject<{}>;
|
|
46
47
|
setWidth: Dispatch<SetStateAction<number>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement, createElement } from 'react';
|
|
2
2
|
import { Image } from 'react-native';
|
|
3
|
-
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn
|
|
3
|
+
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils';
|
|
4
4
|
import { VarContext, ScrollViewContext, RouteContext } from './context';
|
|
5
5
|
import { ExpressionParser, parseFunc, ReplaceSource } from './parser';
|
|
6
6
|
import { initialWindowMetrics } from 'react-native-safe-area-context';
|
|
@@ -110,15 +110,17 @@ export function splitStyle(styleObj) {
|
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
const
|
|
114
|
-
translateX: 'width',
|
|
115
|
-
translateY: 'height',
|
|
113
|
+
const radiusPercentRule = {
|
|
116
114
|
borderTopLeftRadius: 'width',
|
|
117
115
|
borderBottomLeftRadius: 'width',
|
|
118
116
|
borderBottomRightRadius: 'width',
|
|
119
117
|
borderTopRightRadius: 'width',
|
|
120
118
|
borderRadius: 'width'
|
|
121
119
|
};
|
|
120
|
+
const selfPercentRule = Object.assign({
|
|
121
|
+
translateX: 'width',
|
|
122
|
+
translateY: 'height'
|
|
123
|
+
}, radiusPercentRule);
|
|
122
124
|
const parentHeightPercentRule = {
|
|
123
125
|
height: true,
|
|
124
126
|
minHeight: true,
|
|
@@ -193,7 +195,7 @@ function transformVar(styleObj, varKeyPaths, varContext, visitOther) {
|
|
|
193
195
|
const resolved = resolveVar(value, varContext);
|
|
194
196
|
if (resolved === undefined) {
|
|
195
197
|
delete target[key];
|
|
196
|
-
|
|
198
|
+
error(`Can not resolve css var at ${varKeyPath.join('.')}:${value}.`);
|
|
197
199
|
return;
|
|
198
200
|
}
|
|
199
201
|
target[key] = resolved;
|
|
@@ -343,15 +345,7 @@ function transformBoxShadow(styleObj) {
|
|
|
343
345
|
return `${res}${idx === 0 ? '' : ' '}${global.__formatValue(i)}`;
|
|
344
346
|
}, '');
|
|
345
347
|
}
|
|
346
|
-
function
|
|
347
|
-
if (!styleObj.zIndex || typeof styleObj.zIndex === 'number')
|
|
348
|
-
return;
|
|
349
|
-
if (styleObj.zIndex === 'auto') {
|
|
350
|
-
error('Property [z-index] does not supported [auto], please check again!');
|
|
351
|
-
styleObj.zIndex = 0;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
|
|
348
|
+
export function useTransformStyle(styleObj = {}, { enableVar, isTransformBorderRadiusPercent, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
|
|
355
349
|
const varStyle = {};
|
|
356
350
|
const unoVarStyle = {};
|
|
357
351
|
const normalStyle = {};
|
|
@@ -403,7 +397,7 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
|
|
|
403
397
|
function calcVisitor({ key, value, keyPath }) {
|
|
404
398
|
if (calcUseRegExp.test(value)) {
|
|
405
399
|
// calc translate & border-radius 的百分比计算
|
|
406
|
-
if (hasOwn(selfPercentRule, key) &&
|
|
400
|
+
if (hasOwn(selfPercentRule, key) && /calc\(\d+%/.test(value)) {
|
|
407
401
|
hasSelfPercent = true;
|
|
408
402
|
percentKeyPaths.push(keyPath.slice());
|
|
409
403
|
}
|
|
@@ -412,7 +406,12 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
|
|
|
412
406
|
}
|
|
413
407
|
function percentVisitor({ key, value, keyPath }) {
|
|
414
408
|
// fixme 去掉 translate & border-radius 的百分比计算
|
|
415
|
-
|
|
409
|
+
// fixme Image 组件 borderRadius 仅支持 number
|
|
410
|
+
if (isTransformBorderRadiusPercent && hasOwn(radiusPercentRule, key) && PERCENT_REGEX.test(value)) {
|
|
411
|
+
hasSelfPercent = true;
|
|
412
|
+
percentKeyPaths.push(keyPath.slice());
|
|
413
|
+
}
|
|
414
|
+
else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
|
|
416
415
|
percentKeyPaths.push(keyPath.slice());
|
|
417
416
|
}
|
|
418
417
|
}
|
|
@@ -485,11 +484,6 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
|
|
|
485
484
|
transformStringify(normalStyle);
|
|
486
485
|
// transform rpx to px
|
|
487
486
|
transformBoxShadow(normalStyle);
|
|
488
|
-
// transform z-index auto to 0
|
|
489
|
-
transformZIndex(normalStyle);
|
|
490
|
-
if (Array.isArray(normalStyle.transform)) {
|
|
491
|
-
normalStyle.transform = normalStyle.transform.filter(item => !isEmptyObject(item));
|
|
492
|
-
}
|
|
493
487
|
return {
|
|
494
488
|
hasVarDec,
|
|
495
489
|
varContextRef,
|
|
@@ -26,7 +26,7 @@ import { noop } from '@mpxjs/utils'
|
|
|
26
26
|
import { SvgCssUri } from 'react-native-svg/css'
|
|
27
27
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
28
28
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
29
|
-
import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils'
|
|
29
|
+
import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject, isAndroid } from './utils'
|
|
30
30
|
import Portal from './mpx-portal'
|
|
31
31
|
|
|
32
32
|
export type Mode =
|
|
@@ -190,7 +190,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
|
|
|
190
190
|
normalStyle,
|
|
191
191
|
setWidth,
|
|
192
192
|
setHeight
|
|
193
|
-
} = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
|
|
193
|
+
} = useTransformStyle(styleObj, { enableVar, isTransformBorderRadiusPercent: isAndroid && !isSvg && !isLayoutMode, externalVarContext, parentFontSize, parentWidth, parentHeight })
|
|
194
194
|
|
|
195
195
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({
|
|
196
196
|
props,
|
|
@@ -232,6 +232,8 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
232
232
|
const moveTranstion = useSharedValue(0)
|
|
233
233
|
const timerId = useRef(0 as number | ReturnType<typeof setTimeout>)
|
|
234
234
|
const intervalTimer = props.interval || 500
|
|
235
|
+
// 记录是否首次
|
|
236
|
+
const isFirstRef = useRef(true)
|
|
235
237
|
|
|
236
238
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers)
|
|
237
239
|
const waitForHandlers = flatGesture(waitFor)
|
|
@@ -477,10 +479,8 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
477
479
|
}, [])
|
|
478
480
|
|
|
479
481
|
function handleSwiperChange (current: number, pCurrent: number) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
bindchange && bindchange(eventData)
|
|
483
|
-
}
|
|
482
|
+
const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
|
|
483
|
+
bindchange && bindchange(eventData)
|
|
484
484
|
}
|
|
485
485
|
|
|
486
486
|
const runOnJSCallbackRef = useRef({
|
|
@@ -529,9 +529,10 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
529
529
|
// 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
|
|
530
530
|
useAnimatedReaction(() => currentIndex.value, (newIndex: number, preIndex: number) => {
|
|
531
531
|
// 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
|
|
532
|
-
if (newIndex !== preIndex && bindchange) {
|
|
532
|
+
if (newIndex !== preIndex && bindchange && !isFirstRef.current) {
|
|
533
533
|
runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent)
|
|
534
534
|
}
|
|
535
|
+
isFirstRef.current = false
|
|
535
536
|
})
|
|
536
537
|
|
|
537
538
|
useEffect(() => {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement, createElement, MutableRefObject } from 'react'
|
|
2
2
|
import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
|
|
3
|
-
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn
|
|
3
|
+
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils'
|
|
4
4
|
import { VarContext, ScrollViewContext, RouteContext } from './context'
|
|
5
5
|
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
|
|
6
6
|
import { initialWindowMetrics } from 'react-native-safe-area-context'
|
|
7
7
|
import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
|
|
8
8
|
import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
|
|
9
|
-
import { runOnJS } from 'react-native-reanimated'
|
|
10
9
|
import { Gesture } from 'react-native-gesture-handler'
|
|
11
10
|
|
|
12
11
|
export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
|
|
@@ -143,16 +142,17 @@ export function splitStyle<T extends Record<string, any>> (styleObj: T): {
|
|
|
143
142
|
innerStyle: Partial<T>
|
|
144
143
|
}
|
|
145
144
|
}
|
|
146
|
-
|
|
147
|
-
const selfPercentRule: Record<string, 'height' | 'width'> = {
|
|
148
|
-
translateX: 'width',
|
|
149
|
-
translateY: 'height',
|
|
145
|
+
const radiusPercentRule: Record<string, 'height' | 'width'> = {
|
|
150
146
|
borderTopLeftRadius: 'width',
|
|
151
147
|
borderBottomLeftRadius: 'width',
|
|
152
148
|
borderBottomRightRadius: 'width',
|
|
153
149
|
borderTopRightRadius: 'width',
|
|
154
150
|
borderRadius: 'width'
|
|
155
151
|
}
|
|
152
|
+
const selfPercentRule: Record<string, 'height' | 'width'> = Object.assign({
|
|
153
|
+
translateX: 'width',
|
|
154
|
+
translateY: 'height'
|
|
155
|
+
}, radiusPercentRule)
|
|
156
156
|
|
|
157
157
|
const parentHeightPercentRule: Record<string, boolean> = {
|
|
158
158
|
height: true,
|
|
@@ -238,7 +238,7 @@ function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<s
|
|
|
238
238
|
const resolved = resolveVar(value, varContext)
|
|
239
239
|
if (resolved === undefined) {
|
|
240
240
|
delete target[key]
|
|
241
|
-
|
|
241
|
+
error(`Can not resolve css var at ${varKeyPath.join('.')}:${value}.`)
|
|
242
242
|
return
|
|
243
243
|
}
|
|
244
244
|
target[key] = resolved
|
|
@@ -390,23 +390,16 @@ function transformBoxShadow (styleObj: Record<string, any>) {
|
|
|
390
390
|
}, '')
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
function transformZIndex (styleObj: Record<string, any>) {
|
|
394
|
-
if (!styleObj.zIndex || typeof styleObj.zIndex === 'number') return
|
|
395
|
-
if (styleObj.zIndex === 'auto') {
|
|
396
|
-
error('Property [z-index] does not supported [auto], please check again!')
|
|
397
|
-
styleObj.zIndex = 0
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
393
|
interface TransformStyleConfig {
|
|
402
394
|
enableVar?: boolean
|
|
403
395
|
externalVarContext?: Record<string, any>
|
|
404
396
|
parentFontSize?: number
|
|
405
397
|
parentWidth?: number
|
|
406
398
|
parentHeight?: number
|
|
399
|
+
isTransformBorderRadiusPercent?: boolean
|
|
407
400
|
}
|
|
408
401
|
|
|
409
|
-
export function useTransformStyle (styleObj: Record<string, any> = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }: TransformStyleConfig) {
|
|
402
|
+
export function useTransformStyle (styleObj: Record<string, any> = {}, { enableVar, isTransformBorderRadiusPercent, externalVarContext, parentFontSize, parentWidth, parentHeight }: TransformStyleConfig) {
|
|
410
403
|
const varStyle: Record<string, any> = {}
|
|
411
404
|
const unoVarStyle: Record<string, any> = {}
|
|
412
405
|
const normalStyle: Record<string, any> = {}
|
|
@@ -457,7 +450,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
|
|
|
457
450
|
function calcVisitor ({ key, value, keyPath }: VisitorArg) {
|
|
458
451
|
if (calcUseRegExp.test(value)) {
|
|
459
452
|
// calc translate & border-radius 的百分比计算
|
|
460
|
-
if (hasOwn(selfPercentRule, key) &&
|
|
453
|
+
if (hasOwn(selfPercentRule, key) && /calc\(\d+%/.test(value)) {
|
|
461
454
|
hasSelfPercent = true
|
|
462
455
|
percentKeyPaths.push(keyPath.slice())
|
|
463
456
|
}
|
|
@@ -467,7 +460,11 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
|
|
|
467
460
|
|
|
468
461
|
function percentVisitor ({ key, value, keyPath }: VisitorArg) {
|
|
469
462
|
// fixme 去掉 translate & border-radius 的百分比计算
|
|
470
|
-
|
|
463
|
+
// fixme Image 组件 borderRadius 仅支持 number
|
|
464
|
+
if (isTransformBorderRadiusPercent && hasOwn(radiusPercentRule, key) && PERCENT_REGEX.test(value)) {
|
|
465
|
+
hasSelfPercent = true
|
|
466
|
+
percentKeyPaths.push(keyPath.slice())
|
|
467
|
+
} else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
|
|
471
468
|
percentKeyPaths.push(keyPath.slice())
|
|
472
469
|
}
|
|
473
470
|
}
|
|
@@ -477,8 +474,10 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
|
|
|
477
474
|
[envVisitor, percentVisitor, calcVisitor].forEach(visitor => visitor({ target, key, value, keyPath }))
|
|
478
475
|
}
|
|
479
476
|
}
|
|
477
|
+
|
|
480
478
|
// transform 字符串格式转化数组格式(先转数组再处理css var)
|
|
481
479
|
transformTransform(styleObj)
|
|
480
|
+
|
|
482
481
|
// traverse var & generate normalStyle
|
|
483
482
|
traverseStyle(styleObj, [varVisitor])
|
|
484
483
|
hasVarDec = hasVarDec || !!externalVarContext
|
|
@@ -544,11 +543,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
|
|
|
544
543
|
transformStringify(normalStyle)
|
|
545
544
|
// transform rpx to px
|
|
546
545
|
transformBoxShadow(normalStyle)
|
|
547
|
-
|
|
548
|
-
transformZIndex(normalStyle)
|
|
549
|
-
if (Array.isArray(normalStyle.transform)) {
|
|
550
|
-
normalStyle.transform = normalStyle.transform.filter(item => !isEmptyObject(item))
|
|
551
|
-
}
|
|
546
|
+
|
|
552
547
|
return {
|
|
553
548
|
hasVarDec,
|
|
554
549
|
varContextRef,
|