Skip to content

Instantly share code, notes, and snippets.

@SrJSDev
Last active February 13, 2024 17:15
Show Gist options
  • Save SrJSDev/7046451dcb2123b06b310e25bbd6cd53 to your computer and use it in GitHub Desktop.
Save SrJSDev/7046451dcb2123b06b310e25bbd6cd53 to your computer and use it in GitHub Desktop.
Flexible CSS Grid web app layout component and styles (ReactJS, MUI)
/******* CHROME layout *******/
body,
.chrome-- {
height: 100vh;
padding: 0;
margin: auto;
}
.chrome-- {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: auto auto 1fr auto;
grid-template-areas:
'banner banner'
'sidebar header'
'sidebar content'
'sidebar footer';
height: 100%;
}
.chrome-- {
& > .banner {
grid-area: banner;
overflow: hidden;
/* background-color: grey; */
}
& > .sidebar {
grid-area: sidebar;
overflow: hidden;
/* background-color: violet; */
}
& > .header {
grid-area: header;
width: 100%;
height: 100%;
/* background-color: lightblue; */
}
& > .content {
grid-area: content;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
transition: max-width 0.3s ease-in-out;
/* background-color: pink; */
}
& > .footer {
grid-area: footer;
width: 100%;
height: 100%;
/* background-color: lightgreen; */
}
}
import { CSSProperties } from 'react';
import { Box } from '@mui/material';
import { NotificationBar } from '../NotificationBar';
export type PageLayoutProps = {
children: JSX.Element | JSX.Element[];
appMaxWidth?: boolean;
pageMaxWidth?: string;
headerMaxWidth?: string;
Header?: JSX.Element | null;
Footer?: JSX.Element | null;
Sidebar?: JSX.Element | null;
Banner?: JSX.Element | null;
};
export default function PageLayout({
children,
appMaxWidth,
pageMaxWidth,
headerMaxWidth,
Header,
Footer,
Sidebar,
Banner = <NotificationBar />,
}: Readonly<PageLayoutProps>) {
const style: CSSProperties = {
transition: 'max-width 0.3s ease-in-out',
margin: '0 auto',
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
};
return (
<Box
className="chrome--"
sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
margin: 'auto',
height: '100%',
maxWidth: appMaxWidth ? '1600px' : undefined,
}}
>
{Banner ? <header className="banner">{Banner}</header> : null}
{Sidebar ? <aside className="sidebar">{Sidebar}</aside> : null}
{Header ? (
<header
className="header"
style={{ ...style, maxWidth: headerMaxWidth }}
>
{Header}
</header>
) : null}
{/* // Note: if !pageMaxWidth, then align Footer with main Content width--to avoid floating scrollbar */}
{/* // Note: else, then extend main Content area width--100% for max scrollable area */}
{!pageMaxWidth ? (
<main className="content" style={style}>
{children}
</main>
) : (
<main className="content" style={{ ...style, maxWidth: '100%' }}>
<Box sx={{ ...style, maxWidth: pageMaxWidth }} m={0}>
{children}
</Box>
</main>
)}
{Footer ? (
<footer className="footer" style={style}>
{Footer}
</footer>
) : null}
</Box>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment