mirror of
https://github.com/DerTyp7/dertyp7.github.io.git
synced 2025-10-29 21:02:09 +01:00
add theme switch
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
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 {
|
#app {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background-color: var(--color-background-body);
|
||||||
|
min-height: auto;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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 {
|
: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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user