-
Notifications
You must be signed in to change notification settings - Fork 89
/
Toast.tsx
85 lines (74 loc) · 1.81 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
76
77
78
79
80
81
82
83
84
85
import * as React from 'react'
import classNames from 'classnames'
import { Close } from '../Close/Close'
import './Toast.css'
export enum ToastType {
INFO = 'info',
WARN = 'warn',
ERROR = 'error'
}
export type ToastProps = {
type?: ToastType
title: string | JSX.Element
body: string | JSX.Element
closable?: boolean
timeout?: number
icon?: JSX.Element
className?: string
onClose?: () => void
}
export class Toast extends React.PureComponent<ToastProps> {
mounted = false
closeTimeoutId: number | null = null
componentDidMount(): void {
this.mounted = true
if (this.shouldCloseAfterTimeout()) {
this.closeAfterTimeout()
}
}
componentWillUnmount(): void {
this.mounted = false
}
handleClose = (): void => {
this.props.onClose && this.props.onClose()
}
closeAfterTimeout(): void {
const { timeout } = this.props
this.closeTimeoutId = window
? window.setTimeout(() => {
if (this.mounted) {
this.handleClose()
}
this.closeTimeoutId = null
}, timeout)
: null
}
shouldCloseAfterTimeout(): boolean {
const { timeout } = this.props
return timeout !== undefined && this.closeTimeoutId === null
}
render(): JSX.Element {
const {
type = ToastType.INFO,
title,
body,
closable,
icon,
className
} = this.props
return (
<div
className={classNames('dcl', 'toast', type.toLowerCase(), className)}
>
<div className="toast-info">
{icon && <span className="toast-icon">{icon}</span>}
<div>
{closable ? <Close onClick={this.handleClose} /> : null}
<div className="title">{title}</div>
<div className="body">{body}</div>
</div>
</div>
</div>
)
}
}