Update nexus wiki content
This commit is contained in:
124
wiki/concepts/Theme-Toggle.md
Normal file
124
wiki/concepts/Theme-Toggle.md
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
title: "Theme Toggle"
|
||||
type: concept
|
||||
tags: [css, javascript, ux, theme, dark-mode]
|
||||
sources: [design-ux-architect.md]
|
||||
last_updated: 2026-04-24
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Theme Toggle 是允许用户在 light、dark 和 system 三种主题模式之间切换的 UI 组件。所有新站点必须将此组件作为默认必备功能,基于 localStorage 持久化和 `prefers-color-scheme` 检测实现。
|
||||
|
||||
## HTML Structure
|
||||
|
||||
```html
|
||||
<div class="theme-toggle" role="radiogroup" aria-label="Theme selection">
|
||||
<button class="theme-toggle-option" data-theme="light" role="radio" aria-checked="false">
|
||||
<span aria-hidden="true">☀️</span> Light
|
||||
</button>
|
||||
<button class="theme-toggle-option" data-theme="dark" role="radio" aria-checked="false">
|
||||
<span aria-hidden="true">🌙</span> Dark
|
||||
</button>
|
||||
<button class="theme-toggle-option" data-theme="system" role="radio" aria-checked="true">
|
||||
<span aria-hidden="true">💻</span> System
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## CSS Styles
|
||||
|
||||
```css
|
||||
.theme-toggle {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 24px;
|
||||
padding: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.theme-toggle-option {
|
||||
padding: 8px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.theme-toggle-option.active {
|
||||
background: var(--primary-500);
|
||||
color: white;
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript Implementation
|
||||
|
||||
```javascript
|
||||
class ThemeManager {
|
||||
constructor() {
|
||||
this.currentTheme = this.getStoredTheme() || this.getSystemTheme();
|
||||
this.applyTheme(this.currentTheme);
|
||||
this.initializeToggle();
|
||||
}
|
||||
|
||||
getSystemTheme() {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
getStoredTheme() {
|
||||
return localStorage.getItem('theme');
|
||||
}
|
||||
|
||||
applyTheme(theme) {
|
||||
if (theme === 'system') {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
localStorage.removeItem('theme');
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
localStorage.setItem('theme', theme);
|
||||
}
|
||||
this.currentTheme = theme;
|
||||
this.updateToggleUI();
|
||||
}
|
||||
|
||||
initializeToggle() {
|
||||
const toggle = document.querySelector('.theme-toggle');
|
||||
if (toggle) {
|
||||
toggle.addEventListener('click', (e) => {
|
||||
if (e.target.matches('.theme-toggle-option')) {
|
||||
this.applyTheme(e.target.dataset.theme);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
updateToggleUI() {
|
||||
const options = document.querySelectorAll('.theme-toggle-option');
|
||||
options.forEach(option => {
|
||||
option.classList.toggle('active', option.dataset.theme === this.currentTheme);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new ThemeManager();
|
||||
});
|
||||
```
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- [[CSS-Design-System]]:提供颜色变量系统支撑主题切换
|
||||
- [[Theme-Manager]]:JavaScript 主题状态管理类
|
||||
- [[Responsive-Breakpoints]]:与其他响应式设计组件协同
|
||||
- [[Layout-Framework]]:通常放置于 Header/Navigation 区域
|
||||
|
||||
## Sources
|
||||
|
||||
- [[design-ux-architect]] — Theme Toggle 的完整 HTML/CSS/JS 实现规范
|
||||
Reference in New Issue
Block a user