Skip to content

Commit d53582e

Browse files
authored
fix: tweak modal animation to match default android animations (#1428)
1 parent 97a5a0a commit d53582e

File tree

2 files changed

+63
-34
lines changed

2 files changed

+63
-34
lines changed

example/src/Examples/DialogExample.tsx

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,45 @@ class DialogExample extends React.Component<Props, State> {
5050
colors: { background },
5151
},
5252
} = this.props;
53+
5354
const { visible1, visible2, visible3, visible4, visible5 } = this.state;
55+
5456
return (
5557
<View style={[styles.container, { backgroundColor: background }]}>
56-
<Button onPress={this._openDialog1}>Show Dialog with long text</Button>
57-
<Button onPress={this._openDialog2}>
58-
Show Dialog with radio buttons
58+
<Button
59+
mode="outlined"
60+
onPress={this._openDialog1}
61+
style={styles.button}
62+
>
63+
Long text
64+
</Button>
65+
<Button
66+
mode="outlined"
67+
onPress={this._openDialog2}
68+
style={styles.button}
69+
>
70+
Radio buttons
5971
</Button>
60-
<Button onPress={this._openDialog3}>
61-
Show Dialog with loading indicator
72+
<Button
73+
mode="outlined"
74+
onPress={this._openDialog3}
75+
style={styles.button}
76+
>
77+
Progress indicator
6278
</Button>
63-
<Button onPress={this._openDialog4}>Show undismissable Dialog</Button>
64-
<Button onPress={this._openDialog5}>
65-
Show Dialog with custom colors
79+
<Button
80+
mode="outlined"
81+
onPress={this._openDialog4}
82+
style={styles.button}
83+
>
84+
Undismissable Dialog
85+
</Button>
86+
<Button
87+
mode="outlined"
88+
onPress={this._openDialog5}
89+
style={styles.button}
90+
>
91+
Custom colors
6692
</Button>
6793
<DialogWithLongText visible={visible1} close={this._closeDialog1} />
6894
<DialogWithRadioBtns visible={visible2} close={this._closeDialog2} />
@@ -81,7 +107,10 @@ const styles = StyleSheet.create({
81107
container: {
82108
flex: 1,
83109
backgroundColor: Colors.grey200,
84-
padding: 16,
110+
padding: 12,
111+
},
112+
button: {
113+
margin: 4,
85114
},
86115
});
87116

src/components/Modal.tsx

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ type State = {
4545
rendered: boolean;
4646
};
4747

48+
const DEFAULT_DURATION = 220;
49+
4850
/**
4951
* The Modal component is a simple way to present content above an enclosing view.
5052
* To render the `Modal` above other components, you'll need to wrap it with the [`Portal`](portal.html) component.
@@ -123,42 +125,40 @@ class Modal extends React.Component<Props, State> {
123125
};
124126

125127
private showModal = () => {
126-
const {
127-
theme: {
128-
animation: { scale },
129-
},
130-
} = this.props;
131-
132128
BackHandler.removeEventListener('hardwareBackPress', this.handleBack);
133129
BackHandler.addEventListener('hardwareBackPress', this.handleBack);
134-
Animated.timing(this.state.opacity, {
130+
131+
const { opacity } = this.state;
132+
const { scale } = this.props.theme.animation;
133+
134+
Animated.timing(opacity, {
135135
toValue: 1,
136-
duration: scale * 280,
137-
easing: Easing.ease,
136+
duration: scale * DEFAULT_DURATION,
137+
easing: Easing.out(Easing.cubic),
138138
useNativeDriver: true,
139139
}).start();
140140
};
141141

142142
private hideModal = () => {
143-
const {
144-
theme: {
145-
animation: { scale },
146-
},
147-
} = this.props;
148-
149143
BackHandler.removeEventListener('hardwareBackPress', this.handleBack);
150-
Animated.timing(this.state.opacity, {
144+
145+
const { opacity } = this.state;
146+
const { scale } = this.props.theme.animation;
147+
148+
Animated.timing(opacity, {
151149
toValue: 0,
152-
duration: scale * 280,
153-
easing: Easing.ease,
150+
duration: scale * DEFAULT_DURATION,
151+
easing: Easing.out(Easing.cubic),
154152
useNativeDriver: true,
155153
}).start(({ finished }) => {
156154
if (!finished) {
157155
return;
158156
}
157+
159158
if (this.props.visible && this.props.onDismiss) {
160159
this.props.onDismiss();
161160
}
161+
162162
if (this.props.visible) {
163163
this.showModal();
164164
} else {
@@ -174,7 +174,9 @@ class Modal extends React.Component<Props, State> {
174174
}
175175

176176
render() {
177-
if (!this.state.rendered) return null;
177+
const { rendered, opacity } = this.state;
178+
179+
if (!rendered) return null;
178180

179181
const { children, dismissable, theme, contentContainerStyle } = this.props;
180182
const { colors } = theme;
@@ -191,18 +193,16 @@ class Modal extends React.Component<Props, State> {
191193
<Animated.View
192194
style={[
193195
styles.backdrop,
194-
{ backgroundColor: colors.backdrop, opacity: this.state.opacity },
196+
{ backgroundColor: colors.backdrop, opacity },
195197
]}
196198
/>
197199
</TouchableWithoutFeedback>
198200
<SafeAreaView style={styles.wrapper}>
199201
<Surface
200202
style={
201-
[
202-
{ opacity: this.state.opacity },
203-
styles.content,
204-
contentContainerStyle,
205-
] as StyleProp<ViewStyle>
203+
[{ opacity }, styles.content, contentContainerStyle] as StyleProp<
204+
ViewStyle
205+
>
206206
}
207207
>
208208
{children}

0 commit comments

Comments
 (0)