Responsive layout with temporary and permanent Drawer

"Clipped under the app bar" drawer did not work well on small screens
This commit is contained in:
Stefan Forstenlechner 2022-05-27 23:36:19 +02:00
parent 3e93dbcd75
commit 42799389b5
3 changed files with 77 additions and 7 deletions

View File

@ -3,8 +3,20 @@ import Typography from "@mui/material/Typography";
import React from "react";
import env from "../env";
import AppBar from "@mui/material/AppBar";
import useMediaQuery from "@mui/material/useMediaQuery";
import { IconButton } from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import CloseIcon from "@mui/icons-material/Close";
import { smallScreenMediaQuery } from "../ImageGalleryLayout";
export const ImageGalleryAppBar = () => {
export const ImageGalleryAppBar = ({
open,
onDrawerOpenClick,
}: {
open: boolean;
onDrawerOpenClick: () => void;
}) => {
const smallScreen = !useMediaQuery(smallScreenMediaQuery);
return (
<AppBar
position="fixed"
@ -12,6 +24,17 @@ export const ImageGalleryAppBar = () => {
style={{ backgroundColor: env.REACT_APP_APPBAR_COLOR ?? "#1976D2" }}
>
<Toolbar>
{smallScreen && (
<IconButton
color="inherit"
aria-label="open drawer"
onClick={onDrawerOpenClick}
edge="start"
sx={{ mr: 2 }}
>
{open && smallScreen ? <CloseIcon /> : <MenuIcon />}
</IconButton>
)}
<Typography variant="h6" noWrap component="div">
{env.REACT_APP_TITLE ?? "Simple Picture Gallery"}
</Typography>

View File

@ -6,6 +6,9 @@ import { useLocation, useNavigate } from "react-router-dom";
import React, { useState } from "react";
import { Folders } from "./models";
import Toolbar from "@mui/material/Toolbar";
import { useTheme } from "@mui/material";
import useMediaQuery from "@mui/material/useMediaQuery";
import { smallScreenMediaQuery } from "../ImageGalleryLayout";
function getDefaultExpanded(pathname: string): string[] {
const pathParts = [];
@ -105,23 +108,52 @@ function GenerateTreeView({ root }: { root: Folders }) {
}
export const ImageGalleryDrawer = ({
open,
drawerWidth,
folder,
handleDrawerToggle,
}: {
open: boolean;
drawerWidth: number;
folder: Folders;
handleDrawerToggle: () => void;
}) => {
return (
const theme = useTheme();
const smallScreen = !useMediaQuery(smallScreenMediaQuery);
const drawerContent = (
<>
<Toolbar sx={{ marginBottom: 3 }} />
<GenerateTreeView root={folder} />
</>
);
return smallScreen ? (
<Drawer
variant="temporary"
anchor={theme.direction === "rtl" ? "right" : "left"}
open={open}
onClose={handleDrawerToggle}
style={{ width: drawerWidth }}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawerContent}
</Drawer>
) : (
<Drawer
variant="permanent"
sx={{
width: drawerWidth,
flexShrink: 0,
[`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: "border-box" },
[`& .MuiDrawer-paper`]: {
width: drawerWidth,
boxSizing: "border-box",
},
}}
>
<Toolbar />
<GenerateTreeView root={folder} />
{drawerContent}
</Drawer>
);
};

View File

@ -10,11 +10,14 @@ import { Spinner } from "./ImageGallery/Spinner";
import Toolbar from "@mui/material/Toolbar";
const drawerWidth = 240;
export const smallScreenMediaQuery = `(min-width:${drawerWidth * 3}px)`;
function ImageGalleryLayout() {
const [drawerOpen, setDrawerOpen] = useState(false);
const [error, setError] = useState(false);
const [imagesLoaded, setImagesLoaded] = useState(false);
const [images, setImages] = useState<ImageWithThumbnail[]>([]);
const [folders, setFolders] = useState<Folders>({
name: "Home",
fullPath: "/",
@ -25,6 +28,10 @@ function ImageGalleryLayout() {
const location = useLocation();
const navigate = useNavigate();
function handleDrawerToggle() {
setDrawerOpen(!drawerOpen);
}
useEffect(() => {
setImages([]);
setError(false);
@ -63,8 +70,16 @@ function ImageGalleryLayout() {
return (
<Box sx={{ display: "flex" }}>
<CssBaseline />
<ImageGalleryAppBar />
<ImageGalleryDrawer drawerWidth={drawerWidth} folder={folders} />
<ImageGalleryAppBar
open={drawerOpen}
onDrawerOpenClick={handleDrawerToggle}
/>
<ImageGalleryDrawer
open={drawerOpen}
drawerWidth={drawerWidth}
folder={folders}
handleDrawerToggle={handleDrawerToggle}
/>
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<Toolbar />
{imagesLoaded ? <ImageGallery images={images} /> : <Spinner />}