nav menu wave
This commit is contained in:
1
src/img/menu-wave.svg
Normal file
1
src/img/menu-wave.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#282c34" fill-opacity="1" d="M0,32L60,37.3C120,43,240,53,360,64C480,75,600,85,720,106.7C840,128,960,160,1080,160C1200,160,1320,128,1380,112L1440,96L1440,0L1380,0C1320,0,1200,0,1080,0C960,0,840,0,720,0C600,0,480,0,360,0C240,0,120,0,60,0L0,0Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 330 B |
30
src/nav/Menu.tsx
Normal file
30
src/nav/Menu.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import "./menu.scss";
|
||||
import {motion, animate} from "framer-motion";
|
||||
import {useEffect} from "react";
|
||||
|
||||
const articles = [
|
||||
"Test 123",
|
||||
"Hello",
|
||||
"Title of Album"
|
||||
];
|
||||
const hidden = -999;
|
||||
|
||||
export function Menu({active} : {active: boolean}) {
|
||||
useEffect(() => {
|
||||
if(active) {
|
||||
animate(".menu", {left : 0})
|
||||
} else {
|
||||
animate(".menu", {left : hidden})
|
||||
}
|
||||
}, [active]);
|
||||
|
||||
return (
|
||||
<motion.section className="menu">
|
||||
{
|
||||
articles.map(title => <div>
|
||||
{title}
|
||||
</div>)
|
||||
}
|
||||
</motion.section>
|
||||
)
|
||||
}
|
||||
42
src/nav/Nav.tsx
Normal file
42
src/nav/Nav.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React, {useState} from "react";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faBars} from "@fortawesome/free-solid-svg-icons/faBars";
|
||||
import {Menu} from "./Menu";
|
||||
import wave from "../img/menu-wave.svg";
|
||||
import "./nav.scss";
|
||||
import {motion} from "framer-motion";
|
||||
|
||||
export function Nav() {
|
||||
const [active, setActive] = useState(false);
|
||||
|
||||
return <>
|
||||
<nav className="header">
|
||||
<MenuButton active={active} setActive={setActive}/>
|
||||
<Title/>
|
||||
</nav>
|
||||
<Menu active={active}/>
|
||||
<img className="wave" alt="wave" src={wave}/>
|
||||
</>;
|
||||
}
|
||||
|
||||
function MenuButton(props : { active: boolean, setActive: (_:boolean) => void }) {
|
||||
const {active, setActive} = props;
|
||||
|
||||
return (
|
||||
<div className="menu-btn click">
|
||||
<button>
|
||||
<FontAwesomeIcon icon={faBars} onClick={function() {
|
||||
setActive(!active);
|
||||
}} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Title() {
|
||||
return (
|
||||
<a href="/" className="name click">
|
||||
<motion.h1>Tymur Arsentiev</motion.h1>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
16
src/nav/menu.scss
Normal file
16
src/nav/menu.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
@import "./nav";
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: $menu;
|
||||
z-index: 10;
|
||||
color: white;
|
||||
width: 25%;
|
||||
height: 100vh;
|
||||
|
||||
div {
|
||||
padding: $padding;
|
||||
}
|
||||
}
|
||||
52
src/nav/nav.scss
Normal file
52
src/nav/nav.scss
Normal file
@@ -0,0 +1,52 @@
|
||||
$padding: 15px;
|
||||
$menu: #282c34;
|
||||
|
||||
.click:hover {
|
||||
opacity: 90%;
|
||||
}
|
||||
|
||||
.click:active {
|
||||
opacity: 80%;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
justify-self: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
button {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: $menu;
|
||||
padding: $padding;
|
||||
display: flex;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
min-height: 3 * $padding;
|
||||
}
|
||||
|
||||
.name {
|
||||
align-self: center;
|
||||
flex-grow: 1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wave {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
left: -10%;
|
||||
width: 110%;
|
||||
}
|
||||
14
src/router/RouterContext.tsx
Normal file
14
src/router/RouterContext.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import {createContext, PropsWithChildren, useContext, useSyncExternalStore} from "react";
|
||||
|
||||
const RouterContext = createContext<{}>({});
|
||||
|
||||
export function useRouter() {
|
||||
return useContext(RouterContext);
|
||||
}
|
||||
|
||||
export function RouterProvider(props : PropsWithChildren) {
|
||||
|
||||
return <RouterContext.Provider value={{}}>
|
||||
{props.children}
|
||||
</RouterContext.Provider>
|
||||
}
|
||||
Reference in New Issue
Block a user