mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: update header menu style in mobile view
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import classNames from "classnames";
|
||||
import { useEffect } from "react";
|
||||
import { NavLink, useLocation } from "react-router-dom";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useLayoutStore } from "@/store/module";
|
||||
import { useInboxStore } from "@/store/v1";
|
||||
import { Inbox_Status } from "@/types/proto/api/v2/inbox_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { resolution } from "@/utils/layout";
|
||||
import Icon from "./Icon";
|
||||
import UserBanner from "./UserBanner";
|
||||
|
||||
@@ -19,11 +17,8 @@ interface NavLinkItem {
|
||||
|
||||
const Header = () => {
|
||||
const t = useTranslate();
|
||||
const location = useLocation();
|
||||
const layoutStore = useLayoutStore();
|
||||
const user = useCurrentUser();
|
||||
const inboxStore = useInboxStore();
|
||||
const showHeader = layoutStore.state.showHeader;
|
||||
const hasUnreadInbox = inboxStore.inboxes.some((inbox) => inbox.status === Inbox_Status.UNREAD);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -42,22 +37,6 @@ const Header = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleWindowResize = () => {
|
||||
if (window.innerWidth < resolution.sm) {
|
||||
layoutStore.setHeaderStatus(false);
|
||||
} else {
|
||||
layoutStore.setHeaderStatus(true);
|
||||
}
|
||||
};
|
||||
handleWindowResize();
|
||||
window.addEventListener("resize", handleWindowResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleWindowResize);
|
||||
};
|
||||
}, [location]);
|
||||
|
||||
const homeNavLink: NavLinkItem = {
|
||||
id: "header-home",
|
||||
path: "/",
|
||||
@@ -119,22 +98,7 @@ const Header = () => {
|
||||
: [exploreNavLink, signInNavLink];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`fixed sm:sticky top-0 left-0 w-full sm:w-56 h-screen shrink-0 pointer-events-none sm:pointer-events-auto z-10 ${
|
||||
showHeader && "pointer-events-auto"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`fixed top-0 left-0 w-full h-full max-h-screen opacity-0 pointer-events-none transition-opacity duration-300 sm:!hidden ${
|
||||
showHeader && "opacity-60 pointer-events-auto"
|
||||
}`}
|
||||
onClick={() => layoutStore.setHeaderStatus(false)}
|
||||
></div>
|
||||
<header
|
||||
className={`relative w-56 sm:w-full h-full max-h-screen border-r sm:border-none dark:border-r-zinc-700 overflow-auto hide-scrollbar flex flex-col justify-start items-start py-4 z-30 bg-zinc-100 dark:bg-zinc-800 sm:bg-transparent sm:shadow-none transition-all duration-300 -translate-x-full sm:translate-x-0 ${
|
||||
showHeader && "translate-x-0 shadow-2xl"
|
||||
}`}
|
||||
>
|
||||
<header className={`w-full h-full overflow-auto flex flex-col justify-start items-start py-4 z-30`}>
|
||||
<UserBanner />
|
||||
<div className="w-full px-2 py-2 flex flex-col justify-start items-start shrink-0 space-y-2">
|
||||
{navLinks.map((navLink) => (
|
||||
@@ -156,7 +120,6 @@ const Header = () => {
|
||||
))}
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
37
web/src/components/HeaderDrawer.tsx
Normal file
37
web/src/components/HeaderDrawer.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Drawer, IconButton } from "@mui/joy";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import Header from "./Header";
|
||||
import Icon from "./Icon";
|
||||
|
||||
const HeaderDrawer = () => {
|
||||
const location = useLocation();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setOpen(false);
|
||||
}, [location.pathname]);
|
||||
|
||||
const toggleDrawer = (inOpen: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
|
||||
if (event.type === "keydown" && ((event as React.KeyboardEvent).key === "Tab" || (event as React.KeyboardEvent).key === "Shift")) {
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(inOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IconButton onClick={toggleDrawer(true)}>
|
||||
<Icon.Menu className="w-5 h-auto dark:text-gray-200" />
|
||||
</IconButton>
|
||||
<Drawer anchor="left" open={open} onClose={toggleDrawer(false)}>
|
||||
<div className="w-full px-4">
|
||||
<Header />
|
||||
</div>
|
||||
</Drawer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderDrawer;
|
@@ -1,5 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { useLayoutStore } from "@/store/module";
|
||||
import HeaderDrawer from "./HeaderDrawer";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
@@ -14,12 +15,13 @@ const MobileHeader = (props: Props) => {
|
||||
return (
|
||||
<div className="sticky top-0 pt-4 sm:pt-1 pb-1 mb-1 backdrop-blur bg-zinc-100 dark:bg-zinc-800 bg-opacity-70 flex @lg:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-2">
|
||||
<div className="flex flex-row justify-start items-center mr-2 shrink-0 overflow-hidden">
|
||||
<div
|
||||
{/* <div
|
||||
className="flex sm:hidden flex-row justify-center items-center w-6 h-6 mr-1 shrink-0 bg-transparent"
|
||||
onClick={() => layoutStore.setHeaderStatus(true)}
|
||||
>
|
||||
<Icon.Menu className="w-5 h-auto dark:text-gray-200" />
|
||||
</div>
|
||||
</div> */}
|
||||
<HeaderDrawer />
|
||||
<span
|
||||
className="font-bold text-lg leading-10 mr-1 text-ellipsis shrink-0 cursor-pointer overflow-hidden text-gray-700 dark:text-gray-200"
|
||||
onClick={() => location.reload()}
|
||||
|
@@ -9,7 +9,9 @@ function Root() {
|
||||
<DemoBanner />
|
||||
</div>
|
||||
<div className="w-full max-w-6xl mx-auto flex flex-row justify-center items-start sm:px-4">
|
||||
<div className="hidden sm:block sticky top-0 left-0 w-56">
|
||||
<Header />
|
||||
</div>
|
||||
<main className="w-full min-h-screen sm:max-w-[calc(100%-14rem)] flex-grow shrink flex flex-col justify-start items-start">
|
||||
<Outlet />
|
||||
</main>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import store, { useAppSelector } from "..";
|
||||
import { setHeaderStatus, setHomeSidebarStatus } from "../reducer/layout";
|
||||
import { setHomeSidebarStatus } from "../reducer/layout";
|
||||
|
||||
export const useLayoutStore = () => {
|
||||
const state = useAppSelector((state) => state.layout);
|
||||
@@ -8,9 +8,6 @@ export const useLayoutStore = () => {
|
||||
getState: () => {
|
||||
return store.getState().tag;
|
||||
},
|
||||
setHeaderStatus: (showHeader: boolean) => {
|
||||
store.dispatch(setHeaderStatus(showHeader));
|
||||
},
|
||||
setHomeSidebarStatus: (showHomeSidebar: boolean) => {
|
||||
store.dispatch(setHomeSidebarStatus(showHomeSidebar));
|
||||
},
|
||||
|
@@ -1,23 +1,15 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
|
||||
interface State {
|
||||
showHeader: boolean;
|
||||
showHomeSidebar: boolean;
|
||||
}
|
||||
|
||||
const layoutSlice = createSlice({
|
||||
name: "layout",
|
||||
initialState: {
|
||||
showHeader: false,
|
||||
showHomeSidebar: false,
|
||||
} as State,
|
||||
reducers: {
|
||||
setHeaderStatus: (state, action: PayloadAction<boolean>) => {
|
||||
return {
|
||||
...state,
|
||||
showHeader: action.payload,
|
||||
};
|
||||
},
|
||||
setHomeSidebarStatus: (state, action: PayloadAction<boolean>) => {
|
||||
return {
|
||||
...state,
|
||||
@@ -27,6 +19,6 @@ const layoutSlice = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const { setHeaderStatus, setHomeSidebarStatus } = layoutSlice.actions;
|
||||
export const { setHomeSidebarStatus } = layoutSlice.actions;
|
||||
|
||||
export default layoutSlice.reducer;
|
||||
|
Reference in New Issue
Block a user