mirror of
https://github.com/mastermindzh/rickvanlieshout.com
synced 2025-08-23 17:36:15 +02:00
added compact mode switcher
This commit is contained in:
39
src/components/ThemeSwitcher/ThemeSwitcher.tsx
Normal file
39
src/components/ThemeSwitcher/ThemeSwitcher.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
/* eslint-disable no-undef */
|
||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||
import Toggle from "react-toggle";
|
||||
import { Moon } from "./components/Moon";
|
||||
import { Sun } from "./components/Sun";
|
||||
import "./theme.scss";
|
||||
import { Themes } from "./Themes";
|
||||
|
||||
type Props = { showLabel: boolean };
|
||||
|
||||
export const ThemeSwitcher: FunctionComponent<Props> = ({ showLabel }) => {
|
||||
const initTheme = document.documentElement.dataset.theme;
|
||||
const [theme, setTheme] = useState(initTheme);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem("theme", theme ?? Themes.light);
|
||||
document.documentElement.dataset.theme = theme;
|
||||
}, [theme]);
|
||||
|
||||
function toggleTheme() {
|
||||
const newTheme = theme === Themes.dark ? Themes.light : Themes.dark;
|
||||
setTheme(newTheme);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{showLabel && "Switch color mode:"}
|
||||
{showLabel && <br />}
|
||||
<Toggle
|
||||
checked={theme === Themes.dark}
|
||||
icons={{
|
||||
checked: <Moon />,
|
||||
unchecked: <Sun />,
|
||||
}}
|
||||
onChange={toggleTheme}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
4
src/components/ThemeSwitcher/Themes.ts
Normal file
4
src/components/ThemeSwitcher/Themes.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum Themes {
|
||||
dark = "dark",
|
||||
light = "light",
|
||||
}
|
18
src/components/ThemeSwitcher/components/Moon.tsx
Normal file
18
src/components/ThemeSwitcher/components/Moon.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { faMoon } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import React from "react";
|
||||
|
||||
export const Moon = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
fontSize: "1.1em",
|
||||
position: "absolute",
|
||||
top: "-4px",
|
||||
color: "#f1c40f",
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faMoon} />
|
||||
</div>
|
||||
);
|
||||
};
|
19
src/components/ThemeSwitcher/components/Sun.tsx
Normal file
19
src/components/ThemeSwitcher/components/Sun.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { faSun } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import React from "react";
|
||||
|
||||
export const Sun = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: "#f39c12",
|
||||
position: "absolute",
|
||||
fontSize: "1em",
|
||||
top: "-3px",
|
||||
left: "-3px",
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faSun} />
|
||||
</div>
|
||||
);
|
||||
};
|
116
src/components/ThemeSwitcher/theme.scss
Normal file
116
src/components/ThemeSwitcher/theme.scss
Normal file
@@ -0,0 +1,116 @@
|
||||
.react-toggle {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
touch-action: pan-x;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.react-toggle-screenreader-only {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.react-toggle--disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
-webkit-transition: opacity 0.25s;
|
||||
transition: opacity 0.25s;
|
||||
}
|
||||
|
||||
.react-toggle-track {
|
||||
background-color: #4D4D4D;
|
||||
border-radius: 30px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.react-toggle-track-check {
|
||||
bottom: 0px;
|
||||
height: 10px;
|
||||
left: 8px;
|
||||
line-height: 0;
|
||||
margin-bottom: auto;
|
||||
margin-top: auto;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
-webkit-transition: opacity 0.25s ease;
|
||||
-moz-transition: opacity 0.25s ease;
|
||||
transition: opacity 0.25s ease;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.react-toggle--checked .react-toggle-track-check {
|
||||
opacity: 1;
|
||||
-webkit-transition: opacity 0.25s ease;
|
||||
-moz-transition: opacity 0.25s ease;
|
||||
transition: opacity 0.25s ease;
|
||||
}
|
||||
|
||||
.react-toggle-track-x {
|
||||
bottom: 0px;
|
||||
height: 10px;
|
||||
line-height: 0;
|
||||
margin-bottom: auto;
|
||||
margin-top: auto;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 0px;
|
||||
-webkit-transition: opacity 0.25s ease;
|
||||
-moz-transition: opacity 0.25s ease;
|
||||
transition: opacity 0.25s ease;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.react-toggle--checked .react-toggle-track-x {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.react-toggle-thumb {
|
||||
background-color: #FAFAFA;
|
||||
border: 1px solid #4D4D4D;
|
||||
border-radius: 50%;
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
height: 22px;
|
||||
left: 1px;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
|
||||
-webkit-transition: all 0.25s ease;
|
||||
-moz-transition: all 0.25s ease;
|
||||
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
|
||||
transition: all 0.25s ease;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
.react-toggle--checked .react-toggle-thumb {
|
||||
left: 27px;
|
||||
}
|
Reference in New Issue
Block a user