Menu looking pogger
This commit is contained in:
parent
01162f93cb
commit
574689a53b
3 changed files with 54 additions and 18 deletions
24
polsevev.dev.frontend/src/Hooks/useComponentVisible.tsx
Normal file
24
polsevev.dev.frontend/src/Hooks/useComponentVisible.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
export default function useComponentVisible(initialIsVisible: boolean) {
|
||||||
|
const [isCompVisible, setIsCompVisible] =
|
||||||
|
useState<boolean>(initialIsVisible);
|
||||||
|
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const handleClickOutsideComp = (event: Event) => {
|
||||||
|
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||||
|
setIsCompVisible(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener("click", handleClickOutsideComp, true);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("click", handleClickOutsideComp, true);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const openComp = () => setIsCompVisible(true);
|
||||||
|
|
||||||
|
return { ref, isCompVisible, openComp };
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { FC, useEffect, useState } from "react";
|
import { FC, useEffect, useRef, useState } from "react";
|
||||||
import { NavItem, SideBarBox } from "../styles/TopBarStyle";
|
import { NavItem, SideBarBox } from "../styles/TopBarStyle";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
|
import useComponentVisible from "../Hooks/useComponentVisible";
|
||||||
|
|
||||||
const NavigationMenu: FC = () => {
|
const NavigationMenu: FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -9,11 +10,12 @@ const NavigationMenu: FC = () => {
|
||||||
const [isPhone, setIsPhone] = useState(
|
const [isPhone, setIsPhone] = useState(
|
||||||
window.matchMedia("(min-width: 720px)").matches
|
window.matchMedia("(min-width: 720px)").matches
|
||||||
);
|
);
|
||||||
const [showNavButtonsPhone, setShowNavButtonsPhone] = useState(false);
|
|
||||||
const locationButtons = locations.map((location) => (
|
const locationButtons = locations.map((location) => (
|
||||||
<NavItem onClick={() => handleClick(location)}>{location}</NavItem>
|
<NavItem onClick={() => handleClick(location)}>{location}</NavItem>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const { ref, isCompVisible, openComp } = useComponentVisible(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const recheckIsPhone = () => {
|
const recheckIsPhone = () => {
|
||||||
setIsPhone(window.matchMedia("(min-width: 720px)").matches);
|
setIsPhone(window.matchMedia("(min-width: 720px)").matches);
|
||||||
|
@ -28,15 +30,11 @@ const NavigationMenu: FC = () => {
|
||||||
locationButtons
|
locationButtons
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<button
|
<button onClick={() => openComp()}>
|
||||||
onClick={() =>
|
|
||||||
setShowNavButtonsPhone(!showNavButtonsPhone)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">menu</span>
|
<span className="material-symbols-outlined">menu</span>
|
||||||
</button>
|
</button>
|
||||||
{showNavButtonsPhone && (
|
{isCompVisible && (
|
||||||
<SideBarBox>{locationButtons}</SideBarBox>
|
<SideBarBox ref={ref}>{locationButtons}</SideBarBox>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import styled from "styled-components";
|
import styled, { keyframes } from "styled-components";
|
||||||
|
|
||||||
export const Wrapper = styled("div")`
|
export const Wrapper = styled("div")`
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -34,11 +34,25 @@ export const GithubLogo = styled("img")(() => ({
|
||||||
padding: "5px",
|
padding: "5px",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const SideBarBox = styled("div")((props) => ({
|
const comeFromLeft = keyframes`
|
||||||
position: "fixed",
|
from{
|
||||||
top: "5em",
|
left: 100%;
|
||||||
left: "calc(100% - 10em)",
|
}
|
||||||
overflow: "overlay",
|
to {
|
||||||
backgroundColor: props.theme.palette.aero,
|
left: calc(100% - 10em);
|
||||||
textAlign: "center",
|
}
|
||||||
}));
|
`;
|
||||||
|
|
||||||
|
export const SideBarBox = styled("div")`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
animation: ${comeFromLeft} 0.2s linear;
|
||||||
|
left: calc(100% - 10em);
|
||||||
|
overflow: overlay;
|
||||||
|
background-color: ${(props) => props.theme.palette.aero};
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
padding-top: 5px;
|
||||||
|
`;
|
||||||
|
|
Loading…
Reference in a new issue