aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/graph/SlideInPanel.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/SlideInPanel.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/SlideInPanel.tsx')
-rw-r--r--subprojects/frontend/src/graph/SlideInPanel.tsx97
1 files changed, 97 insertions, 0 deletions
diff --git a/subprojects/frontend/src/graph/SlideInPanel.tsx b/subprojects/frontend/src/graph/SlideInPanel.tsx
new file mode 100644
index 00000000..2c189b5b
--- /dev/null
+++ b/subprojects/frontend/src/graph/SlideInPanel.tsx
@@ -0,0 +1,97 @@
1/*
2 * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6
7import Dialog from '@mui/material/Dialog';
8import IconButton from '@mui/material/IconButton';
9import Paper from '@mui/material/Paper';
10import Slide from '@mui/material/Slide';
11import { styled } from '@mui/material/styles';
12import React, { useCallback, useId, useState } from 'react';
13
14import SlideInDialog from './SlideInDialog';
15
16const SlideInPanelRoot = styled('div', {
17 name: 'SlideInPanel-Root',
18 shouldForwardProp: (propName) => propName !== 'anchor',
19})<{ anchor: 'left' | 'right' }>(({ theme, anchor }) => ({
20 position: 'absolute',
21 padding: theme.spacing(1),
22 top: 0,
23 [anchor]: 0,
24 maxHeight: '100%',
25 maxWidth: '100%',
26 overflow: 'hidden',
27 display: 'flex',
28 flexDirection: 'column',
29 alignItems: anchor === 'left' ? 'start' : 'end',
30 '.SlideInPanel-drawer': {
31 overflow: 'hidden',
32 display: 'flex',
33 maxWidth: '100%',
34 margin: theme.spacing(1),
35 },
36}));
37
38export default function SlideInPanel({
39 anchor,
40 dialog,
41 title,
42 icon,
43 iconLabel,
44 buttons,
45 children,
46}: {
47 anchor: 'left' | 'right';
48 dialog: boolean;
49 title: string;
50 icon: (show: boolean) => React.ReactNode;
51 iconLabel: string;
52 buttons: React.ReactNode | ((close: () => void) => React.ReactNode);
53 children?: React.ReactNode;
54}): JSX.Element {
55 const id = useId();
56 const [show, setShow] = useState(false);
57 const close = useCallback(() => setShow(false), []);
58
59 return (
60 <SlideInPanelRoot anchor={anchor}>
61 <IconButton
62 role="switch"
63 aria-checked={show}
64 aria-controls={dialog ? undefined : id}
65 aria-label={iconLabel}
66 onClick={() => setShow(!show)}
67 >
68 {icon(show)}
69 </IconButton>
70 {dialog ? (
71 <Dialog open={show} onClose={close} maxWidth="xl">
72 <SlideInDialog close={close} dialog title={title} buttons={buttons}>
73 {children}
74 </SlideInDialog>
75 </Dialog>
76 ) : (
77 <Slide
78 direction={anchor === 'left' ? 'right' : 'left'}
79 in={show}
80 id={id}
81 mountOnEnter
82 unmountOnExit
83 >
84 <Paper className="SlideInPanel-drawer" elevation={4}>
85 <SlideInDialog close={close} title={title} buttons={buttons}>
86 {children}
87 </SlideInDialog>
88 </Paper>
89 </Slide>
90 )}
91 </SlideInPanelRoot>
92 );
93}
94
95SlideInPanel.defaultProps = {
96 children: undefined,
97};