mirror of
https://github.com/DerTyp7/dertyp7.github.io.git
synced 2025-10-29 12:52:08 +01:00
Add responsive sidebar to Header component
This commit is contained in:
24
src/components/Burger.tsx
Normal file
24
src/components/Burger.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { useState } from "react";
|
||||
import "@styles/Burger.scss";
|
||||
|
||||
export default function Burger({ onClick }: { onClick: () => void }) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const toggleMenu = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`burger ${isOpen ? "open" : ""}`}
|
||||
onClick={() => {
|
||||
toggleMenu();
|
||||
onClick();
|
||||
}}
|
||||
>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,19 +1,44 @@
|
||||
import "@styles/Header.scss";
|
||||
import { useState, useEffect } from "react";
|
||||
import Burger from "@components/Burger";
|
||||
import Sidebar from "@components/Sidebar";
|
||||
|
||||
export default function Header() {
|
||||
const [isSmallScreen, setIsSmallScreen] = useState(window.innerWidth <= 768);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const toggleSidebar = () => setIsOpen(!isOpen);
|
||||
|
||||
useEffect(() => {
|
||||
const checkScreenSize = () => {
|
||||
setIsSmallScreen(window.innerWidth <= 768);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", checkScreenSize);
|
||||
|
||||
return () => window.removeEventListener("resize", checkScreenSize);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="header">
|
||||
<a href="/" className="logo">
|
||||
<span>{</span>J<span>}</span>
|
||||
</a>
|
||||
|
||||
<nav>
|
||||
<a className="current" href="#">
|
||||
About
|
||||
</a>
|
||||
<a href="#skills">Skills</a>
|
||||
<a href="#projects">Projects</a>
|
||||
</nav>
|
||||
{isSmallScreen ? (
|
||||
<>
|
||||
<Burger onClick={toggleSidebar} />
|
||||
<Sidebar isOpen={isOpen} toggle={toggleSidebar} />
|
||||
</>
|
||||
) : (
|
||||
<nav>
|
||||
<a className="current" href="#">
|
||||
About
|
||||
</a>
|
||||
<a href="#skills">Skills</a>
|
||||
<a href="#projects">Projects</a>
|
||||
</nav>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
23
src/components/Sidebar.tsx
Normal file
23
src/components/Sidebar.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import "@styles/Sidebar.scss";
|
||||
|
||||
export default function Sidebar({
|
||||
isOpen,
|
||||
toggle,
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
toggle: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className={`sidebar ${isOpen ? "open" : ""}`}>
|
||||
<a href="#" onClick={toggle}>
|
||||
About
|
||||
</a>
|
||||
<a href="#skills" onClick={toggle}>
|
||||
Skills
|
||||
</a>
|
||||
<a href="#projects" onClick={toggle}>
|
||||
Projects
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
50
src/styles/Burger.scss
Normal file
50
src/styles/Burger.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
.burger {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 20px;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-flow: column nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
div {
|
||||
width: 2rem;
|
||||
height: 0.25rem;
|
||||
background-color: var(--color-font);
|
||||
border-radius: 10px;
|
||||
transform-origin: 1px;
|
||||
transition: all 200ms linear;
|
||||
|
||||
&:nth-child(1) {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
transform: rotate(0);
|
||||
}
|
||||
}
|
||||
|
||||
&.open {
|
||||
div {
|
||||
background-color: var(--color-accent);
|
||||
&:nth-child(1) {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
justify-content: center;
|
||||
gap: 50px;
|
||||
a {
|
||||
color: #fff;
|
||||
color: var(--color-font);
|
||||
text-decoration: none;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 500;
|
||||
|
||||
35
src/styles/Sidebar.scss
Normal file
35
src/styles/Sidebar.scss
Normal file
@@ -0,0 +1,35 @@
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
background-color: var(--color-background-sidebar);
|
||||
transform: translateX(100%);
|
||||
transition: transform 100ms ease-in-out;
|
||||
|
||||
&.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: 2rem;
|
||||
text-transform: uppercase;
|
||||
padding: 2rem;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.5rem;
|
||||
color: var(--color-font);
|
||||
text-decoration: none;
|
||||
transition: color 50ms linear;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
// line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
|
||||
--color-background-body: #000000;
|
||||
--color-background-header: transparent;
|
||||
--color-background-sidebar: #1a1a1a;
|
||||
|
||||
--color-font: #ffffff;
|
||||
--color-font-link-header: #1c1c1c;
|
||||
--color-font-link-header-hover: #000;
|
||||
|
||||
--color-border: #1c1c1c;
|
||||
--color-border-link-header: transparent;
|
||||
--color-border-link-header-hover: var(--color-accent);
|
||||
|
||||
--color-danger: #cf000f;
|
||||
--color-success: #009944;
|
||||
|
||||
Reference in New Issue
Block a user