Capital/components/NavigationDrawer.tsx

118 lines
2.9 KiB
TypeScript
Raw Normal View History

2024-02-24 06:16:57 +00:00
"use client";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import {
Box,
Divider,
Drawer,
IconButton,
List,
ListItemButton,
ListItemIcon,
ListItemText,
styled,
2024-02-24 13:56:35 +00:00
useMediaQuery,
2024-02-24 06:16:57 +00:00
} from "@mui/material";
import { theme } from "@/app/theme";
2024-02-24 08:07:59 +00:00
import { ReactNode } from "react";
import HomeIcon from "@mui/icons-material/Home";
2024-02-24 09:33:35 +00:00
import ArticleIcon from "@mui/icons-material/Article";
2024-02-24 10:54:47 +00:00
import FeedIcon from "@mui/icons-material/RssFeed";
2024-02-24 08:07:59 +00:00
import Link from "next/link";
export interface NavigationItem {
2024-02-24 10:54:47 +00:00
icon?: ReactNode;
title?: string;
link?: string;
divider?: boolean;
2024-02-24 08:07:59 +00:00
}
2024-02-24 06:16:57 +00:00
export const DRAWER_WIDTH = 320;
2024-02-24 08:07:59 +00:00
export const NAVIGATION_ITEMS: NavigationItem[] = [
2024-02-24 09:33:35 +00:00
{ icon: <HomeIcon />, title: "首页", link: "/" },
{ icon: <ArticleIcon />, title: "新闻", link: "/posts" },
2024-02-24 10:54:47 +00:00
{ divider: true },
{ icon: <FeedIcon />, title: "订阅源", link: "/feed" },
2024-02-24 08:07:59 +00:00
];
2024-02-24 06:16:57 +00:00
export const AppNavigationHeader = styled("div")(({ theme }) => ({
display: "flex",
alignItems: "center",
padding: theme.spacing(0, 1),
justifyContent: "flex-start",
2024-02-24 08:07:59 +00:00
height: 64,
2024-02-24 13:56:35 +00:00
...theme.mixins.toolbar,
2024-02-24 06:16:57 +00:00
}));
2024-02-24 13:56:35 +00:00
export function AppNavigation({ showClose, onClose }: { showClose?: boolean; onClose: () => void }) {
2024-02-24 06:16:57 +00:00
return (
<>
<AppNavigationHeader>
2024-02-24 13:56:35 +00:00
{showClose && (
2024-02-24 06:16:57 +00:00
<IconButton onClick={onClose}>
{theme.direction === "rtl" ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
2024-02-24 13:56:35 +00:00
)}
2024-02-24 06:16:57 +00:00
</AppNavigationHeader>
<Divider />
<List>
2024-02-24 10:54:47 +00:00
{NAVIGATION_ITEMS.map((item, idx) => {
2024-02-24 13:56:35 +00:00
return item.divider ? (
<Divider key={idx} />
) : (
2024-02-24 10:54:47 +00:00
<Link key={idx} href={item.link ?? "/"} passHref>
<ListItemButton>
<ListItemIcon>{item.icon}</ListItemIcon>
<ListItemText primary={item.title} />
</ListItemButton>
</Link>
);
})}
2024-02-24 06:16:57 +00:00
</List>
</>
);
}
export const isMobileQuery = theme.breakpoints.down("md");
2024-02-24 13:56:35 +00:00
export default function NavigationDrawer({ open, onClose }: { open: boolean; onClose: () => void }) {
2024-02-24 06:16:57 +00:00
const isMobile = useMediaQuery(isMobileQuery);
return isMobile ? (
<>
<Box sx={{ flexShrink: 0, width: DRAWER_WIDTH }} />
<Drawer
keepMounted
anchor="right"
variant="temporary"
open={open}
onClose={onClose}
sx={{
"& .MuiDrawer-paper": {
boxSizing: "border-box",
2024-02-24 13:56:35 +00:00
width: DRAWER_WIDTH,
},
2024-02-24 06:16:57 +00:00
}}
>
<AppNavigation onClose={onClose} />
</Drawer>
</>
) : (
<Drawer
variant="persistent"
anchor="right"
open={open}
sx={{
width: DRAWER_WIDTH,
flexShrink: 0,
"& .MuiDrawer-paper": {
2024-02-24 13:56:35 +00:00
width: DRAWER_WIDTH,
},
2024-02-24 06:16:57 +00:00
}}
>
<AppNavigation showClose onClose={onClose} />
</Drawer>
);
2024-02-24 13:56:35 +00:00
}