Skip to content

Commit 09dda82

Browse files
committed
feat(toast): use react-spring for animation
1 parent a1087a6 commit 09dda82

4 files changed

Lines changed: 48 additions & 67 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"focus-trap": "5.0.0",
4444
"react-icons": "3.6.1",
4545
"react-native-web": "0.11.2",
46+
"react-spring": "9.0.0-beta.1",
4647
"ts-essentials": "2.0.5"
4748
},
4849
"devDependencies": {

src/components/Toast/Toast.tsx

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as React from 'react';
2-
import { Animated } from 'react-native';
2+
import { View } from 'react-native';
3+
import { animated, useSpring } from 'react-spring/native';
34
import { Omit } from 'ts-essentials';
45

5-
import { Theme, withTheme } from '../../theme';
66
import { Alert, AlertProps } from '../Alert';
77

8-
// Animation taken from https://medium.com/@norbajunior/react-native-facebook-and-instagram-like-top-bar-notifications-with-animated-api-43c48d0443dd
8+
const AnimatedView = animated(View);
9+
910
export type ToastId = string;
1011

1112
export interface ToastSettings extends Omit<AlertProps, 'onClose'> {
@@ -22,66 +23,35 @@ export interface ToastInstance extends ToastSettings {
2223
onRemove: () => void;
2324
}
2425

25-
export interface ToastProps extends ToastInstance {
26-
theme: Theme;
27-
}
28-
29-
export interface ToastState {
30-
value: Animated.Value;
31-
}
32-
33-
const DEFAULT_VALUE = 500;
34-
35-
class ToastBase extends React.Component<ToastProps, ToastState> {
36-
public closeTimer: number | null = null;
37-
38-
constructor(props: ToastProps) {
39-
super(props);
40-
41-
this.state = {
42-
value: new Animated.Value(-DEFAULT_VALUE),
43-
};
44-
}
45-
46-
public componentDidMount() {
47-
const { onRemove, duration = 3000, offset = 16 } = this.props;
48-
const { value } = this.state;
49-
50-
Animated.sequence([
51-
Animated.spring(value, {
52-
bounciness: 8,
53-
speed: 25,
54-
toValue: offset,
55-
}),
56-
Animated.delay(duration),
57-
Animated.spring(value, {
58-
bounciness: 8,
59-
speed: 25,
60-
toValue: -DEFAULT_VALUE,
61-
}),
62-
]).start(() => onRemove());
63-
}
64-
65-
public render() {
66-
const {
67-
component,
68-
offset,
69-
duration,
70-
id,
71-
onRemove,
72-
...toastSettings
73-
} = this.props;
74-
75-
return (
76-
<Animated.View
77-
style={{
78-
transform: [{ translateY: this.state.value }],
79-
}}
80-
>
81-
{component || <Alert {...toastSettings} onClose={onRemove} />}
82-
</Animated.View>
83-
);
84-
}
85-
}
86-
87-
export const Toast = withTheme(ToastBase);
26+
// tslint:disable-next-line
27+
export interface ToastProps extends ToastInstance {}
28+
29+
export const Toast = (props: ToastProps) => {
30+
const {
31+
component,
32+
id,
33+
onRemove,
34+
duration = 3000,
35+
offset = 16,
36+
...toastSettings
37+
} = props;
38+
39+
const style = useSpring({
40+
config: { tension: 240, friction: 24 },
41+
from: { translateY: -500 },
42+
onRest: () => onRemove(),
43+
to: async next => {
44+
// tslint:disable-next-line
45+
await next({ translateY: 10 });
46+
// tslint:disable-next-line
47+
await next({ translateY: -500, delay: duration });
48+
},
49+
});
50+
51+
return (
52+
// @ts-ignore
53+
<AnimatedView style={{ transform: [{ translateY: style.translateY }] }}>
54+
{component || <Alert {...toastSettings} onClose={onRemove} />}
55+
</AnimatedView>
56+
);
57+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const useSpring = () => {};
2+
export const animated = View => View;

yarn.lock

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@
977977
dependencies:
978978
regenerator-runtime "^0.12.0"
979979

980-
"@babel/runtime@^7.0.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3":
980+
"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3":
981981
version "7.4.3"
982982
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.3.tgz#79888e452034223ad9609187a0ad1fe0d2ad4bdc"
983983
integrity sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==
@@ -10116,6 +10116,14 @@ react-simple-code-editor@^0.9.0:
1011610116
resolved "https://registry.yarnpkg.com/react-simple-code-editor/-/react-simple-code-editor-0.9.10.tgz#1ab5ea7215687ed918c6d0dae90736cf01890905"
1011710117
integrity sha512-80LJwRQS7Wi9Ugh/e6FRHWdcg4oQOpMBDFxyDpORILffrHdV3EIQ1IeX5x7488r05iFgLbVDV4nQ1LRKjgCm0g==
1011810118

10119+
react-spring@9.0.0-beta.1:
10120+
version "9.0.0-beta.1"
10121+
resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.0.0-beta.1.tgz#b7a48da6d3f4e20234b1dd11c78480c932f262b1"
10122+
integrity sha512-9d0wLcvInW3Qw7FNYCC61d2kzebXagF6cZN83xR9Sr+g2J+f/IowaZrUFxDnhSFxyRl2F/Oloo0wIedEOqYfEQ==
10123+
dependencies:
10124+
"@babel/runtime" "^7.3.1"
10125+
prop-types "^15.5.8"
10126+
1011910127
react-test-renderer@16.8.6:
1012010128
version "16.8.6"
1012110129
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.6.tgz#188d8029b8c39c786f998aa3efd3ffe7642d5ba1"

0 commit comments

Comments
 (0)