Skip to content

Commit cd7154b

Browse files
committed
Redesign Dark Mode Toggle Button for Better User Experience #470
1 parent 8d810e3 commit cd7154b

File tree

4 files changed

+252
-6
lines changed

4 files changed

+252
-6
lines changed

package-lock.json

Lines changed: 170 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"dependencies": {
2121
"@tailwindcss/vite": "^4.1.14",
22+
"@types/styled-components": "^5.1.34",
2223
"axios": "^1.12.2",
2324
"class-variance-authority": "^0.7.1",
2425
"clsx": "^2.1.1",
@@ -38,6 +39,7 @@
3839
"remark-frontmatter": "^5.0.0",
3940
"remark-gfm": "^4.0.1",
4041
"remark-supersub": "^1.0.0",
42+
"styled-components": "^6.1.19",
4143
"tailwind-merge": "^3.3.1",
4244
"tailwindcss": "^4.1.14",
4345
"tailwindcss-animate": "^1.0.7",

src/components/shared/DarkModeToggle.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState, useEffect } from 'react';
2+
import Switch from '@/styles/DarkToggle';
23

34
const DarkModeToggle = () => {
45
const [isDarkMode, setIsDarkMode] = useState(false);
@@ -26,12 +27,13 @@ const DarkModeToggle = () => {
2627
};
2728

2829
return (
29-
<button
30-
onClick={toggleDarkMode}
31-
className="p-2 rounded-full bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200"
32-
>
33-
{isDarkMode ? '☀️' : '🌙'}
34-
</button>
30+
<>
31+
32+
33+
<Switch checked={isDarkMode} onChange={toggleDarkMode} />;
34+
35+
</>
36+
3537
);
3638
};
3739

src/styles/DarkToggle.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import styled from 'styled-components';
2+
import React from 'react';
3+
4+
interface SwitchProps {
5+
checked: boolean;
6+
onChange: () => void;
7+
}
8+
9+
const Switch: React.FC<SwitchProps> = ({ checked, onChange }) => {
10+
return (
11+
<StyledWrapper>
12+
<label className="switch">
13+
<input
14+
type="checkbox"
15+
checked={checked}
16+
onChange={onChange}
17+
/>
18+
<span className="slider round"></span>
19+
</label>
20+
</StyledWrapper>
21+
);
22+
};
23+
24+
const StyledWrapper = styled.div`
25+
.switch {
26+
position: relative;
27+
display: inline-block;
28+
width: 50px;
29+
height: 28px;
30+
}
31+
32+
.switch input {
33+
opacity: 0;
34+
width: 0;
35+
height: 0;
36+
}
37+
38+
.slider {
39+
position: absolute;
40+
cursor: pointer;
41+
top: 0;
42+
left: 0;
43+
right: 0;
44+
bottom: 0;
45+
background-color: #26c6da; /* sky-teal for light mode */
46+
transition: 0.4s;
47+
border-radius: 34px;
48+
}
49+
50+
.slider:before {
51+
position: absolute;
52+
content: "";
53+
height: 22px;
54+
width: 22px;
55+
left: 3px;
56+
bottom: 3px;
57+
background-color: #fff176; /* yellowish sun knob */
58+
transition: 0.4s;
59+
border-radius: 50%;
60+
}
61+
62+
input:checked + .slider {
63+
background-color: #0d47a1; /* dark blue for dark mode */
64+
}
65+
66+
input:checked + .slider:before {
67+
transform: translateX(22px);
68+
background-color: #90caf9; /* moon knob in light blue */
69+
}
70+
`;
71+
72+
export default Switch;

0 commit comments

Comments
 (0)