@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.
@@ -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}, eg ${info[type]}, received [${value}], please check again!`)
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, animatedKeysShareVal } = useMemo(() => {
172
+ const { shareValMap, animatedKeys, animatedStyleKeys } = useMemo(() => {
173
173
  // 记录需要执行动画的 propName
174
174
  const animatedKeys = [] as string[]
175
- const animatedKeysShareVal = [] as (string|string[])[]
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
- animatedKeysShareVal.push(property)
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) animatedKeysShareVal.push(transforms)
198
+ if (transforms.length) animatedStyleKeys.push(transforms)
198
199
  return {
199
200
  shareValMap,
200
201
  animatedKeys,
201
- animatedKeysShareVal
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
- error(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`)
230
+ warn(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`)
232
231
  }
233
- // console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
234
- const { delay = 0, duration, easing } = transitionMap[isTransformKey ? 'transform' : key]
235
- // console.log('animationOptions=', { delay, duration, easing })
236
- let callback
237
- if (transitionend && (!isTransformKey || !transformTransitionendDone)) {
238
- runOnJSCallbackRef.current = {
239
- animationCallback: (duration: number, finished: boolean, current?: AnimatableValue) => {
240
- transitionend(finished, current, duration)
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
- callback = (finished?: boolean, current?: AnimatableValue) => {
244
- 'worklet'
245
- // 动画结束后设置下一次transformOrigin
246
- if (finished) {
247
- runOnJS(runOnJSCallback)('animationCallback', duration, finished, current)
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.value.reduce((styles, key) => {
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
- width: 0,
98
- height: 0,
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, useSharedValue, useAnimatedStyle, cancelAnimation } from 'react-native-reanimated';
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, animatedKeysShareVal } = useMemo(() => {
144
+ const { shareValMap, animatedKeys, animatedStyleKeys } = useMemo(() => {
145
145
  // 记录需要执行动画的 propName
146
146
  const animatedKeys = [];
147
- const animatedKeysShareVal = [];
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
- animatedKeysShareVal.push(property);
166
+ animatedStyleKeys.push(property);
166
167
  }
167
168
  // console.log('shareValMap = ', valMap)
168
169
  return valMap;
169
170
  }, {});
170
171
  if (transforms.length)
171
- animatedKeysShareVal.push(transforms);
172
+ animatedStyleKeys.push(transforms);
172
173
  return {
173
174
  shareValMap,
174
175
  animatedKeys,
175
- animatedKeysShareVal
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
- error(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`);
206
+ warn(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`);
208
207
  }
209
- // console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
210
- const { delay = 0, duration, easing } = transitionMap[isTransformKey ? 'transform' : key];
211
- // console.log('animationOptions=', { delay, duration, easing })
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
- const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, callback);
228
- // Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
229
- if (isTransformKey) {
230
- transformTransitionendDone = true;
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.value.reduce((styles, key) => {
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
- width: 0,
51
- height: 0,
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
- if (pCurrent !== currentIndex.value) {
359
- const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef });
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, isEmptyObject } from '@mpxjs/utils';
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 selfPercentRule = {
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
- // error(`Can not resolve css var at ${varKeyPath.join('.')}:${value}.`)
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 transformZIndex(styleObj) {
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) && /%/.test(value)) {
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
- if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
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
- if (pCurrent !== currentIndex.value) {
481
- const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
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, isEmptyObject } from '@mpxjs/utils'
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
- // error(`Can not resolve css var at ${varKeyPath.join('.')}:${value}.`)
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) && /%/.test(value)) {
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
- if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
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
- // transform z-index auto to 0
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.10.17-beta.6",
3
+ "version": "2.10.17-beta.7",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"