-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Toast.tsx
75 lines (67 loc) · 1.92 KB
/
Toast.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import React from "react";
import capitalize from "lodash/capitalize";
import { Slide, toast as toastifyToast } from "react-toastify";
import "react-toastify/dist/ReactToastify.min.css";
import type { ToastProps } from "./Toast.types";
import { StyledButton, StyledToast, ToastBody } from "./Toast.styles";
import { getIconByKind } from "../Icon/getIconByKind";
/**
* TODO:
* - Look up accessibility features for toasts (spectrum, MDN, what toastify does and does not support)
* @constructor
*/
function Toast({ ...rest }: ToastProps) {
return (
<StyledToast
autoClose={5000}
closeButton={false}
draggable={false}
hideProgressBar
pauseOnHover
position={toastifyToast.POSITION.TOP_CENTER}
rtl={false}
transition={Slide}
{...rest}
/>
);
}
// content is of type string and not type ToastContent because we do not want to
// allow developers to pass in their own components.
const toast = {
show: (content: string, options?: ToastProps) => {
const actionText = capitalize(options?.action?.text);
const icon = getIconByKind(options?.kind);
// generate a unique toastId with the options given to it
const toastId = JSON.stringify({ ...options, content });
return toastifyToast(
<ToastBody kind="body-m">
{content}
{actionText && (
<StyledButton
kind="tertiary"
onClick={() => {
options?.action?.effect && options?.action?.effect();
toastifyToast.dismiss();
}}
{...options?.action}
>
{actionText}
</StyledButton>
)}
</ToastBody>,
{
icon: icon,
toastId,
type: options?.kind,
closeOnClick: !actionText,
...options,
},
);
},
dismiss: () => toastifyToast.dismiss(),
};
Toast.displayName = "Toast";
Toast.defaultProps = {
kind: undefined,
};
export { Toast, toast };