@mpxjs/webpack-plugin 2.10.17-beta.6 → 2.10.17-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +1 -0
- package/lib/json-compiler/index.js +18 -1
- package/lib/platform/style/wx/index.js +1 -17
- package/lib/react/processJSON.js +20 -1
- package/lib/react/processScript.js +1 -0
- package/lib/react/script-helper.js +0 -1
- package/lib/runtime/components/ali/mpx-recycle-view.mpx +518 -0
- package/lib/runtime/components/ali/mpx-sticky-header.mpx +212 -0
- package/lib/runtime/components/ali/mpx-sticky-section.mpx +17 -0
- 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-recycle-view.d.ts +45 -0
- package/lib/runtime/components/react/dist/mpx-recycle-view.jsx +272 -0
- 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-recycle-view.tsx +398 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +1 -0
- package/lib/runtime/components/react/mpx-sticky-section.tsx +1 -1
- package/lib/runtime/components/react/mpx-swiper.tsx +6 -5
- package/lib/runtime/components/react/utils.tsx +18 -23
- package/lib/runtime/components/web/mpx-recycle-view.vue +508 -0
- package/lib/runtime/components/wx/mpx-list-header-default.mpx +21 -0
- package/lib/runtime/components/wx/mpx-recycle-item-default.mpx +21 -0
- package/lib/runtime/components/wx/mpx-recycle-view.mpx +193 -0
- package/lib/runtime/components/wx/mpx-section-header-default.mpx +21 -0
- package/lib/template-compiler/compiler.js +8 -3
- package/lib/utils/const.js +17 -0
- package/lib/utils/process-extend-components.js +43 -0
- package/lib/web/processJSON.js +20 -2
- package/package.json +1 -1
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import React, { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle } from 'react';
|
|
2
|
+
import { SectionList, RefreshControl } from 'react-native';
|
|
3
|
+
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
4
|
+
import { extendObject, useLayout, useTransformStyle } from './utils';
|
|
5
|
+
const getGeneric = (generichash, generickey) => {
|
|
6
|
+
if (!generichash || !generickey)
|
|
7
|
+
return null;
|
|
8
|
+
const GenericComponent = global.__mpxGenericsMap?.[generichash]?.[generickey]?.();
|
|
9
|
+
if (!GenericComponent)
|
|
10
|
+
return null;
|
|
11
|
+
return forwardRef((props, ref) => {
|
|
12
|
+
return createElement(GenericComponent, extendObject({}, {
|
|
13
|
+
ref: ref
|
|
14
|
+
}, props));
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
const getListHeaderComponent = (generichash, generickey, data) => {
|
|
18
|
+
if (!generichash || !generickey)
|
|
19
|
+
return undefined;
|
|
20
|
+
const ListHeaderComponent = getGeneric(generichash, generickey);
|
|
21
|
+
return ListHeaderComponent ? createElement(ListHeaderComponent, { listHeaderData: data }) : null;
|
|
22
|
+
};
|
|
23
|
+
const getSectionHeaderRenderer = (generichash, generickey) => {
|
|
24
|
+
if (!generichash || !generickey)
|
|
25
|
+
return undefined;
|
|
26
|
+
return (sectionData) => {
|
|
27
|
+
if (!sectionData.section.hasSectionHeader)
|
|
28
|
+
return null;
|
|
29
|
+
const SectionHeaderComponent = getGeneric(generichash, generickey);
|
|
30
|
+
return SectionHeaderComponent ? createElement(SectionHeaderComponent, { itemData: sectionData.section.headerData }) : null;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const getItemRenderer = (generichash, generickey) => {
|
|
34
|
+
if (!generichash || !generickey)
|
|
35
|
+
return undefined;
|
|
36
|
+
return ({ item }) => {
|
|
37
|
+
const ItemComponent = getGeneric(generichash, generickey);
|
|
38
|
+
return ItemComponent ? createElement(ItemComponent, { itemData: item }) : null;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const RecycleView = forwardRef((props = {}, ref) => {
|
|
42
|
+
const { enhanced = false, bounces = true, scrollEventThrottle = 0, height, width, listData, generichash, style = {}, itemHeight = {}, sectionHeaderHeight = {}, listHeaderHeight = {}, listHeaderData = null, useListHeader = false, 'genericrecycle-item': genericrecycleItem, 'genericsection-header': genericsectionHeader, 'genericlist-header': genericListHeader, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'enable-sticky': enableSticky = false, 'enable-back-to-top': enableBackToTop = false, 'end-reached-threshold': onEndReachedThreshold = 0.1, 'refresher-enabled': refresherEnabled, 'show-scrollbar': showScrollbar = true, 'refresher-triggered': refresherTriggered } = props;
|
|
43
|
+
const [refreshing, setRefreshing] = useState(!!refresherTriggered);
|
|
44
|
+
const scrollViewRef = useRef(null);
|
|
45
|
+
const indexMap = useRef({});
|
|
46
|
+
const reverseIndexMap = useRef({});
|
|
47
|
+
const { hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
48
|
+
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef });
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (refreshing !== refresherTriggered) {
|
|
51
|
+
setRefreshing(!!refresherTriggered);
|
|
52
|
+
}
|
|
53
|
+
}, [refresherTriggered]);
|
|
54
|
+
const onRefresh = () => {
|
|
55
|
+
const { bindrefresherrefresh } = props;
|
|
56
|
+
bindrefresherrefresh &&
|
|
57
|
+
bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef }, props));
|
|
58
|
+
};
|
|
59
|
+
const onEndReached = () => {
|
|
60
|
+
const { bindscrolltolower } = props;
|
|
61
|
+
bindscrolltolower &&
|
|
62
|
+
bindscrolltolower(getCustomEvent('scrolltolower', {}, { layoutRef }, props));
|
|
63
|
+
};
|
|
64
|
+
const onScroll = (event) => {
|
|
65
|
+
const { bindscroll } = props;
|
|
66
|
+
bindscroll &&
|
|
67
|
+
bindscroll(getCustomEvent('scroll', event.nativeEvent, { layoutRef }, props));
|
|
68
|
+
};
|
|
69
|
+
// 通过sectionIndex和rowIndex获取原始索引
|
|
70
|
+
const getOriginalIndex = (sectionIndex, rowIndex) => {
|
|
71
|
+
const key = `${sectionIndex}_${rowIndex}`;
|
|
72
|
+
return reverseIndexMap.current[key] ?? -1; // 如果找不到,返回-1
|
|
73
|
+
};
|
|
74
|
+
const scrollToIndex = ({ index, animated, viewOffset = 0, viewPosition = 0 }) => {
|
|
75
|
+
if (scrollViewRef.current) {
|
|
76
|
+
// 通过索引映射表快速定位位置
|
|
77
|
+
const position = indexMap.current[index];
|
|
78
|
+
const [sectionIndex, itemIndex] = position.split('_');
|
|
79
|
+
scrollViewRef.current.scrollToLocation?.({
|
|
80
|
+
itemIndex: itemIndex === 'header' ? 0 : Number(itemIndex) + 1,
|
|
81
|
+
sectionIndex: Number(sectionIndex) || 0,
|
|
82
|
+
animated,
|
|
83
|
+
viewOffset,
|
|
84
|
+
viewPosition
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const getItemHeight = ({ sectionIndex, rowIndex }) => {
|
|
89
|
+
if (!itemHeight) {
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
if (itemHeight.getter) {
|
|
93
|
+
const item = convertedListData[sectionIndex].data[rowIndex];
|
|
94
|
+
// 使用getOriginalIndex获取原始索引
|
|
95
|
+
const originalIndex = getOriginalIndex(sectionIndex, rowIndex);
|
|
96
|
+
return itemHeight.getter?.(item, originalIndex) || 0;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return itemHeight.value || 0;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const getSectionHeaderHeight = ({ sectionIndex }) => {
|
|
103
|
+
const item = convertedListData[sectionIndex];
|
|
104
|
+
const { hasSectionHeader } = item;
|
|
105
|
+
// 使用getOriginalIndex获取原始索引
|
|
106
|
+
const originalIndex = getOriginalIndex(sectionIndex, 'header');
|
|
107
|
+
if (!hasSectionHeader)
|
|
108
|
+
return 0;
|
|
109
|
+
if (sectionHeaderHeight.getter) {
|
|
110
|
+
return sectionHeaderHeight.getter?.(item, originalIndex) || 0;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
return sectionHeaderHeight.value || 0;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const convertedListData = useMemo(() => {
|
|
117
|
+
const sections = [];
|
|
118
|
+
let currentSection = null;
|
|
119
|
+
// 清空之前的索引映射
|
|
120
|
+
indexMap.current = {};
|
|
121
|
+
// 清空反向索引映射
|
|
122
|
+
reverseIndexMap.current = {};
|
|
123
|
+
listData.forEach((item, index) => {
|
|
124
|
+
if (item.isSectionHeader) {
|
|
125
|
+
// 如果已经存在一个 section,先把它添加到 sections 中
|
|
126
|
+
if (currentSection) {
|
|
127
|
+
sections.push(currentSection);
|
|
128
|
+
}
|
|
129
|
+
// 创建新的 section
|
|
130
|
+
currentSection = {
|
|
131
|
+
headerData: item,
|
|
132
|
+
data: [],
|
|
133
|
+
hasSectionHeader: true,
|
|
134
|
+
_originalItemIndex: index
|
|
135
|
+
};
|
|
136
|
+
// 为 section header 添加索引映射
|
|
137
|
+
const sectionIndex = sections.length;
|
|
138
|
+
indexMap.current[index] = `${sectionIndex}_header`;
|
|
139
|
+
// 添加反向索引映射
|
|
140
|
+
reverseIndexMap.current[`${sectionIndex}_header`] = index;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// 如果没有当前 section,创建一个默认的
|
|
144
|
+
if (!currentSection) {
|
|
145
|
+
// 创建默认section (无header的section)
|
|
146
|
+
currentSection = {
|
|
147
|
+
headerData: null,
|
|
148
|
+
data: [],
|
|
149
|
+
hasSectionHeader: false,
|
|
150
|
+
_originalItemIndex: -1
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// 将 item 添加到当前 section 的 data 中
|
|
154
|
+
const itemIndex = currentSection.data.length;
|
|
155
|
+
currentSection.data.push(extendObject({}, item, {
|
|
156
|
+
_originalItemIndex: index
|
|
157
|
+
}));
|
|
158
|
+
let sectionIndex;
|
|
159
|
+
// 为 item 添加索引映射 - 存储格式为: "sectionIndex_itemIndex"
|
|
160
|
+
if (!currentSection.hasSectionHeader && sections.length === 0) {
|
|
161
|
+
// 在默认section中(第一个且无header)
|
|
162
|
+
sectionIndex = 0;
|
|
163
|
+
indexMap.current[index] = `${sectionIndex}_${itemIndex}`;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// 在普通section中
|
|
167
|
+
sectionIndex = sections.length;
|
|
168
|
+
indexMap.current[index] = `${sectionIndex}_${itemIndex}`;
|
|
169
|
+
}
|
|
170
|
+
// 添加反向索引映射
|
|
171
|
+
reverseIndexMap.current[`${sectionIndex}_${itemIndex}`] = index;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
// 添加最后一个 section
|
|
175
|
+
if (currentSection) {
|
|
176
|
+
sections.push(currentSection);
|
|
177
|
+
}
|
|
178
|
+
return sections;
|
|
179
|
+
}, [listData]);
|
|
180
|
+
const { getItemLayout } = useMemo(() => {
|
|
181
|
+
const layouts = [];
|
|
182
|
+
let offset = 0;
|
|
183
|
+
if (useListHeader) {
|
|
184
|
+
// 计算列表头部的高度
|
|
185
|
+
offset += listHeaderHeight.getter?.() || listHeaderHeight.value || 0;
|
|
186
|
+
}
|
|
187
|
+
// 遍历所有 sections
|
|
188
|
+
convertedListData.forEach((section, sectionIndex) => {
|
|
189
|
+
// 添加 section header 的位置信息
|
|
190
|
+
const headerHeight = getSectionHeaderHeight({ sectionIndex });
|
|
191
|
+
layouts.push({
|
|
192
|
+
length: headerHeight,
|
|
193
|
+
offset,
|
|
194
|
+
index: layouts.length
|
|
195
|
+
});
|
|
196
|
+
offset += headerHeight;
|
|
197
|
+
// 添加该 section 中所有 items 的位置信息
|
|
198
|
+
section.data.forEach((item, itemIndex) => {
|
|
199
|
+
const contenteight = getItemHeight({ sectionIndex, rowIndex: itemIndex });
|
|
200
|
+
layouts.push({
|
|
201
|
+
length: contenteight,
|
|
202
|
+
offset,
|
|
203
|
+
index: layouts.length
|
|
204
|
+
});
|
|
205
|
+
offset += contenteight;
|
|
206
|
+
});
|
|
207
|
+
// 添加该 section 尾部位置信息
|
|
208
|
+
// 因为即使 sectionList 没传 renderSectionFooter,getItemLayout 中的 index 的计算也会包含尾部节点
|
|
209
|
+
layouts.push({
|
|
210
|
+
length: 0,
|
|
211
|
+
offset,
|
|
212
|
+
index: layouts.length
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
return {
|
|
216
|
+
itemLayouts: layouts,
|
|
217
|
+
getItemLayout: (data, index) => layouts[index]
|
|
218
|
+
};
|
|
219
|
+
}, [convertedListData, useListHeader]);
|
|
220
|
+
const scrollAdditionalProps = extendObject({
|
|
221
|
+
alwaysBounceVertical: false,
|
|
222
|
+
alwaysBounceHorizontal: false,
|
|
223
|
+
scrollEventThrottle: scrollEventThrottle,
|
|
224
|
+
scrollsToTop: enableBackToTop,
|
|
225
|
+
showsHorizontalScrollIndicator: showScrollbar,
|
|
226
|
+
onEndReachedThreshold,
|
|
227
|
+
ref: scrollViewRef,
|
|
228
|
+
bounces: false,
|
|
229
|
+
stickySectionHeadersEnabled: enableSticky,
|
|
230
|
+
onScroll: onScroll,
|
|
231
|
+
onEndReached: onEndReached
|
|
232
|
+
}, layoutProps);
|
|
233
|
+
if (enhanced) {
|
|
234
|
+
Object.assign(scrollAdditionalProps, {
|
|
235
|
+
bounces
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (refresherEnabled) {
|
|
239
|
+
Object.assign(scrollAdditionalProps, {
|
|
240
|
+
refreshing: refreshing
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
useImperativeHandle(ref, () => {
|
|
244
|
+
return {
|
|
245
|
+
...props,
|
|
246
|
+
scrollToIndex
|
|
247
|
+
};
|
|
248
|
+
});
|
|
249
|
+
const innerProps = useInnerProps(extendObject({}, props, scrollAdditionalProps), [
|
|
250
|
+
'id',
|
|
251
|
+
'show-scrollbar',
|
|
252
|
+
'lower-threshold',
|
|
253
|
+
'refresher-triggered',
|
|
254
|
+
'refresher-enabled',
|
|
255
|
+
'bindrefresherrefresh'
|
|
256
|
+
], { layoutRef });
|
|
257
|
+
return createElement(SectionList, extendObject({
|
|
258
|
+
style: [{ height, width }, style, layoutStyle],
|
|
259
|
+
sections: convertedListData,
|
|
260
|
+
renderItem: getItemRenderer(generichash, genericrecycleItem),
|
|
261
|
+
getItemLayout: getItemLayout,
|
|
262
|
+
ListHeaderComponent: useListHeader ? getListHeaderComponent(generichash, genericListHeader, listHeaderData) : null,
|
|
263
|
+
renderSectionHeader: getSectionHeaderRenderer(generichash, genericsectionHeader),
|
|
264
|
+
refreshControl: refresherEnabled
|
|
265
|
+
? React.createElement(RefreshControl, {
|
|
266
|
+
onRefresh: onRefresh,
|
|
267
|
+
refreshing: refreshing
|
|
268
|
+
})
|
|
269
|
+
: undefined
|
|
270
|
+
}, innerProps));
|
|
271
|
+
});
|
|
272
|
+
export default RecycleView;
|
|
@@ -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,
|