This repository has been archived by the owner on Jan 18, 2024. It is now read-only.
/
GlobalToasts.js
154 lines (137 loc) · 3.74 KB
/
GlobalToasts.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import styled, { css } from 'react-emotion';
import { connect } from 'react-redux';
import * as React from 'react';
import * as SVG from 'app/common/svg';
import * as Constants from 'app/common/constants';
import withRedux from 'app/higher-order/withRedux';
const STYLES_TOAST_CONTAINER = css`
max-width: ${Constants.breakpoints.sidebar}px;
line-height: 1.5;
position: fixed;
bottom: 24px;
right: 24px;
width: 100%;
`;
const STYLES_TOAST = css`
background: ${Constants.colors.white};
box-shadow: 0 1px 4px rgba(0, 0, 30, 0.3);
user-select: none;
width: 100%;
border-radius: 4px;
margin-top: 16px;
transition: 200ms ease all;
animation: 400ms ease fadeInRight;
`;
const STYLES_TOAST_BODY = css`
font-family: ${Constants.fontFamilies.regular};
color: ${Constants.colors.black};
font-size: 12px;
overflow-wrap: break-word;
white-space: pre-wrap;
padding: 16px;
`;
const STYLES_TOAST_TOP = css`
font-family: ${Constants.fontFamilies.mono};
text-transform: uppercase;
font-size: 10px;
height: 30px;
padding: 0 16px 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 4px 4px 0 0;
`;
const STYLES_TOAST_TOP_NORMAL = css`
border-bottom: 1px solid ${Constants.colors.border};
background: ${Constants.colors.border};
`;
const STYLES_TOAST_TOP_WARNING = css`
border-bottom: 1px solid ${Constants.colors.red};
background: ${Constants.colors.red};
color: ${Constants.colors.white};
`;
const STYLES_TOAST_TOP_SUCCESS = css`
border-bottom: 1px solid ${Constants.colors.green};
background: ${Constants.colors.green};
color: ${Constants.colors.white};
`;
const STYLES_TOAST_TOP_ALERT = css`
border-bottom: 1px solid ${Constants.colors.yellow};
background: ${Constants.colors.yellow};
color: ${Constants.colors.white};
`;
const STYLES_TOAST_TOP_LEFT = css`
min-width: 25%;
padding-top: 4px;
width: 100%;
overflow-wrap: break-word;
width: 100%;
`;
const STYLES_TOAST_TOP_RIGHT = css`
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 0 0 0 16px;
cursor: pointer;
`;
export class Toast extends React.Component {
static defaultProps = {
name: 'notice',
};
render() {
const dismissElement = this.props.onDismiss ? (
<span className={STYLES_TOAST_TOP_RIGHT} onClick={this.props.onDismiss}>
<SVG.Dismiss size="16px" />
</span>
) : null;
return (
<div className={STYLES_TOAST} style={this.props.style}>
<header
className={`${STYLES_TOAST_TOP}
${
this.props.name === 'notice' || this.props.name === 'info'
? STYLES_TOAST_TOP_NORMAL
: ''
}
${
this.props.name === 'warning' || this.props.name === 'error'
? STYLES_TOAST_TOP_WARNING
: ''
}
${this.props.name === 'success' ? STYLES_TOAST_TOP_SUCCESS : ''}
${this.props.name === 'alert' ? STYLES_TOAST_TOP_ALERT : ''}`}>
<span className={STYLES_TOAST_TOP_LEFT}>{this.props.name}</span>
{dismissElement}
</header>
<div className={STYLES_TOAST_BODY}>{this.props.children}</div>
</div>
);
}
}
@connect(state => {
return {
toasts: state.toasts,
};
})
export default class GlobalToasts extends React.Component {
_handleDismiss = id => {
this.props.dispatch({
type: 'REMOVE_TOAST',
id,
});
};
render() {
return (
<div className={STYLES_TOAST_CONTAINER}>
{this.props.toasts.map(t => {
return (
<Toast key={t.id} name={t.name} onDismiss={() => this._handleDismiss(t.id)}>
{t.text}
</Toast>
);
})}
</div>
);
}
}