@mpxjs/webpack-plugin 2.9.67 → 2.9.69
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 +13 -8
- package/lib/platform/template/wx/component-config/canvas.js +8 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/react/processStyles.js +14 -4
- package/lib/resolver/AddModePlugin.js +8 -8
- package/lib/runtime/components/react/context.ts +2 -0
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +3 -12
- package/lib/runtime/components/react/dist/mpx-button.jsx +43 -8
- package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
- package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
- package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
- package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
- package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
- package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
- package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +214 -0
- package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +143 -84
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +69 -113
- package/lib/runtime/components/react/dist/mpx-view.jsx +45 -26
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +19 -5
- package/lib/runtime/components/react/dist/pickerFaces.js +75 -0
- package/lib/runtime/components/react/dist/pickerOverlay.jsx +21 -0
- package/lib/runtime/components/react/dist/utils.jsx +54 -3
- package/lib/runtime/components/react/getInnerListeners.ts +3 -17
- package/lib/runtime/components/react/mpx-button.tsx +41 -8
- package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
- package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
- package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
- package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
- package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
- package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
- package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
- package/lib/runtime/components/react/mpx-canvas/index.tsx +302 -0
- package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +232 -103
- package/lib/runtime/components/react/mpx-picker-view.tsx +126 -122
- package/lib/runtime/components/react/mpx-view.tsx +57 -27
- package/lib/runtime/components/react/mpx-web-view.tsx +22 -5
- package/lib/runtime/components/react/pickerFaces.ts +104 -0
- package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
- package/lib/runtime/components/react/types/common.ts +2 -0
- package/lib/runtime/components/react/types/global.d.ts +2 -0
- package/lib/runtime/components/react/utils.tsx +78 -7
- package/lib/template-compiler/compiler.js +3 -2
- package/lib/template-compiler/gen-node-react.js +2 -2
- package/package.json +5 -4
|
@@ -1,108 +1,167 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React, { forwardRef, useRef, useState, useEffect } from 'react';
|
|
3
|
-
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils';
|
|
4
|
-
import useNodesRef from './useNodesRef';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
//
|
|
1
|
+
import { Animated, SafeAreaView } from 'react-native';
|
|
2
|
+
import React, { forwardRef, useRef, useState, useMemo, useCallback, useEffect } from 'react';
|
|
3
|
+
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, usePrevious } from './utils';
|
|
4
|
+
import useNodesRef from './useNodesRef';
|
|
5
|
+
import { createFaces } from './pickerFaces';
|
|
6
|
+
import PickerOverlay from './pickerOverlay';
|
|
7
|
+
// 默认的单个选项高度
|
|
8
|
+
const DefaultPickerItemH = 36;
|
|
9
|
+
// 默认一屏可见选项个数
|
|
10
|
+
const visibleCount = 5;
|
|
8
11
|
const _PickerViewColumn = forwardRef((props, ref) => {
|
|
9
|
-
const {
|
|
10
|
-
// PickerViewColumn
|
|
12
|
+
const { columnData, columnIndex, initialIndex, onSelectChange, onColumnItemRawHChange, getInnerLayout, style, wrapperStyle, pickerOverlayStyle, 'enable-var': enableVar, 'external-var-context': externalVarContext } = props;
|
|
11
13
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
|
|
12
14
|
const { textStyle } = splitStyle(normalStyle);
|
|
13
15
|
const { textProps } = splitProps(props);
|
|
14
|
-
// const { innerStyle } = splitStyle(normalStyle)
|
|
15
|
-
// scrollView的ref
|
|
16
16
|
const scrollViewRef = useRef(null);
|
|
17
17
|
useNodesRef(props, ref, scrollViewRef, {});
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const { height: pickerH, itemHeight = DefaultPickerItemH } = wrapperStyle;
|
|
19
|
+
const [itemRawH, setItemRawH] = useState(0); // 单个选项真实渲染高度
|
|
20
|
+
const maxIndex = useMemo(() => columnData.length - 1, [columnData]);
|
|
21
|
+
const touching = useRef(false);
|
|
22
|
+
const scrolling = useRef(false);
|
|
23
|
+
const activeIndex = useRef(initialIndex);
|
|
24
|
+
const prevIndex = usePrevious(initialIndex);
|
|
25
|
+
const prevMaxIndex = usePrevious(maxIndex);
|
|
26
|
+
const initialOffset = useMemo(() => ({
|
|
27
|
+
x: 0,
|
|
28
|
+
y: itemRawH * initialIndex
|
|
29
|
+
}), [itemRawH]);
|
|
30
|
+
const snapToOffsets = useMemo(() => columnData.map((_, i) => i * itemRawH), [columnData, itemRawH]);
|
|
31
|
+
const contentContainerStyle = useMemo(() => {
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
paddingVertical: Math.round(pickerH - itemRawH) / 2
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
}, [pickerH, itemRawH]);
|
|
20
38
|
useEffect(() => {
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
if (!scrollViewRef.current ||
|
|
40
|
+
!itemRawH ||
|
|
41
|
+
touching.current ||
|
|
42
|
+
scrolling.current ||
|
|
43
|
+
prevIndex == null ||
|
|
44
|
+
initialIndex === prevIndex ||
|
|
45
|
+
initialIndex === activeIndex.current ||
|
|
46
|
+
maxIndex !== prevMaxIndex) {
|
|
47
|
+
return;
|
|
24
48
|
}
|
|
25
|
-
|
|
49
|
+
activeIndex.current = initialIndex;
|
|
50
|
+
scrollViewRef.current.scrollTo({
|
|
51
|
+
x: 0,
|
|
52
|
+
y: itemRawH * initialIndex,
|
|
53
|
+
animated: false
|
|
54
|
+
});
|
|
55
|
+
}, [itemRawH, initialIndex]);
|
|
26
56
|
const onScrollViewLayout = () => {
|
|
27
57
|
getInnerLayout && getInnerLayout(layoutRef);
|
|
28
58
|
};
|
|
29
|
-
const {
|
|
30
|
-
|
|
31
|
-
|
|
59
|
+
const { layoutRef, layoutProps } = useLayout({
|
|
60
|
+
props,
|
|
61
|
+
hasSelfPercent,
|
|
62
|
+
setWidth,
|
|
63
|
+
setHeight,
|
|
64
|
+
nodeRef: scrollViewRef,
|
|
65
|
+
onLayout: onScrollViewLayout
|
|
66
|
+
});
|
|
67
|
+
const onContentSizeChange = (w, h) => {
|
|
68
|
+
scrollViewRef.current?.scrollTo({
|
|
69
|
+
x: 0,
|
|
70
|
+
y: itemRawH * initialIndex,
|
|
71
|
+
animated: false
|
|
72
|
+
});
|
|
73
|
+
};
|
|
32
74
|
const onItemLayout = (e) => {
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
onColumnLayoutChange && onColumnLayoutChange({ height: layout.height * 5 });
|
|
75
|
+
const { height: rawH } = e.nativeEvent.layout;
|
|
76
|
+
if (rawH && itemRawH !== rawH) {
|
|
77
|
+
setItemRawH(rawH);
|
|
78
|
+
onColumnItemRawHChange(rawH);
|
|
38
79
|
}
|
|
39
80
|
};
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const { y: scrollY } = e.nativeEvent.contentOffset;
|
|
43
|
-
const selIndex = Math.floor(scrollY / itemH);
|
|
44
|
-
onSelectChange(selIndex);
|
|
45
|
-
}
|
|
81
|
+
const onTouchStart = () => {
|
|
82
|
+
touching.current = true;
|
|
46
83
|
};
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
realElement = [children];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return realElement;
|
|
64
|
-
};
|
|
65
|
-
const realChilds = getRealChilds();
|
|
66
|
-
const arrChild = realChilds.map((item, index) => {
|
|
67
|
-
const InnerProps = index === 0 ? { onLayout: onItemLayout } : {};
|
|
68
|
-
const strKey = 'picker' + props.prefix + '-column' + index;
|
|
69
|
-
const arrHeight = (wrapperStyle.itemHeight + '').match(/\d+/g) || [];
|
|
70
|
-
const iHeight = (arrHeight[0] || defaultItemHeight);
|
|
71
|
-
return <View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>
|
|
72
|
-
{wrapChildren({
|
|
73
|
-
children: item
|
|
74
|
-
}, {
|
|
75
|
-
hasVarDec,
|
|
76
|
-
varContext: varContextRef.current,
|
|
77
|
-
textStyle,
|
|
78
|
-
textProps
|
|
79
|
-
})}
|
|
80
|
-
</View>;
|
|
81
|
-
});
|
|
82
|
-
const totalHeight = itemH * 5;
|
|
83
|
-
if (wrapperStyle.height && totalHeight !== wrapperStyle.height) {
|
|
84
|
-
const fix = Math.ceil((totalHeight - wrapperStyle.height) / 2);
|
|
85
|
-
arrChild.unshift(<View key="picker-column-0" style={[{ height: itemH - fix }]}></View>);
|
|
86
|
-
arrChild.unshift(<View key="picker-column-1" style={[{ height: itemH }]}></View>);
|
|
87
|
-
arrChild.push(<View key="picker-column-2" style={[{ height: itemH }]}></View>);
|
|
88
|
-
arrChild.push(<View key="picker-column-3" style={[{ height: itemH - fix }]}></View>);
|
|
84
|
+
const onTouchEnd = () => {
|
|
85
|
+
touching.current = false;
|
|
86
|
+
};
|
|
87
|
+
const onTouchCancel = () => {
|
|
88
|
+
touching.current = false;
|
|
89
|
+
};
|
|
90
|
+
const onMomentumScrollBegin = () => {
|
|
91
|
+
scrolling.current = true;
|
|
92
|
+
};
|
|
93
|
+
const onMomentumScrollEnd = (e) => {
|
|
94
|
+
scrolling.current = false;
|
|
95
|
+
if (!itemRawH) {
|
|
96
|
+
return;
|
|
89
97
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
const { y: scrollY } = e.nativeEvent.contentOffset;
|
|
99
|
+
let calcIndex = Math.round(scrollY / itemRawH);
|
|
100
|
+
activeIndex.current = calcIndex;
|
|
101
|
+
if (calcIndex !== initialIndex) {
|
|
102
|
+
calcIndex = Math.max(0, Math.min(calcIndex, maxIndex)) || 0;
|
|
103
|
+
onSelectChange(calcIndex);
|
|
95
104
|
}
|
|
96
|
-
return arrChild;
|
|
97
105
|
};
|
|
106
|
+
const offsetY = useRef(new Animated.Value(0)).current;
|
|
107
|
+
const onScroll = useMemo(() => Animated.event([{ nativeEvent: { contentOffset: { y: offsetY } } }], {
|
|
108
|
+
useNativeDriver: true
|
|
109
|
+
}), [offsetY]);
|
|
110
|
+
const faces = useMemo(() => createFaces(itemRawH, visibleCount), [itemRawH]);
|
|
111
|
+
const getTransform = useCallback((index) => {
|
|
112
|
+
const inputRange = faces.map((f) => itemRawH * (index + f.index));
|
|
113
|
+
return {
|
|
114
|
+
opacity: offsetY.interpolate({
|
|
115
|
+
inputRange: inputRange,
|
|
116
|
+
outputRange: faces.map((x) => x.opacity),
|
|
117
|
+
extrapolate: 'clamp'
|
|
118
|
+
}),
|
|
119
|
+
rotateX: offsetY.interpolate({
|
|
120
|
+
inputRange: inputRange,
|
|
121
|
+
outputRange: faces.map((x) => `${x.deg}deg`),
|
|
122
|
+
extrapolate: 'extend'
|
|
123
|
+
}),
|
|
124
|
+
translateY: offsetY.interpolate({
|
|
125
|
+
inputRange: inputRange,
|
|
126
|
+
outputRange: faces.map((x) => x.offsetY),
|
|
127
|
+
extrapolate: 'extend'
|
|
128
|
+
})
|
|
129
|
+
};
|
|
130
|
+
}, [offsetY, faces, itemRawH]);
|
|
131
|
+
const renderInnerchild = () => columnData.map((item, index) => {
|
|
132
|
+
const InnerProps = index === 0 ? { onLayout: onItemLayout } : {};
|
|
133
|
+
const strKey = `picker-column-${columnIndex}-${index}`;
|
|
134
|
+
const { opacity, rotateX, translateY } = getTransform(index);
|
|
135
|
+
return (<Animated.View key={strKey} {...InnerProps} style={[
|
|
136
|
+
{
|
|
137
|
+
height: itemHeight || DefaultPickerItemH,
|
|
138
|
+
width: '100%',
|
|
139
|
+
opacity,
|
|
140
|
+
transform: [
|
|
141
|
+
{ translateY },
|
|
142
|
+
{ rotateX },
|
|
143
|
+
{ perspective: 1000 } // 适配 Android
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
]}>
|
|
147
|
+
{wrapChildren({ children: item }, {
|
|
148
|
+
hasVarDec,
|
|
149
|
+
varContext: varContextRef.current,
|
|
150
|
+
textStyle,
|
|
151
|
+
textProps
|
|
152
|
+
})}
|
|
153
|
+
</Animated.View>);
|
|
154
|
+
});
|
|
98
155
|
const renderScollView = () => {
|
|
99
|
-
return (<Animated.ScrollView
|
|
156
|
+
return (<Animated.ScrollView ref={scrollViewRef} bounces={true} horizontal={false} pagingEnabled={false} nestedScrollEnabled={true} removeClippedSubviews={true} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} {...layoutProps} scrollEventThrottle={16} contentContainerStyle={contentContainerStyle} contentOffset={initialOffset} snapToOffsets={snapToOffsets} onContentSizeChange={onContentSizeChange} onScroll={onScroll} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} onTouchCancel={onTouchCancel} onMomentumScrollBegin={onMomentumScrollBegin} onMomentumScrollEnd={onMomentumScrollEnd}>
|
|
100
157
|
{renderInnerchild()}
|
|
101
|
-
|
|
158
|
+
</Animated.ScrollView>);
|
|
102
159
|
};
|
|
160
|
+
const renderOverlay = () => (<PickerOverlay itemHeight={itemHeight} overlayItemStyle={pickerOverlayStyle}/>);
|
|
103
161
|
return (<SafeAreaView style={[{ display: 'flex', flex: 1 }]}>
|
|
104
|
-
|
|
105
|
-
|
|
162
|
+
{renderScollView()}
|
|
163
|
+
{renderOverlay()}
|
|
164
|
+
</SafeAreaView>);
|
|
106
165
|
});
|
|
107
|
-
_PickerViewColumn.displayName = '
|
|
166
|
+
_PickerViewColumn.displayName = 'MpxPickerViewColumn';
|
|
108
167
|
export default _PickerViewColumn;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { View } from 'react-native';
|
|
2
|
-
import { LinearGradient } from 'react-native-linear-gradient';
|
|
3
2
|
import React, { forwardRef, useState, useRef } from 'react';
|
|
4
3
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
5
|
-
import useNodesRef from './useNodesRef';
|
|
6
|
-
import {
|
|
4
|
+
import useNodesRef from './useNodesRef';
|
|
5
|
+
import { useLayout, splitProps, splitStyle, wrapChildren, parseInlineStyle, useTransformStyle, useDebounceCallback, useStableCallback, extendObject } from './utils';
|
|
7
6
|
const styles = {
|
|
8
7
|
wrapper: {
|
|
9
8
|
display: 'flex',
|
|
@@ -12,16 +11,6 @@ const styles = {
|
|
|
12
11
|
justifyContent: 'space-around',
|
|
13
12
|
overflow: 'hidden',
|
|
14
13
|
alignItems: 'center'
|
|
15
|
-
},
|
|
16
|
-
maskTop: {
|
|
17
|
-
position: 'absolute',
|
|
18
|
-
width: 1000,
|
|
19
|
-
zIndex: 100
|
|
20
|
-
},
|
|
21
|
-
maskBottom: {
|
|
22
|
-
position: 'absolute',
|
|
23
|
-
width: 1000,
|
|
24
|
-
zIndex: 100
|
|
25
14
|
}
|
|
26
15
|
};
|
|
27
16
|
const _PickerView = forwardRef((props, ref) => {
|
|
@@ -29,67 +18,62 @@ const _PickerView = forwardRef((props, ref) => {
|
|
|
29
18
|
// indicatorStyle 需要转换为rn的style
|
|
30
19
|
// 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
|
|
31
20
|
const indicatorStyle = parseInlineStyle(props['indicator-style']);
|
|
32
|
-
const { height: indicatorH,
|
|
21
|
+
const { height: indicatorH, ...pickerOverlayStyle } = indicatorStyle;
|
|
22
|
+
const [pickMaxH, setPickMaxH] = useState(0);
|
|
33
23
|
const nodeRef = useRef(null);
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
const cloneRef = useRef(null);
|
|
25
|
+
const activeValueRef = useRef(value);
|
|
26
|
+
activeValueRef.current = value.slice();
|
|
36
27
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
|
|
37
|
-
|
|
38
|
-
const { textProps } = splitProps(props);
|
|
28
|
+
useNodesRef(props, ref, nodeRef, {});
|
|
39
29
|
const {
|
|
40
30
|
// 存储layout布局信息
|
|
41
31
|
layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: nodeRef });
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
maskPos.height = itemH * 2 + Math.ceil((normalStyle.height - pickH) / 2);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
maskPos.height = itemH * 2;
|
|
52
|
-
}
|
|
53
|
-
const onColumnLayoutChange = (layoutConfig) => {
|
|
54
|
-
pickH = layoutConfig.height;
|
|
55
|
-
setPickH(layoutConfig.height);
|
|
32
|
+
const { textProps } = splitProps(props);
|
|
33
|
+
const { textStyle } = splitStyle(normalStyle);
|
|
34
|
+
const onColumnItemRawHChange = (height) => {
|
|
35
|
+
if (height > pickMaxH) {
|
|
36
|
+
setPickMaxH(height);
|
|
37
|
+
}
|
|
56
38
|
};
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
39
|
+
const bindchangeDebounce = useDebounceCallback(useStableCallback(bindchange), 300);
|
|
40
|
+
const onSelectChange = (columnIndex, selectedIndex) => {
|
|
41
|
+
bindchangeDebounce.clear();
|
|
42
|
+
const activeValue = activeValueRef.current;
|
|
43
|
+
activeValue[columnIndex] = selectedIndex;
|
|
44
|
+
const eventData = getCustomEvent('change', {}, { detail: { value: activeValue, source: 'change' }, layoutRef });
|
|
45
|
+
bindchangeDebounce(eventData);
|
|
62
46
|
};
|
|
63
|
-
const
|
|
47
|
+
const onInitialChange = (value) => {
|
|
48
|
+
const eventData = getCustomEvent('change', {}, { detail: { value, source: 'change' }, layoutRef });
|
|
49
|
+
bindchange?.(eventData); // immediate
|
|
50
|
+
};
|
|
51
|
+
const innerProps = useInnerProps(props, extendObject({
|
|
64
52
|
ref: nodeRef,
|
|
65
|
-
style: {
|
|
66
|
-
...normalStyle,
|
|
67
|
-
...layoutStyle,
|
|
53
|
+
style: extendObject(normalStyle, layoutStyle, {
|
|
68
54
|
position: 'relative',
|
|
69
55
|
overflow: 'hidden'
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
}, [
|
|
73
|
-
|
|
74
|
-
], { layoutRef });
|
|
75
|
-
const cloneChild = (child, index) => {
|
|
76
|
-
// const extraProps = index === 0 ? { getInnerLayout: getInnerLayout, innerProps } : {}
|
|
56
|
+
}),
|
|
57
|
+
layoutProps
|
|
58
|
+
}), ['enable-offset'], { layoutRef });
|
|
59
|
+
const renderColumn = (child, index, columnData, initialIndex) => {
|
|
77
60
|
const extraProps = {};
|
|
78
|
-
const childProps = {
|
|
79
|
-
|
|
61
|
+
const childProps = child?.props || {};
|
|
62
|
+
const wrappedProps = extendObject(childProps, {
|
|
63
|
+
columnData,
|
|
80
64
|
ref: cloneRef,
|
|
81
|
-
|
|
82
|
-
key:
|
|
65
|
+
columnIndex: index,
|
|
66
|
+
key: `pick-view-${index}`,
|
|
83
67
|
wrapperStyle: {
|
|
84
68
|
height: normalStyle?.height || 0,
|
|
85
69
|
itemHeight: indicatorH || 0
|
|
86
70
|
},
|
|
87
|
-
|
|
71
|
+
onColumnItemRawHChange,
|
|
88
72
|
onSelectChange: onSelectChange.bind(null, index),
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
92
|
-
const realElement = React.cloneElement(child,
|
|
73
|
+
initialIndex,
|
|
74
|
+
pickerOverlayStyle
|
|
75
|
+
}, extraProps);
|
|
76
|
+
const realElement = React.cloneElement(child, wrappedProps);
|
|
93
77
|
return wrapChildren({
|
|
94
78
|
children: realElement
|
|
95
79
|
}, {
|
|
@@ -99,65 +83,37 @@ const _PickerView = forwardRef((props, ref) => {
|
|
|
99
83
|
textProps
|
|
100
84
|
});
|
|
101
85
|
};
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
colors: ['rgba(255,255,255,0.8)', 'rgba(255,255,255,0.2)'],
|
|
105
|
-
style: [
|
|
106
|
-
styles.maskTop,
|
|
107
|
-
{
|
|
108
|
-
height: maskPos.height,
|
|
109
|
-
top: 0,
|
|
110
|
-
pointerEvents: 'none'
|
|
111
|
-
}
|
|
112
|
-
]
|
|
113
|
-
};
|
|
114
|
-
return (<LinearGradient {...linearProps}/>);
|
|
115
|
-
};
|
|
116
|
-
const renderBottomMask = () => {
|
|
117
|
-
const linearProps = {
|
|
118
|
-
colors: ['rgba(255,255,255,0.2)', 'rgba(255,255,255,0.8)'],
|
|
119
|
-
style: [
|
|
120
|
-
styles.maskBottom,
|
|
121
|
-
{
|
|
122
|
-
height: maskPos.height,
|
|
123
|
-
bottom: 0,
|
|
124
|
-
pointerEvents: 'none'
|
|
125
|
-
}
|
|
126
|
-
]
|
|
127
|
-
};
|
|
128
|
-
return <LinearGradient {...linearProps}></LinearGradient>;
|
|
86
|
+
const validateChildInitialIndex = (index, data) => {
|
|
87
|
+
return Math.max(0, Math.min(value[index] || 0, data.length - 1));
|
|
129
88
|
};
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
height: itemH,
|
|
136
|
-
borderTopWidth: 1,
|
|
137
|
-
borderBottomWidth: 1,
|
|
138
|
-
borderColor: '#f0f0f0',
|
|
139
|
-
width: '100%',
|
|
140
|
-
zIndex: 101
|
|
141
|
-
}]}></View>;
|
|
142
|
-
};
|
|
143
|
-
const renderSubChild = () => {
|
|
144
|
-
if (Array.isArray(children)) {
|
|
145
|
-
return children.map((item, index) => {
|
|
146
|
-
return cloneChild(item, index);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
return cloneChild(children, 0);
|
|
89
|
+
const flatColumnChildren = (data) => {
|
|
90
|
+
const columnData = React.Children.toArray(data?.props?.children);
|
|
91
|
+
if (columnData.length === 1 && React.isValidElement(columnData[0]) && columnData[0].type === React.Fragment) {
|
|
92
|
+
// 只有一个 Fragment 嵌套情况
|
|
93
|
+
return React.Children.toArray(columnData[0].props.children);
|
|
151
94
|
}
|
|
95
|
+
return columnData;
|
|
96
|
+
};
|
|
97
|
+
const renderPickerColumns = () => {
|
|
98
|
+
const columns = React.Children.toArray(children);
|
|
99
|
+
const renderColumns = [];
|
|
100
|
+
const validValue = [];
|
|
101
|
+
let isInvalid = false;
|
|
102
|
+
columns.forEach((item, index) => {
|
|
103
|
+
const columnData = flatColumnChildren(item);
|
|
104
|
+
const validIndex = validateChildInitialIndex(index, columnData);
|
|
105
|
+
if (validIndex !== value[index]) {
|
|
106
|
+
isInvalid = true;
|
|
107
|
+
}
|
|
108
|
+
validValue.push(validIndex);
|
|
109
|
+
renderColumns.push(renderColumn(item, index, columnData, validIndex));
|
|
110
|
+
});
|
|
111
|
+
isInvalid && onInitialChange(validValue);
|
|
112
|
+
return renderColumns;
|
|
152
113
|
};
|
|
153
114
|
return (<View {...innerProps}>
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
{renderSubChild()}
|
|
157
|
-
</View>
|
|
158
|
-
{renderBottomMask()}
|
|
159
|
-
{!isSetW && renderLine()}
|
|
160
|
-
</View>);
|
|
115
|
+
<View style={[styles.wrapper]}>{renderPickerColumns()}</View>
|
|
116
|
+
</View>);
|
|
161
117
|
});
|
|
162
|
-
_PickerView.displayName = '
|
|
118
|
+
_PickerView.displayName = 'MpxPickerView';
|
|
163
119
|
export default _PickerView;
|
|
@@ -10,7 +10,7 @@ import useInnerProps from './getInnerListeners';
|
|
|
10
10
|
import Animated from 'react-native-reanimated';
|
|
11
11
|
import useAnimationHooks from './useAnimationHooks';
|
|
12
12
|
import useNodesRef from './useNodesRef';
|
|
13
|
-
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils';
|
|
13
|
+
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle } from './utils';
|
|
14
14
|
import LinearGradient from 'react-native-linear-gradient';
|
|
15
15
|
const linearMap = new Map([
|
|
16
16
|
['top', 0],
|
|
@@ -201,7 +201,7 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
201
201
|
}
|
|
202
202
|
else { // 数值类型 ImageStyle
|
|
203
203
|
// 数值类型设置为 stretch
|
|
204
|
-
imageProps.
|
|
204
|
+
imageProps.resizeMode = 'stretch';
|
|
205
205
|
dimensions = {
|
|
206
206
|
width: isPercent(width) ? width : +width,
|
|
207
207
|
height: isPercent(height) ? height : +height
|
|
@@ -216,8 +216,9 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
216
216
|
}
|
|
217
217
|
// background-image转换为source
|
|
218
218
|
function backgroundImage(imageProps, preImageInfo) {
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
const src = preImageInfo.src;
|
|
220
|
+
if (src) {
|
|
221
|
+
imageProps.source = { uri: src };
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
224
|
// 渐变的转换
|
|
@@ -241,8 +242,8 @@ function linearGradient(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
241
242
|
const imageStyleToProps = (preImageInfo, imageSize, layoutInfo) => {
|
|
242
243
|
// 初始化
|
|
243
244
|
const imageProps = {
|
|
245
|
+
resizeMode: 'cover',
|
|
244
246
|
style: {
|
|
245
|
-
resizeMode: 'cover',
|
|
246
247
|
position: 'absolute'
|
|
247
248
|
// ...StyleSheet.absoluteFillObject
|
|
248
249
|
},
|
|
@@ -430,7 +431,23 @@ function preParseImage(imageStyle) {
|
|
|
430
431
|
function isDiagonalAngle(linearInfo) {
|
|
431
432
|
return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction]);
|
|
432
433
|
}
|
|
433
|
-
function
|
|
434
|
+
function inheritStyle(innerStyle = {}) {
|
|
435
|
+
const { borderWidth, borderRadius } = innerStyle;
|
|
436
|
+
const borderStyles = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'];
|
|
437
|
+
return pickStyle(innerStyle, borderStyles, borderWidth && borderRadius
|
|
438
|
+
? (key, val) => {
|
|
439
|
+
// 盒子内圆角borderWith与borderRadius的关系
|
|
440
|
+
// 当borderRadius 小于 当borderWith 内边框为直角
|
|
441
|
+
// 当borderRadius 大于等于 当borderWith 内边框为圆角
|
|
442
|
+
if (borderStyles.includes(key)) {
|
|
443
|
+
const borderVal = +val - borderWidth;
|
|
444
|
+
return borderVal > 0 ? borderVal : 0;
|
|
445
|
+
}
|
|
446
|
+
return val;
|
|
447
|
+
}
|
|
448
|
+
: undefined);
|
|
449
|
+
}
|
|
450
|
+
function wrapImage(imageStyle, innerStyle, enableFastImage) {
|
|
434
451
|
// 预处理数据
|
|
435
452
|
const preImageInfo = preParseImage(imageStyle);
|
|
436
453
|
// 预解析
|
|
@@ -510,12 +527,12 @@ function wrapImage(imageStyle) {
|
|
|
510
527
|
setShow(true);
|
|
511
528
|
}
|
|
512
529
|
};
|
|
513
|
-
return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
|
|
530
|
+
return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
|
|
514
531
|
{show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
|
|
515
|
-
{show && type === 'image' &&
|
|
532
|
+
{show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage))}
|
|
516
533
|
</View>;
|
|
517
534
|
}
|
|
518
|
-
function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps }) {
|
|
535
|
+
function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }) {
|
|
519
536
|
const children = wrapChildren(props, {
|
|
520
537
|
hasVarDec,
|
|
521
538
|
varContext,
|
|
@@ -523,13 +540,13 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
|
|
|
523
540
|
textProps
|
|
524
541
|
});
|
|
525
542
|
return [
|
|
526
|
-
enableBackground ? wrapImage(backgroundStyle) : null,
|
|
543
|
+
enableBackground ? wrapImage(backgroundStyle, innerStyle, enableFastImage) : null,
|
|
527
544
|
children
|
|
528
545
|
];
|
|
529
546
|
}
|
|
530
547
|
const _View = forwardRef((viewProps, ref) => {
|
|
531
548
|
const { textProps, innerProps: props = {} } = splitProps(viewProps);
|
|
532
|
-
let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
|
|
549
|
+
let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
|
|
533
550
|
const [isHover, setIsHover] = useState(false);
|
|
534
551
|
// 默认样式
|
|
535
552
|
const defaultStyle = {
|
|
@@ -595,9 +612,20 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
595
612
|
}
|
|
596
613
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
597
614
|
const viewStyle = Object.assign({}, innerStyle, layoutStyle);
|
|
615
|
+
enableAnimation = enableAnimation || !!animation;
|
|
616
|
+
const enableAnimationRef = useRef(enableAnimation);
|
|
617
|
+
if (enableAnimationRef.current !== enableAnimation) {
|
|
618
|
+
throw new Error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.');
|
|
619
|
+
}
|
|
620
|
+
const finalStyle = enableAnimation
|
|
621
|
+
? useAnimationHooks({
|
|
622
|
+
animation,
|
|
623
|
+
style: viewStyle
|
|
624
|
+
})
|
|
625
|
+
: viewStyle;
|
|
598
626
|
const innerProps = useInnerProps(props, {
|
|
599
627
|
ref: nodeRef,
|
|
600
|
-
style:
|
|
628
|
+
style: finalStyle,
|
|
601
629
|
...layoutProps,
|
|
602
630
|
...(hoverStyle && {
|
|
603
631
|
bindtouchstart: onTouchStart,
|
|
@@ -611,27 +639,18 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
611
639
|
], {
|
|
612
640
|
layoutRef
|
|
613
641
|
});
|
|
614
|
-
enableAnimation = enableAnimation || !!animation;
|
|
615
|
-
const enableAnimationRef = useRef(enableAnimation);
|
|
616
|
-
if (enableAnimationRef.current !== enableAnimation) {
|
|
617
|
-
throw new Error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.');
|
|
618
|
-
}
|
|
619
|
-
const finalStyle = enableAnimation
|
|
620
|
-
? useAnimationHooks({
|
|
621
|
-
animation,
|
|
622
|
-
style: viewStyle
|
|
623
|
-
})
|
|
624
|
-
: viewStyle;
|
|
625
642
|
const childNode = wrapWithChildren(props, {
|
|
626
643
|
hasVarDec,
|
|
627
644
|
enableBackground: enableBackgroundRef.current,
|
|
628
645
|
textStyle,
|
|
629
646
|
backgroundStyle,
|
|
630
647
|
varContext: varContextRef.current,
|
|
631
|
-
textProps
|
|
648
|
+
textProps,
|
|
649
|
+
innerStyle,
|
|
650
|
+
enableFastImage
|
|
632
651
|
});
|
|
633
|
-
return
|
|
634
|
-
? (<Animated.View {...innerProps}
|
|
652
|
+
return enableAnimation
|
|
653
|
+
? (<Animated.View {...innerProps}>
|
|
635
654
|
{childNode}
|
|
636
655
|
</Animated.View>)
|
|
637
656
|
: (<View {...innerProps}>
|