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:
parent
3e93dbcd75
commit
42799389b5
|
|
@ -3,8 +3,20 @@ import Typography from "@mui/material/Typography";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import env from "../env";
|
import env from "../env";
|
||||||
import AppBar from "@mui/material/AppBar";
|
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 (
|
return (
|
||||||
<AppBar
|
<AppBar
|
||||||
position="fixed"
|
position="fixed"
|
||||||
|
|
@ -12,6 +24,17 @@ export const ImageGalleryAppBar = () => {
|
||||||
style={{ backgroundColor: env.REACT_APP_APPBAR_COLOR ?? "#1976D2" }}
|
style={{ backgroundColor: env.REACT_APP_APPBAR_COLOR ?? "#1976D2" }}
|
||||||
>
|
>
|
||||||
<Toolbar>
|
<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">
|
<Typography variant="h6" noWrap component="div">
|
||||||
{env.REACT_APP_TITLE ?? "Simple Picture Gallery"}
|
{env.REACT_APP_TITLE ?? "Simple Picture Gallery"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Folders } from "./models";
|
import { Folders } from "./models";
|
||||||
import Toolbar from "@mui/material/Toolbar";
|
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[] {
|
function getDefaultExpanded(pathname: string): string[] {
|
||||||
const pathParts = [];
|
const pathParts = [];
|
||||||
|
|
@ -105,23 +108,52 @@ function GenerateTreeView({ root }: { root: Folders }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ImageGalleryDrawer = ({
|
export const ImageGalleryDrawer = ({
|
||||||
|
open,
|
||||||
drawerWidth,
|
drawerWidth,
|
||||||
folder,
|
folder,
|
||||||
|
handleDrawerToggle,
|
||||||
}: {
|
}: {
|
||||||
|
open: boolean;
|
||||||
drawerWidth: number;
|
drawerWidth: number;
|
||||||
folder: Folders;
|
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
|
<Drawer
|
||||||
variant="permanent"
|
variant="permanent"
|
||||||
sx={{
|
sx={{
|
||||||
width: drawerWidth,
|
width: drawerWidth,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
[`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: "border-box" },
|
[`& .MuiDrawer-paper`]: {
|
||||||
|
width: drawerWidth,
|
||||||
|
boxSizing: "border-box",
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Toolbar />
|
{drawerContent}
|
||||||
<GenerateTreeView root={folder} />
|
|
||||||
</Drawer>
|
</Drawer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,14 @@ import { Spinner } from "./ImageGallery/Spinner";
|
||||||
import Toolbar from "@mui/material/Toolbar";
|
import Toolbar from "@mui/material/Toolbar";
|
||||||
|
|
||||||
const drawerWidth = 240;
|
const drawerWidth = 240;
|
||||||
|
export const smallScreenMediaQuery = `(min-width:${drawerWidth * 3}px)`;
|
||||||
|
|
||||||
function ImageGalleryLayout() {
|
function ImageGalleryLayout() {
|
||||||
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
const [imagesLoaded, setImagesLoaded] = useState(false);
|
const [imagesLoaded, setImagesLoaded] = useState(false);
|
||||||
const [images, setImages] = useState<ImageWithThumbnail[]>([]);
|
const [images, setImages] = useState<ImageWithThumbnail[]>([]);
|
||||||
|
|
||||||
const [folders, setFolders] = useState<Folders>({
|
const [folders, setFolders] = useState<Folders>({
|
||||||
name: "Home",
|
name: "Home",
|
||||||
fullPath: "/",
|
fullPath: "/",
|
||||||
|
|
@ -25,6 +28,10 @@ function ImageGalleryLayout() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
function handleDrawerToggle() {
|
||||||
|
setDrawerOpen(!drawerOpen);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setImages([]);
|
setImages([]);
|
||||||
setError(false);
|
setError(false);
|
||||||
|
|
@ -63,8 +70,16 @@ function ImageGalleryLayout() {
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: "flex" }}>
|
<Box sx={{ display: "flex" }}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<ImageGalleryAppBar />
|
<ImageGalleryAppBar
|
||||||
<ImageGalleryDrawer drawerWidth={drawerWidth} folder={folders} />
|
open={drawerOpen}
|
||||||
|
onDrawerOpenClick={handleDrawerToggle}
|
||||||
|
/>
|
||||||
|
<ImageGalleryDrawer
|
||||||
|
open={drawerOpen}
|
||||||
|
drawerWidth={drawerWidth}
|
||||||
|
folder={folders}
|
||||||
|
handleDrawerToggle={handleDrawerToggle}
|
||||||
|
/>
|
||||||
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
|
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
|
||||||
<Toolbar />
|
<Toolbar />
|
||||||
{imagesLoaded ? <ImageGallery images={images} /> : <Spinner />}
|
{imagesLoaded ? <ImageGallery images={images} /> : <Spinner />}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue