mirror of
https://github.com/DerTyp7/dertyp7.github.io.git
synced 2025-10-30 13:17:10 +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 "@styles/Header.scss";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import Burger from "@components/Burger";
|
||||||
|
import Sidebar from "@components/Sidebar";
|
||||||
|
|
||||||
export default function Header() {
|
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 (
|
return (
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<a href="/" className="logo">
|
<a href="/" className="logo">
|
||||||
<span>{</span>J<span>}</span>
|
<span>{</span>J<span>}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<nav>
|
{isSmallScreen ? (
|
||||||
<a className="current" href="#">
|
<>
|
||||||
About
|
<Burger onClick={toggleSidebar} />
|
||||||
</a>
|
<Sidebar isOpen={isOpen} toggle={toggleSidebar} />
|
||||||
<a href="#skills">Skills</a>
|
</>
|
||||||
<a href="#projects">Projects</a>
|
) : (
|
||||||
</nav>
|
<nav>
|
||||||
|
<a className="current" href="#">
|
||||||
|
About
|
||||||
|
</a>
|
||||||
|
<a href="#skills">Skills</a>
|
||||||
|
<a href="#projects">Projects</a>
|
||||||
|
</nav>
|
||||||
|
)}
|
||||||
</div>
|
</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;
|
justify-content: center;
|
||||||
gap: 50px;
|
gap: 50px;
|
||||||
a {
|
a {
|
||||||
color: #fff;
|
color: var(--color-font);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
font-weight: 500;
|
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 {
|
:root {
|
||||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
// line-height: 1.5;
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
|
|||||||
@@ -3,14 +3,11 @@
|
|||||||
|
|
||||||
--color-background-body: #000000;
|
--color-background-body: #000000;
|
||||||
--color-background-header: transparent;
|
--color-background-header: transparent;
|
||||||
|
--color-background-sidebar: #1a1a1a;
|
||||||
|
|
||||||
--color-font: #ffffff;
|
--color-font: #ffffff;
|
||||||
--color-font-link-header: #1c1c1c;
|
|
||||||
--color-font-link-header-hover: #000;
|
|
||||||
|
|
||||||
--color-border: #1c1c1c;
|
--color-border: #1c1c1c;
|
||||||
--color-border-link-header: transparent;
|
|
||||||
--color-border-link-header-hover: var(--color-accent);
|
|
||||||
|
|
||||||
--color-danger: #cf000f;
|
--color-danger: #cf000f;
|
||||||
--color-success: #009944;
|
--color-success: #009944;
|
||||||
|
|||||||
Reference in New Issue
Block a user