UNPKG

6.32 kBPlain TextView Raw
1import { Box, Flex } from '../primitives';
2import Button from '../Button';
3import Heading from '../Heading';
4import Icon, { LocalIconProps } from '../Icon/Icon';
5import Pane from '../Pane';
6import styled, { css, keyframes, palette, space, theme, selector } from '../styled';
7
8import { LocalToastProps } from './Toast';
9import { ToastCloseProps } from './ToastClose';
10import { ToastTitleProps } from './ToastTitle';
11
12export const ToastClose = styled(Button)<ToastCloseProps>`
13 width: 24px;
14 min-height: 24px;
15 padding: 0;
16 text-align: right;
17
18 ${props =>
19 props.isAbsolute
20 ? css`
21 position: absolute;
22 right: ${space(2)}rem;
23 top: ${space(2)}rem;
24 `
25 : css`
26 margin: 0 ${space(2)}rem;
27 `};
28
29 &:hover {
30 background-color: ${palette('white700')};
31 & {
32 ${theme('fannypack.Toast.Close.hover')};
33 }
34 }
35
36 & {
37 ${theme('fannypack.Toast.Close.base')};
38 }
39`;
40
41export const ToastTitle = styled(Heading)<ToastTitleProps>`
42 & {
43 ${theme('fannypack.Toast.Title.base')};
44 }
45`;
46
47export const ToastIconWrapper = styled(Flex)<any>`
48 margin-right: ${space(3)}rem;
49 margin-left: -${space(1)}rem;
50 align-items: center;
51
52 & {
53 ${theme('fannypack.Toast.Icon.wrapper')};
54 }
55`;
56
57export const ToastIcon = styled(Icon)<LocalIconProps>`
58 & {
59 ${theme('fannypack.Toast.Icon.base')};
60 }
61`;
62
63export const Content = styled(Flex)<{ // eslint-disable-line
64 showCountdownBar?: boolean;
65}>`
66 padding: ${space(4)}rem;
67 padding-right: ${space(8)}rem;
68
69 ${props =>
70 props.showCountdownBar
71 ? css`
72 padding-left: calc(${space(4)}rem + 5px);
73 `
74 : css`
75 padding-left: ${space(4)}rem;
76 `};
77
78 & {
79 ${theme('fannypack.Toast.Content.base')};
80 }
81`;
82
83export const heightCountdown = keyframes`
84 from {
85 height: calc(100% + 2px);
86 }
87
88 to {
89 height: 0%;
90 }
91`;
92export const widthCountdown = keyframes`
93 from {
94 width: calc(100% + 2px);
95 }
96
97 to {
98 width: 0%;
99 }
100`;
101export const CountdownBar = styled(Box)<{ // eslint-disable-line
102 autoDismissTimeout?: number;
103 isBackground?: boolean;
104 isHorizontal?: boolean;
105 type?: string;
106}>`
107 position: absolute;
108
109 ${props =>
110 props.isHorizontal
111 ? css`
112 border-bottom-right-radius: 3px;
113 border-bottom-left-radius: 3px;
114 bottom: 0;
115 height: 5px;
116 right: -1px;
117 width: calc(100% + 2px);
118 `
119 : css`
120 border-top-left-radius: 3px;
121 border-bottom-left-radius: 3px;
122 bottom: -1px;
123 height: calc(100% + 2px);
124 margin-left: -1px;
125 width: 5px;
126 `};
127
128 ${props =>
129 props.type &&
130 css`
131 background-color: ${props.isBackground ? palette(`${props.type}Tint`) : palette(props.type)};
132 `};
133
134 ${props =>
135 props.autoDismissTimeout &&
136 css`
137 ${(props: any) =>
138 props.isHorizontal
139 ? css`
140 animation: ${widthCountdown} ${props.autoDismissTimeout}ms linear forwards;
141 border-bottom-left-radius: unset;
142 `
143 : css`
144 animation: ${heightCountdown} ${props.autoDismissTimeout}ms linear forwards;
145 border-top-left-radius: unset;
146 `};
147
148 & {
149 ${theme('fannypack.Toast.CountdownBar.autoDismissTimeout')};
150 }
151 `};
152
153 ${props =>
154 props.isBackground &&
155 css`
156 & {
157 ${theme('fannypack.Toast.CountdownBar.background')};
158 }
159 `};
160
161 & {
162 ${theme('fannypack.Toast.CountdownBar.base')};
163 }
164`;
165
166const tintAttributes = css<LocalToastProps>`
167 background-color: ${props => props.type && palette(`${props.type}Tint`)(props)};
168 color: ${props => props.type && palette(`${props.type}TintInverted`)(props)};
169 fill: ${props => props.type && palette(`${props.type}TintInverted`)(props)};
170 ${theme('fannypack.Toast.tint')};
171`;
172export const Toast = styled(Pane)<LocalToastProps>`
173 align-items: center;
174 display: flex;
175 font-size: ${theme('fannypack.fontSizes.150')}rem;
176 justify-content: space-between;
177 position: relative;
178 width: 350px;
179
180 &:not(:last-child) {
181 margin-bottom: ${space(4)}rem;
182 }
183
184 & {
185 ${props => props.hasTint && tintAttributes};
186 }
187
188 & {
189 ${theme('fannypack.Toast.base')};
190 }
191`;
192
193const fromLeft = keyframes`
194 from {
195 transform: translateX(-120%);
196 }
197
198 to {
199 transform: translateX(0);
200 }
201`;
202const fromRight = keyframes`
203 from {
204 transform: translateX(120%);
205 }
206
207 to {
208 transform: translateX(0);
209 }
210`;
211const fromTop = keyframes`
212 from {
213 transform: translateY(-120%);
214 }
215
216 to {
217 transform: translateY(0);
218 }
219`;
220const fromBottom = keyframes`
221 from {
222 transform: translateY(120%);
223 }
224
225 to {
226 transform: translateY(0);
227 }
228`;
229export const placementAttributes: { [key: string]: any } = {
230 'top-start': css`
231 top: 1rem;
232 left: 1rem;
233
234 & ${selector(Toast)} {
235 animation: ${fromLeft} 300ms ease-in-out forwards;
236 }
237 `,
238 top: css`
239 top: 1rem;
240 left: 50%;
241 transform: translateX(-50%);
242
243 & ${selector(Toast)} {
244 animation: ${fromTop} 300ms ease-in-out forwards;
245 }
246 `,
247 'top-end': css`
248 top: 1rem;
249 right: 1rem;
250
251 & ${selector(Toast)} {
252 animation: ${fromRight} 300ms ease-in-out forwards;
253 }
254 `,
255 left: css`
256 left: 1rem;
257 top: 50%;
258 transform: translateY(-50%);
259
260 & ${selector(Toast)} {
261 animation: ${fromLeft} 300ms ease-in-out forwards;
262 }
263 `,
264 right: css`
265 right: 1rem;
266 top: 50%;
267 transform: translateY(-50%);
268
269 & ${selector(Toast)} {
270 animation: ${fromRight} 300ms ease-in-out forwards;
271 }
272 `,
273 'bottom-start': css`
274 bottom: 1rem;
275 left: 1rem;
276
277 & ${selector(Toast)} {
278 animation: ${fromLeft} 300ms ease-in-out forwards;
279 }
280 `,
281 bottom: css`
282 bottom: 1rem;
283 left: 50%;
284 transform: translateX(-50%);
285
286 & ${selector(Toast)} {
287 animation: ${fromBottom} 300ms ease-in-out forwards;
288 }
289 `,
290 'bottom-end': css`
291 bottom: 1rem;
292 right: 1rem;
293
294 & ${selector(Toast)} {
295 animation: ${fromRight} 300ms ease-in-out forwards;
296 }
297 `
298};
299export const Toasts = styled(Box)<{ placement: string }>`
300 position: fixed;
301 z-index: 99999;
302
303 ${props => placementAttributes[props.placement]};
304
305 & {
306 ${theme('fannypack.Toasts.base')};
307 }
308`;
309
310export default Toast;
311
\No newline at end of file