UNPKG

5.54 kBJavaScriptView Raw
1function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
3import * as React from 'react';
4import { Animated, SafeAreaView, StyleSheet } from 'react-native';
5import Button from './Button';
6import Surface from './Surface';
7import Text from './Typography/Text';
8import { withTheme } from '../core/theming';
9const DURATION_SHORT = 4000;
10const DURATION_MEDIUM = 7000;
11const DURATION_LONG = 10000;
12/**
13 * Snackbars provide brief feedback about an operation through a message at the bottom of the screen.
14 * Snackbar by default uses `onSurface` color from theme.
15 * <div class="screenshots">
16 * <img class="medium" src="screenshots/snackbar.gif" />
17 * </div>
18 *
19 * ## Usage
20 * ```js
21 * import * as React from 'react';
22 * import { View, StyleSheet } from 'react-native';
23 * import { Button, Snackbar } from 'react-native-paper';
24 *
25 * const MyComponent = () => {
26 * const [visible, setVisible] = React.useState(false);
27 *
28 * const onToggleSnackBar = () => setVisible(!visible);
29 *
30 * const onDismissSnackBar = () => setVisible(false);
31 *
32 * return (
33 * <View style={styles.container}>
34 * <Button onPress={onToggleSnackBar}>{visible ? 'Hide' : 'Show'}</Button>
35 * <Snackbar
36 * visible={visible}
37 * onDismiss={onDismissSnackBar}
38 * action={{
39 * label: 'Undo',
40 * onPress: () => {
41 * // Do something
42 * },
43 * }}>
44 * Hey there! I'm a Snackbar.
45 * </Snackbar>
46 * </View>
47 * );
48 * };
49 *
50 * const styles = StyleSheet.create({
51 * container: {
52 * flex: 1,
53 * justifyContent: 'space-between',
54 * },
55 * });
56 *
57 * export default MyComponent;
58 * ```
59 */
60
61const Snackbar = _ref => {
62 let {
63 visible,
64 action,
65 duration = DURATION_MEDIUM,
66 onDismiss,
67 children,
68 wrapperStyle,
69 style,
70 theme,
71 ...rest
72 } = _ref;
73 const {
74 current: opacity
75 } = React.useRef(new Animated.Value(0.0));
76 const [hidden, setHidden] = React.useState(!visible);
77 const hideTimeout = React.useRef(undefined);
78 const {
79 scale
80 } = theme.animation;
81 React.useEffect(() => {
82 return () => {
83 if (hideTimeout.current) clearTimeout(hideTimeout.current);
84 };
85 }, []);
86 React.useLayoutEffect(() => {
87 if (visible) {
88 // show
89 if (hideTimeout.current) clearTimeout(hideTimeout.current);
90 setHidden(false);
91 Animated.timing(opacity, {
92 toValue: 1,
93 duration: 200 * scale,
94 useNativeDriver: true
95 }).start(_ref2 => {
96 let {
97 finished
98 } = _ref2;
99
100 if (finished) {
101 const isInfinity = duration === Number.POSITIVE_INFINITY || duration === Number.NEGATIVE_INFINITY;
102
103 if (finished && !isInfinity) {
104 hideTimeout.current = setTimeout(onDismiss, duration);
105 }
106 }
107 });
108 } else {
109 // hide
110 if (hideTimeout.current) clearTimeout(hideTimeout.current);
111 Animated.timing(opacity, {
112 toValue: 0,
113 duration: 100 * scale,
114 useNativeDriver: true
115 }).start(_ref3 => {
116 let {
117 finished
118 } = _ref3;
119 if (finished) setHidden(true);
120 });
121 }
122 }, [visible, duration, opacity, scale, onDismiss]);
123 const {
124 colors,
125 roundness
126 } = theme;
127 if (hidden) return null;
128 const {
129 style: actionStyle,
130 label: actionLabel,
131 onPress: onPressAction,
132 ...actionProps
133 } = action || {};
134 return /*#__PURE__*/React.createElement(SafeAreaView, {
135 pointerEvents: "box-none",
136 style: [styles.wrapper, wrapperStyle]
137 }, /*#__PURE__*/React.createElement(Surface, _extends({
138 pointerEvents: "box-none",
139 accessibilityLiveRegion: "polite",
140 style: [styles.container, {
141 borderRadius: roundness,
142 opacity: opacity,
143 transform: [{
144 scale: visible ? opacity.interpolate({
145 inputRange: [0, 1],
146 outputRange: [0.9, 1]
147 }) : 1
148 }]
149 }, {
150 backgroundColor: colors.onSurface
151 }, style]
152 }, rest), /*#__PURE__*/React.createElement(Text, {
153 style: [styles.content, {
154 marginRight: action ? 0 : 16,
155 color: colors.surface
156 }]
157 }, children), action ? /*#__PURE__*/React.createElement(Button, _extends({
158 onPress: () => {
159 onPressAction === null || onPressAction === void 0 ? void 0 : onPressAction();
160 onDismiss();
161 },
162 style: [styles.button, actionStyle],
163 color: colors.accent,
164 compact: true,
165 mode: "text"
166 }, actionProps), actionLabel) : null));
167};
168/**
169 * Show the Snackbar for a short duration.
170 */
171
172
173Snackbar.DURATION_SHORT = DURATION_SHORT;
174/**
175 * Show the Snackbar for a medium duration.
176 */
177
178Snackbar.DURATION_MEDIUM = DURATION_MEDIUM;
179/**
180 * Show the Snackbar for a long duration.
181 */
182
183Snackbar.DURATION_LONG = DURATION_LONG;
184const styles = StyleSheet.create({
185 wrapper: {
186 position: 'absolute',
187 bottom: 0,
188 width: '100%'
189 },
190 container: {
191 elevation: 6,
192 flexDirection: 'row',
193 justifyContent: 'space-between',
194 alignItems: 'center',
195 margin: 8,
196 borderRadius: 4
197 },
198 content: {
199 marginLeft: 16,
200 marginVertical: 14,
201 flexWrap: 'wrap',
202 flex: 1
203 },
204 button: {
205 marginHorizontal: 8,
206 marginVertical: 6
207 }
208});
209export default withTheme(Snackbar);
210//# sourceMappingURL=Snackbar.js.map
\No newline at end of file