1 | import * as React from 'react';
|
2 | import * as PropTypes from 'prop-types';
|
3 |
|
4 | import _get from 'lodash/get';
|
5 |
|
6 | import { withTheme } from '../styled';
|
7 | import { ThemeConfig } from '../types';
|
8 | import Portal from '../Portal';
|
9 |
|
10 | import { Toasts } from './styled';
|
11 | import ToastContainer from './ToastContainer';
|
12 | import Toast from './Toast';
|
13 |
|
14 | export type ToastManagerProps = {
|
15 | theme?: {
|
16 | fannypack: ThemeConfig;
|
17 | };
|
18 | };
|
19 |
|
20 | export const ToastManager: React.FunctionComponent<ToastManagerProps> = ({ theme }) => {
|
21 | const ToastComponent = _get(theme, 'fannypack.Toast.component', Toast);
|
22 | const defaultProps = _get(theme, 'fannypack.Toast.defaultProps', {});
|
23 | const placement = _get(theme, 'fannypack.Toast.placement', 'top-end');
|
24 | const isStacked = _get(theme, 'fannypack.Toast.isStacked', true);
|
25 | return (
|
26 | <Portal>
|
27 | <Toasts placement={placement}>
|
28 | <ToastContainer placement={placement}>
|
29 | {state =>
|
30 | [...(isStacked ? state.toasts : [state.toasts[0]])].filter(Boolean).map(toast => (
|
31 | <ToastComponent
|
32 | key={toast.key}
|
33 | onClickClose={() => state.remove({ key: toast.key })}
|
34 | {...defaultProps}
|
35 | {...toast}
|
36 | >
|
37 | {toast.message}
|
38 | </ToastComponent>
|
39 | ))
|
40 | }
|
41 | </ToastContainer>
|
42 | </Toasts>
|
43 | </Portal>
|
44 | );
|
45 | };
|
46 |
|
47 | export const toastManagerPropTypes = {
|
48 | theme: PropTypes.object as PropTypes.Validator<ToastManagerProps['theme']>
|
49 | };
|
50 | ToastManager.propTypes = toastManagerPropTypes;
|
51 |
|
52 | export const toastManagerDefaultProps = {
|
53 | theme: {
|
54 | fannypack: {}
|
55 | }
|
56 | };
|
57 | ToastManager.defaultProps = toastManagerDefaultProps;
|
58 |
|
59 | export default withTheme(ToastManager);
|