-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathNotification.js
121 lines (110 loc) · 3.02 KB
/
Notification.js
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import React from 'react';
import { number, string, func, oneOf } from 'prop-types';
import classnames from 'classnames';
import { pascalize } from 'humps';
import * as olt from '@lightelligence/styles';
const animationDuration = 200;
const Notification = ({
type,
title,
content,
timeout,
onClick,
onClose,
onHide,
...props
}) => {
const timers = React.useRef([]);
const [isOpen, setOpenState] = React.useState(false);
const requestHide = React.useCallback(() => {
setOpenState(false);
timers.current.push(
setTimeout(() => {
if (onHide) onHide();
}, animationDuration),
);
}, [onHide]);
React.useEffect(() => {
const registeredTimers = timers.current;
if (timeout !== 0) {
registeredTimers.push(setTimeout(requestHide, timeout));
}
registeredTimers.push(setTimeout(() => setOpenState(true), 100));
return () => {
registeredTimers.forEach(clearTimeout);
};
}, [requestHide, timeout]);
const clickHandler = React.useCallback(() => {
onClick();
requestHide();
}, [onClick, requestHide]);
const closeHandler = React.useCallback(
(event) => {
if (event.stopPropagation) {
event.stopPropagation();
}
onClose();
requestHide();
},
[onClose, requestHide],
);
return (
<div
className={classnames(
olt.Notification,
type && olt[`Notification${pascalize(type)}`],
type + type + type,
isOpen && olt.isOpen,
)}
onClick={clickHandler}
onKeyDown={() => {}}
role="button"
tabIndex={0}
{...props}
>
<div className={olt.NotificationDialog}>
<header className={olt.NotificationHeader}>{title}</header>
<div className={olt.NotificationContent}>{content}</div>
</div>
<button
type="button"
className={olt.NotificationClose}
onClick={closeHandler}
tabIndex={0}
>
<i
className={classnames(olt.Icon, olt.IconMedium, olt.IconClose)}
data-icon="close"
/>
</button>
</div>
);
};
Notification.propTypes = {
// TODO: oneOf Rendering is broken in guide
// this should be should be
/** The type of the notification. */
type: oneOf(['info', 'success', 'warning', 'error']),
/** Defines the title of the notification. */
title: string,
/** Defines the content of the notification. */
content: string,
/** Set the timeout in ms, use 0 to make the notificaiton stay until the user clicks.. */
timeout: number,
/** Callback when the user clicks the notification. The notification starts closing at this moment. */
onClick: func,
/** Callback when the user clicks the close icon. The notification starts closing at this moment. */
onClose: func,
/** Callback when the notification finishes closing after a click or the timeout. */
onHide: func,
};
Notification.defaultProps = {
type: 'error',
title: '',
content: '',
timeout: 4000,
onClick: () => {},
onClose: () => {},
onHide: () => {},
};
export { Notification };