Skip to content

Commit 9773e8e

Browse files
committed
improvement:darkmode
1 parent 233a95f commit 9773e8e

4 files changed

Lines changed: 95 additions & 2 deletions

File tree

css/style.css

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,27 @@
1717
--radius-lg: 0.75rem;
1818
}
1919

20+
[data-theme="dark"] {
21+
--bg-light: #0f172a;
22+
--bg-white: #1e293b;
23+
--text-primary: #f1f5f9;
24+
--text-secondary: #94a3b8;
25+
--border-color: #334155;
26+
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
27+
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
28+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4);
29+
}
30+
2031
* {
2132
margin: 0;
2233
padding: 0;
2334
box-sizing: border-box;
35+
transition: background-color 0.6s cubic-bezier(0.4, 0, 0.2, 1), color 0.6s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.6s cubic-bezier(0.4, 0, 0.2, 1);
2436
}
2537

2638
html {
2739
scroll-behavior: smooth;
40+
background-color: var(--bg-light);
2841
}
2942

3043
body {
@@ -38,6 +51,10 @@ body {
3851
flex-direction: column;
3952
}
4053

54+
* {
55+
transition: background-color 0.5s ease, color 0.5s ease, border-color 0.5s ease;
56+
}
57+
4158
#root {
4259
flex: 1;
4360
display: flex;
@@ -120,6 +137,39 @@ nav {
120137
justify-content: space-between;
121138
align-items: center;
122139
padding: 1.25rem 0;
140+
gap: 1rem;
141+
}
142+
143+
.dark-mode-toggle {
144+
display: flex;
145+
align-items: center;
146+
justify-content: center;
147+
width: 40px;
148+
height: 40px;
149+
border: none;
150+
background-color: var(--bg-light);
151+
color: var(--text-primary);
152+
border-radius: var(--radius-md);
153+
cursor: pointer;
154+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
155+
}
156+
157+
.dark-mode-toggle:hover {
158+
background-color: var(--primary-color);
159+
color: white;
160+
transform: scale(1.05);
161+
}
162+
163+
.dark-mode-toggle:active {
164+
transform: scale(0.95);
165+
}
166+
167+
.dark-mode-toggle i {
168+
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
169+
}
170+
171+
.dark-mode-toggle:hover i {
172+
transform: rotate(15deg);
123173
}
124174

125175
.logo {

js/app.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ const DevPanel = ({ onToggle }) => {
1313

1414
const App = () => {
1515
const [currentPage, setCurrentPage] = useState('home');
16+
const [isDark, setIsDark] = useState(false);
17+
18+
useEffect(() => {
19+
const savedTheme = localStorage.getItem('theme');
20+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
21+
22+
const initialDark = savedTheme === 'dark' || (savedTheme === null && prefersDark);
23+
setIsDark(initialDark);
24+
document.documentElement.setAttribute('data-theme', initialDark ? 'dark' : 'light');
25+
}, []);
1626

1727
useEffect(() => {
1828
const handlePopState = () => {
@@ -37,6 +47,13 @@ const App = () => {
3747
Config.setMode(!Config.isDevelopment);
3848
};
3949

50+
const handleToggleDarkMode = () => {
51+
const newDark = !isDark;
52+
setIsDark(newDark);
53+
document.documentElement.setAttribute('data-theme', newDark ? 'dark' : 'light');
54+
localStorage.setItem('theme', newDark ? 'dark' : 'light');
55+
};
56+
4057
const renderPage = () => {
4158
switch (currentPage) {
4259
case 'works':
@@ -53,7 +70,7 @@ const App = () => {
5370
return (
5471
<div className="app">
5572
{Config.isDevelopment && <DevPanel onToggle={handleToggleMode} />}
56-
<Header currentPage={currentPage} onNavigate={handleNavigate} />
73+
<Header currentPage={currentPage} onNavigate={handleNavigate} isDark={isDark} onToggleDarkMode={handleToggleDarkMode} />
5774
{renderPage()}
5875
<Footer />
5976
</div>

js/components/DarkModeToggle.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const DarkModeToggle = ({ isDark, onToggle }) => {
2+
return (
3+
<button
4+
onClick={onToggle}
5+
className="dark-mode-toggle"
6+
aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
7+
>
8+
{isDark ? (
9+
<i className="fa-solid fa-sun" style={{ fontSize: '1.25rem' }}></i>
10+
) : (
11+
<i className="fa-solid fa-moon" style={{ fontSize: '1.25rem' }}></i>
12+
)}
13+
</button>
14+
);
15+
};

js/components/Header.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const Header = ({ currentPage, onNavigate }) => {
1+
const Header = ({ currentPage, onNavigate, isDark, onToggleDarkMode }) => {
22
const navItems = [
33
{ id: 'home', label: 'Home' },
44
{ id: 'works', label: 'Works' },
@@ -24,6 +24,17 @@ const Header = ({ currentPage, onNavigate }) => {
2424
</li>
2525
))}
2626
</ul>
27+
<button
28+
onClick={onToggleDarkMode}
29+
className="dark-mode-toggle"
30+
aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
31+
>
32+
{isDark ? (
33+
<i className="fa-solid fa-sun" style={{ fontSize: '1.25rem' }}></i>
34+
) : (
35+
<i className="fa-solid fa-moon" style={{ fontSize: '1.25rem' }}></i>
36+
)}
37+
</button>
2738
</nav>
2839
</div>
2940
</header>

0 commit comments

Comments
 (0)