Skip to content

Instantly share code, notes, and snippets.

@cxmeel
Last active September 8, 2020 17:56
Show Gist options
  • Save cxmeel/e395de999f3f0c8d207bcd3ff3454c1a to your computer and use it in GitHub Desktop.
Save cxmeel/e395de999f3f0c8d207bcd3ff3454c1a to your computer and use it in GitHub Desktop.
Fake body and navigation panels for React using Material UI. https://pseudo-body-component.stackblitz.io
import React, { useLayoutEffect, useState, useCallback } from 'react';
import clsx from 'clsx';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { Paper, makeStyles } from '@material-ui/core';
const useStyles = makeStyles(theme => ({
pseudoBody: {
width: '100vw',
height: '100vh',
overflow: 'hidden',
background: 'white',
display: 'flex',
flexDirection: 'row',
flexWrap: 'nowrap'
},
bodyMenu: {
position: 'relative',
width: '100%',
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
marginRight: '-3em',
flexShrink: 0,
[theme.breakpoints.up('md')]: {
marginRight: -Math.max(theme.breakpoints.values.xs, 444),
paddingRight: Math.max(theme.breakpoints.values.xs, 444)
},
transition: theme.transitions.create('all', {
duration: theme.transitions.duration.complex * 2
}),
pointerEvents: 'visiblefill',
zIndex: 0
},
bodyMenuCollapse: {
marginRight: '-100%'
},
bodyBody: {
position: 'relative',
width: '100%',
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
borderRadius: '3em',
flexShrink: 0,
[theme.breakpoints.up('md')]: {
width: Math.max(theme.breakpoints.values.xs, 444)
},
transition: theme.transitions.create('all', {
duration: theme.transitions.duration.complex * 2
}),
pointerEvents: 'visiblefill',
zIndex: 1
},
bodyBodyCollapse: {
width: '100%',
borderRadius: 0
},
bodyShieldCollapse: {
display: 'none'
},
bodyShield: {
display: 'block',
position: 'absolute',
width: '100%',
height: '100%',
top: 0,
left: 0,
[theme.breakpoints.up('md')]: {
display: 'none'
}
}
}));
export default (props = {}) => {
const classes = useStyles();
const [open, __setOpen] = useState(props.open);
const setOpen = useCallback(
state => {
__setOpen(state);
props.onOpenChange && props.onOpenChange(state);
},
[props]
);
useLayoutEffect(() => setOpen(props.open), [props.open, setOpen]);
return (
<>
<div className={classes.pseudoBody}>
<ThemeProvider
theme={props.theme || createMuiTheme({ palette: { type: 'dark' } })}>
<Paper
square
elevation={0}
className={clsx(classes.bodyMenu, {
[classes.bodyMenuCollapse]: !open
})}>
{props.navigation}
</Paper>
</ThemeProvider>
<Paper
elevation={open ? 0 : 24}
className={clsx(classes.bodyBody, {
[classes.bodyBodyCollapse]: !open
})}>
{props.children}
<div
className={clsx(classes.bodyShieldCollapse, {
[classes.bodyShield]: open
})}
onClick={() => setOpen(false)}
/>
</Paper>
</div>
</>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment