colorTheme toggle done.
This commit is contained in:
127
package-lock.json
generated
127
package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^7.0.2",
|
||||
"styled-components": "^6.1.13",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -287,6 +288,24 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/is-prop-valid": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
|
||||
"integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/memoize": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
||||
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
|
||||
},
|
||||
"node_modules/@emotion/unitless": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz",
|
||||
@@ -1413,6 +1432,11 @@
|
||||
"@types/react": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/stylis": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
|
||||
"integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw=="
|
||||
},
|
||||
"node_modules/@vitejs/plugin-react": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
|
||||
@@ -1751,6 +1775,14 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/camelize": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
|
||||
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001690",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
|
||||
@@ -1870,11 +1902,28 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-color-keywords": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
||||
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/css-to-react-native": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
|
||||
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
|
||||
"dependencies": {
|
||||
"camelize": "^1.0.0",
|
||||
"css-color-keywords": "^1.0.0",
|
||||
"postcss-value-parser": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/data-view-buffer": {
|
||||
"version": "1.0.1",
|
||||
@@ -3678,6 +3727,11 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-value-parser": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@@ -3974,6 +4028,11 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/shallowequal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -4188,6 +4247,70 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/styled-components": {
|
||||
"version": "6.1.13",
|
||||
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz",
|
||||
"integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==",
|
||||
"dependencies": {
|
||||
"@emotion/is-prop-valid": "1.2.2",
|
||||
"@emotion/unitless": "0.8.1",
|
||||
"@types/stylis": "4.2.5",
|
||||
"css-to-react-native": "3.2.0",
|
||||
"csstype": "3.1.3",
|
||||
"postcss": "8.4.38",
|
||||
"shallowequal": "1.1.0",
|
||||
"stylis": "4.3.2",
|
||||
"tslib": "2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/styled-components"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 16.8.0",
|
||||
"react-dom": ">= 16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/styled-components/node_modules/postcss": {
|
||||
"version": "8.4.38",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
|
||||
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/styled-components/node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/stylis": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
|
||||
"integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg=="
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^7.0.2",
|
||||
"styled-components": "^6.1.13",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
1
src/assets/icons/colorModeToggle/moon.svg
Normal file
1
src/assets/icons/colorModeToggle/moon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 561 B |
1
src/assets/icons/colorModeToggle/sun.svg
Normal file
1
src/assets/icons/colorModeToggle/sun.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM160 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 902 B |
@@ -1,17 +1,110 @@
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import "../css/Switch.css";
|
||||
import { useState } from "react";
|
||||
import "animate.css";
|
||||
import styled from "styled-components";
|
||||
import SunIcon from "../assets/icons/colorModeToggle/sun.svg?react";
|
||||
import MoonIcon from "../assets/icons/colorModeToggle/moon.svg?react";
|
||||
|
||||
const SwitchBtn = styled.button`
|
||||
background-color: ${(props) =>
|
||||
props.colormode === "dark" ? "#000767" : "#009d28"};
|
||||
border: 1px solid
|
||||
${(props) => (props.colormode === "dark" ? "#f6f1d5" : "#fff145")};
|
||||
border-radius: 99px;
|
||||
width: 50px;
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.748);
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const SwitchContainer = styled.div`
|
||||
transition: background-color 1s ease;
|
||||
grid-area: 8 / 4 / 10 / 5;
|
||||
background-color: ${(props) =>
|
||||
props.colormode === "dark" ? "#131862" : "#69d0ff"};
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
border: 1px solid
|
||||
${(props) => (props.colormode === "dark" ? "#1e2be0" : "#9bdfff")};
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const StyledSunIcon = styled(SunIcon)`
|
||||
fill: #fff145;
|
||||
`;
|
||||
|
||||
const StyledMoonIcon = styled(MoonIcon)`
|
||||
fill: #f6f1d5;
|
||||
`;
|
||||
|
||||
const PlanetsContainer = styled.div`
|
||||
transition: transform 0.5s ease-in-out;
|
||||
transform: ${(props) => `rotate(${props.rotation}deg)`};
|
||||
`;
|
||||
|
||||
const Switch = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => {
|
||||
const [animation, setAnimation] = useState(initialAnimation);
|
||||
const [colormode, setcolormode] = useState(() => {
|
||||
// Retrieve initial color mode from localStorage or default to "dark"
|
||||
return localStorage.getItem("colormode") || "dark";
|
||||
});
|
||||
const [rotation, setRotation] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
// Save the current color mode to localStorage whenever it changes
|
||||
localStorage.setItem("colormode", colormode);
|
||||
}, [colormode]);
|
||||
|
||||
const toggleColorMode = () => {
|
||||
setcolormode((prevMode) => (prevMode === "dark" ? "light" : "dark"));
|
||||
setRotation((prevRotation) => prevRotation + 90);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`switch container animate__animated ${animation}`}
|
||||
<SwitchContainer
|
||||
colormode={colormode}
|
||||
className={`container animate__animated ${animation}`}
|
||||
onAnimationEnd={() => onAnimationEnd(setAnimation)}
|
||||
>
|
||||
switch
|
||||
<div className="wrapper">
|
||||
<PlanetsContainer rotation={rotation} className="planets">
|
||||
<StyledSunIcon
|
||||
colormode={colormode}
|
||||
className={`sun1 toggleIcon ${
|
||||
colormode === "dark" ? "setting" : "rising"
|
||||
}`}
|
||||
/>
|
||||
<StyledMoonIcon
|
||||
colormode={colormode}
|
||||
className={`moon1 toggleIcon ${
|
||||
colormode === "dark" ? "rising" : "setting"
|
||||
}`}
|
||||
/>
|
||||
<StyledSunIcon
|
||||
colormode={colormode}
|
||||
className={`sun2 toggleIcon ${
|
||||
colormode === "dark" ? "setting" : "rising"
|
||||
}`}
|
||||
/>
|
||||
<StyledMoonIcon
|
||||
colormode={colormode}
|
||||
className={`moon2 toggleIcon ${
|
||||
colormode === "dark" ? "rising" : "setting"
|
||||
}`}
|
||||
/>
|
||||
</PlanetsContainer>
|
||||
</div>
|
||||
<SwitchBtn
|
||||
colormode={colormode}
|
||||
className={`colormodeBtn ${colormode}Btn`}
|
||||
onClick={toggleColorMode}
|
||||
>
|
||||
<div className={`colorToggleThumb ${colormode}`}></div>
|
||||
</SwitchBtn>
|
||||
</SwitchContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,8 +10,24 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.imgs img:first-child {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
.imgs img:last-child {
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
.imgs img {
|
||||
height: 55%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.img img {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
height: 55%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.img img,
|
||||
|
||||
@@ -1,38 +1,70 @@
|
||||
.switch {
|
||||
grid-area: 8 / 4 / 10 / 5;
|
||||
}
|
||||
|
||||
.switch-container {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.switch-checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch-label {
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
border-radius: 34px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.switch-label .switch-button {
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
.wrapper {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
transition: transform 0.2s;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
|
||||
.switch-checkbox:checked + .switch-label .switch-button {
|
||||
transform: translateX(26px);
|
||||
.toggleIcon {
|
||||
position: absolute;
|
||||
width: 2rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.colorToggleThumb {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 99px;
|
||||
transform: translateX(0);
|
||||
transition: left 0.3s ease;
|
||||
position: absolute;
|
||||
left: 3px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.colorToggleThumb.dark {
|
||||
left: calc(50px - 25px);
|
||||
}
|
||||
|
||||
.planets {
|
||||
position: absolute;
|
||||
/* border: 1px solid white; */
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
top: 0;
|
||||
left: -80%;
|
||||
}
|
||||
|
||||
/* Top corner */
|
||||
.moon1 {
|
||||
top: 10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/* Right corner */
|
||||
.sun2 {
|
||||
top: 50%;
|
||||
right: 10px;
|
||||
transform: translateY(-50%);
|
||||
fill: aqua;
|
||||
}
|
||||
|
||||
/* Bottom corner */
|
||||
.moon2 {
|
||||
bottom: 10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/* Left corner */
|
||||
.sun1 {
|
||||
top: 50%;
|
||||
left: 10px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user