119 lines
No EOL
3.1 KiB
Text
119 lines
No EOL
3.1 KiB
Text
---
|
|
---
|
|
<div class="theme-dropdown" id="theme-dropdown">
|
|
<button class="theme-switcher" id="theme-switcher">Theme</button>
|
|
<div class="menu-body" id="menu-body">
|
|
<div class="dropdown-item" data-theme="auto">System</div>
|
|
<div class="dropdown-item" data-theme="dark">Dark</div>
|
|
<div class="dropdown-item" data-theme="light">Light</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.theme-dropdown {
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
|
|
.menu-body {
|
|
display: none;
|
|
position: fixed;
|
|
right: 45px;
|
|
bottom: 70px;
|
|
background-color: var(--bg-color);
|
|
border: 1px solid var(--border-color);
|
|
min-width: 140px;
|
|
z-index: 20;
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.dropdown-item {
|
|
padding: 0.5rem 1rem;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.dropdown-item:hover {
|
|
background-color: var(--border-color);
|
|
}
|
|
|
|
.dropdown-item.active {
|
|
color: var(--accent-color);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.theme-dropdown:hover .menu-body {
|
|
display: block;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// Constants for theme options
|
|
const THEME_AUTO = 'auto';
|
|
const THEME_DARK = 'dark';
|
|
const THEME_LIGHT = 'light';
|
|
|
|
// DOM elements
|
|
const themeDropdown = document.getElementById('theme-dropdown');
|
|
const menuBody = document.getElementById('menu-body');
|
|
const dropdownItems = document.querySelectorAll('.dropdown-item');
|
|
const root = document.documentElement;
|
|
|
|
// Get system preference
|
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
const systemTheme = prefersDark ? THEME_DARK : THEME_LIGHT;
|
|
|
|
// Get saved theme from localStorage or default to auto
|
|
const savedThemeMode = localStorage.getItem('themeMode') || THEME_AUTO;
|
|
const savedTheme = localStorage.getItem('theme');
|
|
|
|
// Function to update active state in dropdown menu
|
|
function updateActiveState(activeTheme) {
|
|
dropdownItems.forEach(item => {
|
|
if (item.getAttribute('data-theme') === activeTheme) {
|
|
item.classList.add('active');
|
|
} else {
|
|
item.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Function to apply theme
|
|
function applyTheme(themeMode) {
|
|
// Update active state in dropdown
|
|
updateActiveState(themeMode);
|
|
|
|
// Save theme mode preference
|
|
localStorage.setItem('themeMode', themeMode);
|
|
|
|
// Apply the appropriate theme
|
|
if (themeMode === THEME_AUTO) {
|
|
// Follow system
|
|
localStorage.removeItem('theme');
|
|
root.removeAttribute('data-theme');
|
|
} else {
|
|
// Set to specific theme
|
|
root.setAttribute('data-theme', themeMode);
|
|
localStorage.setItem('theme', themeMode);
|
|
}
|
|
}
|
|
|
|
// Initialize theme
|
|
applyTheme(savedThemeMode);
|
|
|
|
// Add click handlers to dropdown items
|
|
dropdownItems.forEach(item => {
|
|
item.addEventListener('click', () => {
|
|
const selectedTheme = item.getAttribute('data-theme');
|
|
applyTheme(selectedTheme);
|
|
});
|
|
});
|
|
|
|
// Listen for system preference changes
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
|
if (savedThemeMode === THEME_AUTO) {
|
|
// Only update if we're in auto mode
|
|
root.removeAttribute('data-theme');
|
|
}
|
|
});
|
|
</script> |