mirror of
https://github.com/DerTyp7/dertyp7.github.io.git
synced 2025-10-29 12:52:08 +01:00
add theme switch
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import "@styles/Header.scss";
|
||||
import ThemeSwitch from "@components/ThemeSwitch";
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<header className="header">
|
||||
<div className="logo">brandname</div>
|
||||
<div className="logo">
|
||||
<h1>Meister</h1>
|
||||
</div>
|
||||
<div className="links">
|
||||
<a href="">Link1</a>
|
||||
<a href="">Link2</a>
|
||||
@@ -10,7 +14,7 @@ export default function Header() {
|
||||
<a href="">Link4</a>
|
||||
</div>
|
||||
<div className="control">
|
||||
<div>Theme</div>
|
||||
<ThemeSwitch />
|
||||
<div>Language</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
63
src/components/ThemeSwitch.tsx
Normal file
63
src/components/ThemeSwitch.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--color-background-body);
|
||||
min-height: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
a {
|
||||
margin-left: 1rem;
|
||||
text-decoration: none;
|
||||
color: #323232;
|
||||
color: var(--color-font-link-header);
|
||||
font-weight: 600;
|
||||
font-size: 1.2rem;
|
||||
transition: all 0.1s ease-in-out;
|
||||
border-bottom: 3px solid transparent;
|
||||
border-bottom: 3px solid var(--color-font-link-header);
|
||||
|
||||
&:hover {
|
||||
color: #000000;
|
||||
border-color: #000000;
|
||||
color: var(--color-font-link-header-hover);
|
||||
border-color: var(--color-font-link-header-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
src/styles/ThemeSwitch.scss
Normal file
26
src/styles/ThemeSwitch.scss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
@import "variables_colors.scss";
|
||||
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
background-color: #ffffff;
|
||||
color: var(--color-font);
|
||||
background-color: var(--color-background-body);
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
@@ -19,3 +21,15 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body,
|
||||
#root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user