Skip to content

Commit 4c93d7d

Browse files
committed
Add theme toggle button with light/dark mode functionality to header component
1 parent c7a901c commit 4c93d7d

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

public/js/components/pf-header.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,31 @@ class PfHeader extends HTMLElement {
2727
justify-content: space-between;
2828
margin-bottom: 30px;
2929
}
30+
31+
/* Theme toggle styles */
32+
.theme-toggle {
33+
margin-left: 15px;
34+
background-color: transparent;
35+
border: 1px solid #ddd;
36+
border-radius: 50%;
37+
width: 36px;
38+
height: 36px;
39+
display: flex;
40+
align-items: center;
41+
justify-content: center;
42+
cursor: pointer;
43+
transition: background-color 0.2s;
44+
}
45+
46+
.theme-toggle:hover {
47+
background-color: #f0f0f0;
48+
}
49+
50+
.theme-toggle svg {
51+
width: 20px;
52+
height: 20px;
53+
fill: currentColor;
54+
}
3055
3156
.logo {
3257
display: flex;
@@ -142,6 +167,16 @@ class PfHeader extends HTMLElement {
142167
<a href="/api-keys" class="nav-link">API Keys</a>
143168
<a href="/login" class="nav-link login-link">Login</a>
144169
<a href="/register" class="subscription-link register-link">Register</a>
170+
<button class="theme-toggle" title="Toggle light/dark theme">
171+
${this.currentTheme === 'dark'
172+
? `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
173+
<path d="M12 18C8.68629 18 6 15.3137 6 12C6 8.68629 8.68629 6 12 6C15.3137 6 18 8.68629 18 12C18 15.3137 15.3137 18 12 18ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.51472 4.92893L4.92893 3.51472L7.05025 5.63604L5.63604 7.05025L3.51472 4.92893ZM16.9497 18.364L18.364 16.9497L20.4853 19.0711L19.0711 20.4853L16.9497 18.364ZM19.0711 3.51472L20.4853 4.92893L18.364 7.05025L16.9497 5.63604L19.0711 3.51472ZM5.63604 16.9497L7.05025 18.364L4.92893 20.4853L3.51472 19.0711L5.63604 16.9497ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z"/>
174+
</svg>`
175+
: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
176+
<path d="M10 7C10 10.866 13.134 14 17 14C18.9584 14 20.729 13.1957 21.9995 11.8995C22 11.933 22 11.9665 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C12.0335 2 12.067 2 12.1005 2.00049C10.8043 3.27105 10 5.04157 10 7ZM4 12C4 16.4183 7.58172 20 12 20C15.0583 20 17.7158 18.2839 19.062 15.7621C18.3945 15.9187 17.7035 16 17 16C12.0294 16 8 11.9706 8 7C8 6.29648 8.08133 5.60547 8.2379 4.938C5.71611 6.28423 4 8.9417 4 12Z"/>
177+
</svg>`
178+
}
179+
</button>
145180
</div>
146181
</div>
147182
`;
@@ -160,7 +195,48 @@ class PfHeader extends HTMLElement {
160195
document.addEventListener('themechange', (event) => {
161196
this.currentTheme = event.detail.theme;
162197
this.updateLogo();
198+
this.updateThemeToggle();
163199
});
200+
201+
// Add event listener for theme toggle button
202+
const themeToggle = this.shadowRoot.querySelector('.theme-toggle');
203+
if (themeToggle) {
204+
themeToggle.addEventListener('click', () => {
205+
this.toggleTheme();
206+
});
207+
}
208+
}
209+
210+
toggleTheme() {
211+
const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
212+
this.currentTheme = newTheme;
213+
214+
// Update the document theme
215+
document.documentElement.setAttribute('data-theme', newTheme);
216+
217+
// Save theme preference
218+
localStorage.setItem('profullstack-theme', newTheme);
219+
220+
// Update UI
221+
this.updateLogo();
222+
this.updateThemeToggle();
223+
224+
// Dispatch theme change event
225+
const event = new CustomEvent('themechange', { detail: { theme: newTheme } });
226+
document.dispatchEvent(event);
227+
}
228+
229+
updateThemeToggle() {
230+
const themeToggle = this.shadowRoot.querySelector('.theme-toggle');
231+
if (themeToggle) {
232+
themeToggle.innerHTML = this.currentTheme === 'dark'
233+
? `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
234+
<path d="M12 18C8.68629 18 6 15.3137 6 12C6 8.68629 8.68629 6 12 6C15.3137 6 18 8.68629 18 12C18 15.3137 15.3137 18 12 18ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.51472 4.92893L4.92893 3.51472L7.05025 5.63604L5.63604 7.05025L3.51472 4.92893ZM16.9497 18.364L18.364 16.9497L20.4853 19.0711L19.0711 20.4853L16.9497 18.364ZM19.0711 3.51472L20.4853 4.92893L18.364 7.05025L16.9497 5.63604L19.0711 3.51472ZM5.63604 16.9497L7.05025 18.364L4.92893 20.4853L3.51472 19.0711L5.63604 16.9497ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z"/>
235+
</svg>`
236+
: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
237+
<path d="M10 7C10 10.866 13.134 14 17 14C18.9584 14 20.729 13.1957 21.9995 11.8995C22 11.933 22 11.9665 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C12.0335 2 12.067 2 12.1005 2.00049C10.8043 3.27105 10 5.04157 10 7ZM4 12C4 16.4183 7.58172 20 12 20C15.0583 20 17.7158 18.2839 19.062 15.7621C18.3945 15.9187 17.7035 16 17 16C12.0294 16 8 11.9706 8 7C8 6.29648 8.08133 5.60547 8.2379 4.938C5.71611 6.28423 4 8.9417 4 12Z"/>
238+
</svg>`;
239+
}
164240
}
165241

166242
updateLogo() {

0 commit comments

Comments
 (0)