add theme switch

This commit is contained in:
DerTyp7
2023-10-10 15:44:08 +02:00
parent c9dd93a051
commit 033993eda8
6 changed files with 118 additions and 8 deletions

View File

@@ -1,8 +1,12 @@
import "@styles/Header.scss"; import "@styles/Header.scss";
import ThemeSwitch from "@components/ThemeSwitch";
export default function Header() { export default function Header() {
return ( return (
<header className="header"> <header className="header">
<div className="logo">brandname</div> <div className="logo">
<h1>Meister</h1>
</div>
<div className="links"> <div className="links">
<a href="">Link1</a> <a href="">Link1</a>
<a href="">Link2</a> <a href="">Link2</a>
@@ -10,7 +14,7 @@ export default function Header() {
<a href="">Link4</a> <a href="">Link4</a>
</div> </div>
<div className="control"> <div className="control">
<div>Theme</div> <ThemeSwitch />
<div>Language</div> <div>Language</div>
</div> </div>
</header> </header>

View File

@@ -0,0 +1,63 @@
import "@styles/ThemeSwitch.scss";
import { useEffect, useRef } from "react";
export default function ThemeSwitch() {
const svgRef = useRef<SVGSVGElement>(null);
function switchTheme(theme: string) {
const bodyElement = document.getElementsByTagName("body")[0];
if (theme == "dark") {
bodyElement.classList.add("theme-dark");
} else {
bodyElement.classList.remove("theme-dark");
localStorage.setItem("theme", "light");
}
}
function toggleTheme() {
if (svgRef.current) {
if (localStorage.getItem("theme") == "light") {
svgRef.current.style.animationDirection = "normal";
svgRef.current.style.animationName = "spinThemeSwitch";
} else {
svgRef.current.style.animationDirection = "reverse";
svgRef.current.style.animationName = "spinThemeSwitch";
}
setTimeout(() => {
if (localStorage.getItem("theme") == "light") {
localStorage.setItem("theme", "dark");
switchTheme("dark");
} else {
localStorage.setItem("theme", "light");
switchTheme("light");
}
if (svgRef.current) {
svgRef.current.style.animationName = "";
}
}, 150);
}
}
useEffect(() => {
if (localStorage.getItem("theme") == "dark") {
switchTheme("dark");
} else {
switchTheme("light");
}
}, []);
return (
<div className="themeSwitch" onClick={toggleTheme}>
<svg
ref={svgRef}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path d="M448 256c0-106-86-192-192-192V448c106 0 192-86 192-192zm64 0c0 141.4-114.6 256-256 256S0 397.4 0 256S114.6 0 256 0S512 114.6 512 256z" />
</svg>
</div>
);
}

View File

@@ -1,4 +1,7 @@
#app { #app {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: var(--color-background-body);
min-height: auto;
flex: 1;
} }

View File

@@ -20,15 +20,15 @@
a { a {
margin-left: 1rem; margin-left: 1rem;
text-decoration: none; text-decoration: none;
color: #323232; color: var(--color-font-link-header);
font-weight: 600; font-weight: 600;
font-size: 1.2rem; font-size: 1.2rem;
transition: all 0.1s ease-in-out; transition: all 0.1s ease-in-out;
border-bottom: 3px solid transparent; border-bottom: 3px solid var(--color-font-link-header);
&:hover { &:hover {
color: #000000; color: var(--color-font-link-header-hover);
border-color: #000000; border-color: var(--color-font-link-header-hover);
} }
} }
} }

View File

@@ -0,0 +1,26 @@
.themeSwitch {
svg {
aspect-ratio: 1;
height: 2rem;
cursor: pointer;
animation-duration: 150ms;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-direction: normal;
fill: var(--color-font-nav);
transition: all 50ms linear;
&:hover {
fill: var(--color-font);
}
}
@keyframes spinThemeSwitch {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-180deg);
}
}
}

View File

@@ -1,11 +1,13 @@
@import "variables_colors.scss";
: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; line-height: 1.5;
font-weight: 400; font-weight: 400;
color-scheme: light dark; color-scheme: light dark;
color: rgba(0, 0, 0, 0.87); color: var(--color-font);
background-color: #ffffff; background-color: var(--color-background-body);
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
@@ -19,3 +21,15 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
html {
scroll-behavior: smooth;
}
body,
#root {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}