Files
rainblogweb/frontend/src/theme.jsx
T
miaomiao 1bed2dda5f P3: 前端工程化搭建 - Vite + React 多入口脚手架
- vite.config.js 双入口(前台 index + 后台 admin),产物输出 public/dist
- 前台 App 布局壳 + 11 条路由占位;api client/theme/utils 共享层
- index.html 保留 ${site_name} 等占位符与 style.css 引用(UI 100% 还原基础)
- dev 代理 3101,构建产物 gitignored
2026-08-06 22:29:03 +08:00

45 lines
1.3 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
// 与 v1 一致:深色模式由 document.documentElement 上的 data-theme="dark" 控制
// public/css/style.css 使用 [data-theme="dark"] 选择器,非 .dark 类)
const THEME_KEY = 'theme';
const ThemeContext = createContext(null);
function applyTheme(theme) {
if (theme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.removeAttribute('data-theme');
}
}
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState(() => {
const saved = localStorage.getItem(THEME_KEY);
if (saved === 'dark' || saved === 'light') return saved;
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
});
useEffect(() => {
applyTheme(theme);
localStorage.setItem(THEME_KEY, theme);
}, [theme]);
const value = useMemo(
() => ({
theme,
toggleTheme: () => setTheme((t) => (t === 'dark' ? 'light' : 'dark')),
setTheme,
}),
[theme]
);
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error('useTheme 必须在 ThemeProvider 内使用');
return ctx;
}