mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 09:11:38 +00:00
Fix menu list on mobile
* add ahooks library * add useAppDispatch and useAppSelector hooks * move out router event handle from useEffect * fix router events off
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { FC, MouseEvent, useEffect } from 'react';
|
||||
import { FC, MouseEvent, useRef } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Image,
|
||||
@ -13,9 +13,8 @@ import {
|
||||
Button,
|
||||
} from '@chakra-ui/react';
|
||||
import UseAnimations from 'react-useanimations';
|
||||
import menu2 from 'react-useanimations/lib/menu2';
|
||||
import menu3 from 'react-useanimations/lib/menu3';
|
||||
import { FiHome, FiArchive, FiUser, FiSun, FiMoon } from 'react-icons/fi';
|
||||
import Link from 'next/link';
|
||||
import useGetColors from '../lib/hooks/useGetColors';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
@ -40,28 +39,68 @@ const menu = [
|
||||
},
|
||||
];
|
||||
|
||||
interface MenuListProps {
|
||||
boxBg: string;
|
||||
handleMenuClick: (
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
path: string
|
||||
) => void;
|
||||
}
|
||||
const MenuList: FC<MenuListProps> = ({ boxBg, handleMenuClick }) => {
|
||||
return (
|
||||
<Flex
|
||||
as="nav"
|
||||
mt={['1.5rem', null]}
|
||||
flexFlow={['column']}
|
||||
py={['1rem', null, 'unset']}
|
||||
px={['2rem', '4rem', 'unset']}
|
||||
bg={[boxBg, null, 'unset']}
|
||||
shadow={['card', null, 'unset']}
|
||||
>
|
||||
{menu.map((item) => {
|
||||
return (
|
||||
<Flex
|
||||
onClick={(e) => handleMenuClick(e, item.path)}
|
||||
href={item.path}
|
||||
key={item.id}
|
||||
as="a"
|
||||
alignItems="center"
|
||||
justifyContent={['unset', null, 'space-between']}
|
||||
fontSize={['18', null, '22']}
|
||||
my={['0.5rem', null, '0.5rem']}
|
||||
cursor="pointer"
|
||||
>
|
||||
<Icon as={item.icon} mr={['2.5rem', null, 'unset']} />
|
||||
<Text>{item.name}</Text>
|
||||
</Flex>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const NavBar: FC = () => {
|
||||
const router = useRouter();
|
||||
|
||||
const [isLargerThan768] = useMediaQuery('(min-width: 768px)');
|
||||
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true });
|
||||
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: false });
|
||||
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
|
||||
const { boxBg, bioColor, textColor, headingColor } = useGetColors();
|
||||
|
||||
useEffect(() => {
|
||||
if ((isOpen && !isLargerThan768) || (!isOpen && isLargerThan768))
|
||||
onToggle();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLargerThan768]);
|
||||
|
||||
const iconRef = useRef<HTMLDivElement>(null);
|
||||
// Switch pages
|
||||
const handleMenuClick = (
|
||||
e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>,
|
||||
path: string
|
||||
) => {
|
||||
e.preventDefault();
|
||||
!isLargerThan768 && onToggle();
|
||||
!isLargerThan768 &&
|
||||
// Click the animate icon.
|
||||
(iconRef.current?.children[0] as HTMLDivElement).click();
|
||||
router.push(path);
|
||||
};
|
||||
|
||||
@ -124,36 +163,19 @@ const NavBar: FC = () => {
|
||||
|
||||
{/* Menu */}
|
||||
<Box mx={['-2rem', '-4rem', 'unset']}>
|
||||
<Collapse in={isOpen} animateOpacity>
|
||||
<Flex
|
||||
as="nav"
|
||||
mt={['1.5rem', null]}
|
||||
flexFlow={['column']}
|
||||
py={['1rem', null, 'unset']}
|
||||
px={['2rem', '4rem', 'unset']}
|
||||
bg={[boxBg, null, 'unset']}
|
||||
shadow={['card', null, 'unset']}
|
||||
>
|
||||
{menu.map((item) => {
|
||||
return (
|
||||
<Flex
|
||||
onClick={(e) => handleMenuClick(e, item.path)}
|
||||
href={item.path}
|
||||
key={item.id}
|
||||
as="a"
|
||||
alignItems="center"
|
||||
justifyContent={['unset', null, 'space-between']}
|
||||
fontSize={['18', null, '22']}
|
||||
my={['0.5rem', null, '0.5rem']}
|
||||
cursor="pointer"
|
||||
>
|
||||
<Icon as={item.icon} mr={['2.5rem', null, 'unset']} />
|
||||
<Text>{item.name}</Text>
|
||||
</Flex>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
</Collapse>
|
||||
{/* Mobile menu */}
|
||||
<Box
|
||||
as={Collapse}
|
||||
in={isOpen}
|
||||
animateOpacity
|
||||
display={[null, null, 'none']}
|
||||
>
|
||||
<MenuList boxBg={boxBg} handleMenuClick={handleMenuClick} />
|
||||
</Box>
|
||||
{/* Desktop menu */}
|
||||
<Box display={['none', 'none', 'block']}>
|
||||
<MenuList boxBg={boxBg} handleMenuClick={handleMenuClick} />
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
@ -161,13 +183,14 @@ const NavBar: FC = () => {
|
||||
position={'absolute'}
|
||||
top={'1.5rem'}
|
||||
right={'1rem'}
|
||||
onClick={onToggle}
|
||||
ref={iconRef}
|
||||
>
|
||||
<UseAnimations
|
||||
reverse={isOpen}
|
||||
size={40}
|
||||
animation={menu2}
|
||||
speed={1.5}
|
||||
animation={menu3}
|
||||
speed={2}
|
||||
onClick={onToggle}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -4,7 +4,7 @@ import { Box, Flex, Heading, Text, Link } from '@chakra-ui/react';
|
||||
import { AllPostsData } from '../lib/posts';
|
||||
import { Icon, Image } from '@chakra-ui/react';
|
||||
import { FiCalendar, FiTag } from 'react-icons/fi';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useAppDispatch } from '../app/hooks';
|
||||
import { setFromPath } from '../features/router/routerSlice';
|
||||
import { useRouter } from 'next/router';
|
||||
import useGetColors from '../lib/hooks/useGetColors';
|
||||
@ -14,7 +14,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const PostCard: FC<Props> = ({ post }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const router = useRouter();
|
||||
|
||||
const goToPost: MouseEventHandler<HTMLAnchorElement> = (e) => {
|
||||
|
Reference in New Issue
Block a user