aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer/src/components/banner/NotificationBanner.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/renderer/src/components/banner/NotificationBanner.tsx')
-rw-r--r--packages/renderer/src/components/banner/NotificationBanner.tsx110
1 files changed, 110 insertions, 0 deletions
diff --git a/packages/renderer/src/components/banner/NotificationBanner.tsx b/packages/renderer/src/components/banner/NotificationBanner.tsx
new file mode 100644
index 0000000..70fe693
--- /dev/null
+++ b/packages/renderer/src/components/banner/NotificationBanner.tsx
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import Alert, { AlertColor } from '@mui/material/Alert';
22import Box from '@mui/material/Box';
23import Typography from '@mui/material/Typography';
24import { styled } from '@mui/material/styles';
25import React, { ReactNode } from 'react';
26import { useTranslation } from 'react-i18next';
27
28const NotificationBannerRoot = styled(Alert)(({ theme }) => ({
29 padding: `7px ${theme.spacing(1)} 6px ${theme.spacing(2)}`,
30 // Match the height of the location bar.
31 minHeight: 53,
32 borderRadius: 0,
33 borderBottom: `1px solid ${theme.palette.divider}`,
34 '.MuiAlert-message': {
35 flexGrow: 1,
36 paddingTop: 0,
37 paddingBottom: 4,
38 display: 'flex',
39 flexWrap: 'wrap',
40 justifyContent: 'center',
41 },
42 '.MuiAlert-action': {
43 paddingLeft: 0,
44 paddingRight: theme.spacing(1),
45 },
46}));
47
48const NotificationBannerText = styled(Typography)(({ theme }) => ({
49 fontSize: 'inherit',
50 paddingTop: theme.spacing(1),
51 paddingRight: theme.spacing(2),
52 flexGrow: 9999,
53}));
54
55const NotificationBannerButtons = styled(Box, {
56 shouldForwardProp: (prop) => prop !== 'hasCloseButton',
57})<{ hasCloseButton: boolean }>(({ theme, hasCloseButton }) => ({
58 fontSize: 'inherit',
59 paddingTop: theme.spacing(0.5),
60 paddingRight: hasCloseButton ? theme.spacing(0.5) : 0,
61 display: 'flex',
62 flexWrap: 'wrap',
63 flexGrow: 1,
64 gap: theme.spacing(1),
65 '.MuiButton-root': {
66 flexGrow: 1,
67 },
68}));
69
70export default function NotificationBanner({
71 severity,
72 icon,
73 onClose,
74 buttons,
75 children,
76}: {
77 severity?: AlertColor;
78 icon?: ReactNode;
79 onClose?: () => void;
80 buttons?: ReactNode;
81 children?: ReactNode;
82}): JSX.Element {
83 const { t } = useTranslation();
84
85 return (
86 /* eslint-disable react/jsx-props-no-spreading -- Conditionally set the onClose prop. */
87 <NotificationBannerRoot
88 severity={severity ?? 'success'}
89 icon={icon ?? false}
90 {...(onClose === undefined ? {} : { onClose })}
91 closeText={t<string>('banner.close')}
92 >
93 {/* eslint-enable react/jsx-props-no-spreading */}
94 <NotificationBannerText>{children}</NotificationBannerText>
95 {buttons && (
96 <NotificationBannerButtons hasCloseButton={onClose !== undefined}>
97 {buttons}
98 </NotificationBannerButtons>
99 )}
100 </NotificationBannerRoot>
101 );
102}
103
104NotificationBanner.defaultProps = {
105 severity: 'success',
106 icon: false,
107 onClose: undefined,
108 buttons: undefined,
109 children: undefined,
110};