Skip to content

Commit f1696df

Browse files
committed
feat:添加modal中间显示[#627]
1 parent c604b14 commit f1696df

File tree

3 files changed

+66
-14
lines changed

3 files changed

+66
-14
lines changed

example/examples/src/routes/Modal/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export default class ModalView extends Component<ModalViewProps> {
2222
{label: 'left', value: 'left'},
2323
{label: 'top', value: 'top'},
2424
{label: 'bottom', value: 'bottom'},
25+
{label: 'middle', value: 'middle'},
2526
];
2627
render() {
2728
const {route} = this.props;
@@ -34,7 +35,7 @@ export default class ModalView extends Component<ModalViewProps> {
3435
<Body style={{paddingLeft: 16, paddingRight: 16}}>
3536
<Card title="基础实例">
3637
<Modal
37-
placement={this.state.direction as 'left' | 'right' | 'top' | 'bottom'}
38+
placement={this.state.direction as 'left' | 'right' | 'top' | 'bottom' | 'middle'}
3839
// maskClosable={false}
3940
visible={this.state.modalVisible}
4041
onClosed={() => this.setState({modalVisible: false})}

packages/core/src/Modal/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ function ButtonGroupView() {
1818
const [topModal,setTopModal]= useState(false)
1919
const [leftModal,setLeftModal]= useState(false)
2020
const [rightModal,setRightModal]= useState(false)
21+
const [middleModal,setMiddleModal]= useState(false)
2122
const data = Array.from(new Array(24)).map((_val, i) => {
2223
return { icon: <Icon name="heart-on" color="red" />, text: `${i}`}
2324
});
@@ -73,6 +74,16 @@ function ButtonGroupView() {
7374
</View>
7475
</SafeAreaView>
7576
</Modal>
77+
<Modal visible={middleModal} placement='middle'>
78+
<SafeAreaView style={{width:600}}>
79+
<View>
80+
<Grid data={data} columns='6' hasLine={false}/>
81+
<Button onPress={() => setMiddleModal(false)}>
82+
隐藏中间弹出的模态框
83+
</Button>
84+
</View>
85+
</SafeAreaView>
86+
</Modal>
7687
<Button onPress={() => setLowerModal(true)}>
7788
下面显示
7889
</Button>
@@ -85,6 +96,9 @@ function ButtonGroupView() {
8596
<Button onPress={() => setRightModal(true)}>
8697
右边显示
8798
</Button>
99+
<Button onPress={() => setMiddleModal(true)}>
100+
中间显示
101+
</Button>
88102
</Fragment>
89103
);
90104
}
@@ -97,7 +111,7 @@ export default ButtonGroupView
97111

98112
| 参数 | 说明 | 类型 | 默认值 |
99113
|------|------|-----|------|
100-
| placement | 模态框的方向 | `'top' \| 'right' \| 'bottom' \| 'left'` | bottom |
114+
| placement | 模态框的方向 | `'top' \| 'right' \| 'bottom' \| 'left' \| 'middle'` | bottom |
101115
| onClosed | 关闭函数 | `() => void` | - |
102116
| containerStyle | 样式 | `ViewStyle` | - |
103117

packages/core/src/Modal/index.tsx

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useMemo, useRef, useEffect } from 'react';
1+
import React, { useState, useMemo, useRef, useEffect, useReducer } from 'react';
22
import { Animated, StyleSheet, LayoutChangeEvent, Dimensions, ViewStyle } from 'react-native';
33
import MaskLayer, { MaskLayerProps } from '../MaskLayer';
44
import { Theme } from '../theme';
@@ -8,20 +8,35 @@ const MainWidth = Dimensions.get('window').width;
88
const MainHeight = Dimensions.get('window').height;
99

1010
export interface ModalProps extends MaskLayerProps {
11-
placement?: 'top' | 'right' | 'bottom' | 'left';
11+
placement?: 'top' | 'right' | 'bottom' | 'left' | 'middle';
1212
onClosed?: () => void;
1313
containerStyle?: ViewStyle;
1414
}
1515

16+
interface StoreType {
17+
layoutHeight: number;
18+
layoutWidth: number;
19+
}
20+
21+
export const reducer: React.Reducer<StoreType, Partial<StoreType>> = (state, action) => {
22+
return {
23+
...state,
24+
...action,
25+
};
26+
};
27+
1628
const Modal = (props: ModalProps = {}) => {
1729
const { onClosed, visible, children, placement = 'bottom', containerStyle, ...otherProps } = props;
1830
const theme = useTheme<Theme>();
1931
const AnimatedOpacity = useRef(new Animated.Value(0)).current;
20-
const [layoutHeight, setLayoutHeight] = useState(0);
21-
const [layoutWidth, setLayoutWidth] = useState(0);
32+
const [{ layoutHeight, layoutWidth }, dispatch] = useReducer(reducer, { layoutHeight: 0, layoutWidth: 0 });
2233
const [translateValue] = useState(new Animated.Value(0));
23-
const isVertical = /^(top|bottom)$/.test(placement);
24-
const isHorizontal = /^(left|right)$/.test(placement);
34+
35+
const { isVertical, isHorizontal } = useMemo(() => {
36+
const isVertical = /^(top|bottom)$/.test(placement);
37+
const isHorizontal = /^(left|right)$/.test(placement);
38+
return { isVertical, isHorizontal };
39+
}, [placement]);
2540

2641
useEffect(() => {
2742
function getTransformSize() {
@@ -37,6 +52,9 @@ const Modal = (props: ModalProps = {}) => {
3752
if (placement === 'right') {
3853
return layoutWidth;
3954
}
55+
if (placement === 'middle') {
56+
return layoutWidth;
57+
}
4058
return 0;
4159
}
4260
const result = getTransformSize();
@@ -82,20 +100,30 @@ const Modal = (props: ModalProps = {}) => {
82100
if (isHorizontal) {
83101
translateStyle.translateX = translateValue;
84102
}
103+
if (placement === 'middle') {
104+
translateStyle.translateY = translateValue;
105+
}
85106

86107
const child = useMemo(
87108
() => (
88109
<Animated.View
89-
style={[styles.content, placement && styles[placement], { opacity: AnimatedOpacity }, containerStyle]}
110+
style={[
111+
styles.content,
112+
placement && styles[placement],
113+
placement === 'middle' && styles.middle_warp,
114+
{ opacity: AnimatedOpacity },
115+
containerStyle,
116+
]}
90117
>
91118
<Animated.View
92119
onLayout={(event: LayoutChangeEvent) => {
93120
const { height, width } = event.nativeEvent.layout;
94-
if (!layoutHeight && isVertical) {
95-
setLayoutHeight(height);
96-
}
97-
if (!layoutWidth && isHorizontal) {
98-
setLayoutWidth(width);
121+
if (placement === 'middle') {
122+
dispatch({ layoutHeight: height, layoutWidth: width });
123+
} else if (!layoutHeight && isVertical) {
124+
dispatch({ layoutHeight: height });
125+
} else if (!layoutWidth && isHorizontal) {
126+
dispatch({ layoutWidth: width });
99127
}
100128
}}
101129
style={[
@@ -165,4 +193,13 @@ const styles = StyleSheet.create({
165193
height: MainHeight,
166194
right: 0,
167195
},
196+
middle: {},
197+
middle_warp: {
198+
bottom: 0,
199+
top: 0,
200+
right: 0,
201+
left: 0,
202+
justifyContent: 'center',
203+
alignItems: 'center',
204+
},
168205
});

0 commit comments

Comments
 (0)