Change layout to "Clipped under the app bar"

To avoid lag of PhotoAlbum component due to many re-renderings of the
layout during transition of opening/closing of drawer
This commit is contained in:
Stefan Forstenlechner 2022-05-27 15:39:24 +02:00
parent e81e81bd5c
commit 3e93dbcd75
6 changed files with 23 additions and 146 deletions

View File

@ -1,38 +1,21 @@
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";
import Typography from "@mui/material/Typography";
import React from "react";
import AppBar from "../MuiLayout/AppBar";
import env from "../env";
import AppBar from "@mui/material/AppBar";
function ImageGalleryAppBar({
open,
drawerWidth,
onDrawerOpenClick,
}: {
open: boolean;
drawerWidth: number;
onDrawerOpenClick: () => void;
}) {
export const ImageGalleryAppBar = () => {
return (
<AppBar position="fixed" open={open} drawerwidth={drawerWidth}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={onDrawerOpenClick}
edge="start"
sx={{ mr: 2, ...(open && { display: "none" }) }}
<AppBar
position="fixed"
sx={{ zIndex: (theme) => theme.zIndex.drawer + 1 }}
style={{ backgroundColor: env.REACT_APP_APPBAR_COLOR ?? "#1976D2" }}
>
<MenuIcon />
</IconButton>
<Toolbar>
<Typography variant="h6" noWrap component="div">
{env.REACT_APP_TITLE ?? "Simple Picture Gallery"}
</Typography>
</Toolbar>
</AppBar>
);
}
export default ImageGalleryAppBar;
};

View File

@ -1,16 +1,11 @@
import Drawer from "@mui/material/Drawer";
import IconButton from "@mui/material/IconButton";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import FolderIcon from "@mui/icons-material/Folder";
import FolderOpenIcon from "@mui/icons-material/FolderOpen";
import Divider from "@mui/material/Divider";
import { useTheme } from "@mui/material/styles";
import { TreeItem, TreeView } from "@mui/lab";
import { useLocation, useNavigate } from "react-router-dom";
import React, { useState } from "react";
import { Folders } from "./models";
import DrawerHeader from "../MuiLayout/DrawerHeader";
import Toolbar from "@mui/material/Toolbar";
function getDefaultExpanded(pathname: string): string[] {
const pathParts = [];
@ -109,45 +104,24 @@ function GenerateTreeView({ root }: { root: Folders }) {
);
}
function ImageGalleryDrawer({
open,
export const ImageGalleryDrawer = ({
drawerWidth,
folder,
onDrawerCloseClick,
}: {
open: boolean;
drawerWidth: number;
folder: Folders;
onDrawerCloseClick: () => void;
}) {
const theme = useTheme();
}) => {
return (
<Drawer
variant="permanent"
sx={{
width: drawerWidth,
flexShrink: 0,
"& .MuiDrawer-paper": {
width: drawerWidth,
boxSizing: "border-box",
},
[`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: "border-box" },
}}
variant="persistent"
anchor="left"
open={open}
>
<DrawerHeader>
<IconButton onClick={onDrawerCloseClick}>
{theme.direction === "ltr" ? (
<ChevronLeftIcon />
) : (
<ChevronRightIcon />
)}
</IconButton>
</DrawerHeader>
<Divider />
<Toolbar />
<GenerateTreeView root={folder} />
</Drawer>
);
}
export default ImageGalleryDrawer;
};

View File

@ -3,17 +3,15 @@ import Box from "@mui/material/Box";
import CssBaseline from "@mui/material/CssBaseline";
import { useLocation, useNavigate } from "react-router-dom";
import { Folders, ImageWithThumbnail } from "./ImageGallery/models";
import ImageGalleryAppBar from "./ImageGallery/ImageGalleryAppBar";
import DrawerHeader from "./MuiLayout/DrawerHeader";
import ImageGalleryDrawer from "./ImageGallery/ImageGalleryDrawer";
import { ImageGalleryAppBar } from "./ImageGallery/ImageGalleryAppBar";
import { ImageGalleryDrawer } from "./ImageGallery/ImageGalleryDrawer";
import ImageGallery from "./ImageGallery/ImageGallery";
import Main from "./MuiLayout/Main";
import { Spinner } from "./ImageGallery/Spinner";
import Toolbar from "@mui/material/Toolbar";
const drawerWidth = 240;
function ImageGalleryLayout() {
const [open, setOpen] = useState(true);
const [error, setError] = useState(false);
const [imagesLoaded, setImagesLoaded] = useState(false);
const [images, setImages] = useState<ImageWithThumbnail[]>([]);
@ -27,14 +25,6 @@ function ImageGalleryLayout() {
const location = useLocation();
const navigate = useNavigate();
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
useEffect(() => {
setImages([]);
setError(false);
@ -73,21 +63,12 @@ function ImageGalleryLayout() {
return (
<Box sx={{ display: "flex" }}>
<CssBaseline />
<ImageGalleryAppBar
open={open}
drawerWidth={drawerWidth}
onDrawerOpenClick={handleDrawerOpen}
/>
<ImageGalleryDrawer
open={open}
drawerWidth={drawerWidth}
folder={folders}
onDrawerCloseClick={handleDrawerClose}
/>
<Main open={open} drawerwidth={drawerWidth}>
<DrawerHeader />
<ImageGalleryAppBar />
<ImageGalleryDrawer drawerWidth={drawerWidth} folder={folders} />
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<Toolbar />
{imagesLoaded ? <ImageGallery images={images} /> : <Spinner />}
</Main>
</Box>
</Box>
);
}

View File

@ -1,26 +0,0 @@
import { styled } from "@mui/material/styles";
import MuiAppBar from "@mui/material/AppBar";
import env from "../env";
const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== "open",
})<{
open?: boolean;
drawerwidth: number;
}>(({ theme, open, drawerwidth }) => ({
backgroundColor: env.REACT_APP_APPBAR_COLOR ?? "#1976D2",
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerwidth}px)`,
marginLeft: `${drawerwidth}px`,
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
export default AppBar;

View File

@ -1,12 +0,0 @@
import { styled } from "@mui/material/styles";
const DrawerHeader = styled("div")(({ theme }) => ({
display: "flex",
alignItems: "center",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: "flex-end",
}));
export default DrawerHeader;

View File

@ -1,23 +0,0 @@
import { styled } from "@mui/material/styles";
const Main = styled("main", { shouldForwardProp: (prop) => prop !== "open" })<{
open?: boolean;
drawerwidth: number;
}>(({ theme, open, drawerwidth }) => ({
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-${drawerwidth}px`,
...(open && {
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}));
export default Main;