@mpxjs/webpack-plugin 2.9.66 → 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/dependencies/RecordGlobalComponentsDependency.js +11 -12
- package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
- package/lib/index.js +29 -8
- package/lib/json-compiler/index.js +2 -11
- package/lib/loader.js +24 -45
- package/lib/native-loader.js +49 -64
- package/lib/platform/json/wx/index.js +3 -10
- package/lib/platform/style/wx/index.js +15 -10
- 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/index.js +4 -3
- package/lib/react/processJSON.js +5 -13
- package/lib/react/processMainScript.js +7 -3
- package/lib/react/processScript.js +3 -4
- package/lib/react/processStyles.js +14 -4
- package/lib/react/processTemplate.js +2 -2
- package/lib/resolver/AddModePlugin.js +20 -7
- 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 +44 -9
- 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-checkbox-group.jsx +30 -17
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-form.jsx +33 -24
- package/lib/runtime/components/react/dist/mpx-icon.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +44 -38
- package/lib/runtime/components/react/dist/mpx-label.jsx +10 -7
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -17
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +378 -294
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
- 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-radio-group.jsx +30 -17
- package/lib/runtime/components/react/dist/mpx-radio.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +49 -29
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-switch.jsx +8 -1
- package/lib/runtime/components/react/dist/mpx-text.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +46 -27
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +20 -6
- 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/useAnimationHooks.js +96 -8
- package/lib/runtime/components/react/dist/utils.jsx +66 -6
- package/lib/runtime/components/react/getInnerListeners.ts +3 -16
- package/lib/runtime/components/react/mpx-button.tsx +42 -9
- 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-checkbox-group.tsx +52 -29
- package/lib/runtime/components/react/mpx-checkbox.tsx +1 -1
- package/lib/runtime/components/react/mpx-form.tsx +42 -34
- package/lib/runtime/components/react/mpx-icon.tsx +1 -1
- package/lib/runtime/components/react/mpx-image/index.tsx +2 -3
- package/lib/runtime/components/react/mpx-input.tsx +68 -66
- package/lib/runtime/components/react/mpx-label.tsx +11 -8
- package/lib/runtime/components/react/mpx-movable-area.tsx +11 -19
- package/lib/runtime/components/react/mpx-movable-view.tsx +456 -334
- package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
- 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-radio-group.tsx +55 -29
- package/lib/runtime/components/react/mpx-radio.tsx +1 -1
- package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
- package/lib/runtime/components/react/mpx-scroll-view.tsx +81 -36
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +2 -2
- package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
- package/lib/runtime/components/react/mpx-swiper-item.tsx +1 -1
- package/lib/runtime/components/react/mpx-switch.tsx +10 -2
- package/lib/runtime/components/react/mpx-text.tsx +1 -1
- package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
- package/lib/runtime/components/react/mpx-view.tsx +58 -28
- package/lib/runtime/components/react/mpx-web-view.tsx +23 -6
- 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/useAnimationHooks.ts +97 -13
- package/lib/runtime/components/react/useNodesRef.ts +1 -0
- package/lib/runtime/components/react/utils.tsx +94 -8
- package/lib/runtime/optionProcessorReact.js +0 -15
- package/lib/runtime/swanHelper.wxs +1 -1
- package/lib/style-compiler/index.js +1 -1
- package/lib/style-compiler/plugins/scope-id.js +1 -0
- package/lib/template-compiler/compiler.js +47 -16
- package/lib/template-compiler/gen-node-react.js +2 -2
- package/lib/template-compiler/index.js +4 -4
- package/lib/utils/pre-process-json.js +113 -0
- package/lib/web/index.js +5 -4
- package/lib/web/processJSON.js +5 -13
- package/lib/web/processTemplate.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;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ✔ bindchange
|
|
3
3
|
*/
|
|
4
|
-
import { useRef, forwardRef, useContext } from 'react';
|
|
4
|
+
import { useRef, forwardRef, useContext, useMemo, useEffect } from 'react';
|
|
5
5
|
import { View } from 'react-native';
|
|
6
6
|
import { warn } from '@mpxjs/utils';
|
|
7
7
|
import { FormContext, RadioGroupContext } from './context';
|
|
@@ -9,7 +9,9 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
|
9
9
|
import useNodesRef from './useNodesRef';
|
|
10
10
|
import { useLayout, useTransformStyle, wrapChildren } from './utils';
|
|
11
11
|
const radioGroup = forwardRef((props, ref) => {
|
|
12
|
-
const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight
|
|
12
|
+
const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
13
|
+
const propsRef = useRef({});
|
|
14
|
+
propsRef.current = props;
|
|
13
15
|
const formContext = useContext(FormContext);
|
|
14
16
|
let formValuesMap;
|
|
15
17
|
if (formContext) {
|
|
@@ -28,16 +30,13 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
28
30
|
const nodeRef = useRef(null);
|
|
29
31
|
useNodesRef(props, ref, nodeRef, { defaultStyle });
|
|
30
32
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
31
|
-
const
|
|
33
|
+
const getValue = () => {
|
|
32
34
|
for (const key in groupValue) {
|
|
33
35
|
if (groupValue[key].checked) {
|
|
34
36
|
return key;
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
|
-
const getValue = () => {
|
|
39
|
-
return getSelectionValue();
|
|
40
|
-
};
|
|
41
40
|
const resetValue = () => {
|
|
42
41
|
Object.keys(groupValue).forEach((key) => {
|
|
43
42
|
groupValue[key].checked = false;
|
|
@@ -52,15 +51,29 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
52
51
|
formValuesMap.set(props.name, { getValue, resetValue });
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
return () => {
|
|
56
|
+
if (formValuesMap && props.name) {
|
|
57
|
+
formValuesMap.delete(props.name);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}, []);
|
|
61
|
+
const contextValue = useMemo(() => {
|
|
62
|
+
const notifyChange = (evt) => {
|
|
63
|
+
const { bindchange } = propsRef.current;
|
|
64
|
+
bindchange &&
|
|
65
|
+
bindchange(getCustomEvent('tap', evt, {
|
|
66
|
+
layoutRef,
|
|
67
|
+
detail: {
|
|
68
|
+
value: getValue()
|
|
69
|
+
}
|
|
70
|
+
}, propsRef.current));
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
groupValue,
|
|
74
|
+
notifyChange
|
|
75
|
+
};
|
|
76
|
+
}, []);
|
|
64
77
|
const innerProps = useInnerProps(props, {
|
|
65
78
|
ref: nodeRef,
|
|
66
79
|
style: { ...normalStyle, ...layoutStyle },
|
|
@@ -69,7 +82,7 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
69
82
|
layoutRef
|
|
70
83
|
});
|
|
71
84
|
return (<View {...innerProps}>
|
|
72
|
-
<RadioGroupContext.Provider value={
|
|
85
|
+
<RadioGroupContext.Provider value={contextValue}>
|
|
73
86
|
{wrapChildren(props, {
|
|
74
87
|
hasVarDec,
|
|
75
88
|
varContext: varContextRef.current
|
|
@@ -77,5 +90,5 @@ const radioGroup = forwardRef((props, ref) => {
|
|
|
77
90
|
</RadioGroupContext.Provider>
|
|
78
91
|
</View>);
|
|
79
92
|
});
|
|
80
|
-
radioGroup.displayName = '
|
|
93
|
+
radioGroup.displayName = 'MpxRadioGroup';
|
|
81
94
|
export default radioGroup;
|