aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/graph/SlideInDialog.tsx
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-02-23 19:03:03 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-02-23 19:13:23 +0100
commitcf07f20847642aec1eafe6234c2ce35264bbaabb (patch)
tree3d89fbd37db49f815eba4215dfc3d3800ff93970 /subprojects/frontend/src/graph/SlideInDialog.tsx
parentfeat(frontend): add top bar logo (diff)
downloadrefinery-cf07f20847642aec1eafe6234c2ce35264bbaabb.tar.gz
refinery-cf07f20847642aec1eafe6234c2ce35264bbaabb.tar.zst
refinery-cf07f20847642aec1eafe6234c2ce35264bbaabb.zip
feat(frontend): graph export formal selector
Diffstat (limited to 'subprojects/frontend/src/graph/SlideInDialog.tsx')
-rw-r--r--subprojects/frontend/src/graph/SlideInDialog.tsx109
1 files changed, 109 insertions, 0 deletions
diff --git a/subprojects/frontend/src/graph/SlideInDialog.tsx b/subprojects/frontend/src/graph/SlideInDialog.tsx
new file mode 100644
index 00000000..d9060fb0
--- /dev/null
+++ b/subprojects/frontend/src/graph/SlideInDialog.tsx
@@ -0,0 +1,109 @@
1/*
2 * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6
7import CloseIcon from '@mui/icons-material/Close';
8import Button from '@mui/material/Button';
9import IconButton from '@mui/material/IconButton';
10import Typography from '@mui/material/Typography';
11import { styled } from '@mui/material/styles';
12import React, { useId } from 'react';
13
14const SlideInDialogRoot = styled('div', {
15 name: 'SlideInDialog-Root',
16 shouldForwardProp: (propName) => propName !== 'dialog',
17})<{ dialog: boolean }>(({ theme, dialog }) => {
18 return {
19 maxHeight: '100%',
20 maxWidth: '100%',
21 overflow: 'hidden',
22 display: 'flex',
23 flexDirection: 'column',
24 '.SlideInDialog-title': {
25 display: 'flex',
26 flexDirection: 'row',
27 alignItems: 'center',
28 padding: theme.spacing(1),
29 paddingLeft: theme.spacing(2),
30 borderBottom: `1px solid ${theme.palette.divider}`,
31 '& h2': {
32 flexGrow: 1,
33 },
34 '.MuiIconButton-root': {
35 flexGrow: 0,
36 flexShrink: 0,
37 marginLeft: theme.spacing(2),
38 },
39 },
40 '.MuiFormControlLabel-root': {
41 marginLeft: 0,
42 paddingTop: theme.spacing(1),
43 paddingLeft: theme.spacing(1),
44 '& + .MuiFormControlLabel-root': {
45 paddingTop: 0,
46 },
47 },
48 '.SlideInDialog-buttons': {
49 padding: theme.spacing(1),
50 display: 'flex',
51 flexDirection: 'row',
52 justifyContent: 'flex-end',
53 ...(dialog
54 ? {
55 marginTop: theme.spacing(1),
56 borderTop: `1px solid ${theme.palette.divider}`,
57 }
58 : {}),
59 },
60 };
61});
62
63export default function SlideInDialog({
64 close,
65 dialog,
66 title,
67 buttons,
68 children,
69}: {
70 close: () => void;
71 dialog?: boolean;
72 title: string;
73 buttons: React.ReactNode | ((close: () => void) => React.ReactNode);
74 children?: React.ReactNode;
75}): JSX.Element {
76 const titleId = useId();
77
78 return (
79 <SlideInDialogRoot
80 dialog={dialog ?? SlideInDialog.defaultProps.dialog}
81 aria-labelledby={dialog ? titleId : undefined}
82 >
83 {dialog && (
84 <div className="SlideInDialog-title">
85 <Typography variant="h6" component="h2" id={titleId}>
86 {title}
87 </Typography>
88 <IconButton aria-label="Close" onClick={close}>
89 <CloseIcon />
90 </IconButton>
91 </div>
92 )}
93 {children}
94 <div className="SlideInDialog-buttons">
95 {typeof buttons === 'function' ? buttons(close) : buttons}
96 {!dialog && (
97 <Button color="inherit" onClick={close}>
98 Close
99 </Button>
100 )}
101 </div>
102 </SlideInDialogRoot>
103 );
104}
105
106SlideInDialog.defaultProps = {
107 dialog: false,
108 children: undefined,
109};