Files
claudecodeui/src/contexts/ThemeContext.jsx

94 lines
2.9 KiB
JavaScript

import React, { createContext, useContext, useState, useEffect } from 'react';
const ThemeContext = createContext();
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};
export const ThemeProvider = ({ children }) => {
// Check for saved theme preference or default to system preference
const [isDarkMode, setIsDarkMode] = useState(() => {
// Check localStorage first
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
return savedTheme === 'dark';
}
// Check system preference
if (window.matchMedia) {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return false;
});
// Update document class and localStorage when theme changes
useEffect(() => {
if (isDarkMode) {
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
// Update iOS status bar style and theme color for dark mode
const statusBarMeta = document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
if (statusBarMeta) {
statusBarMeta.setAttribute('content', 'black-translucent');
}
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute('content', '#0c1117'); // Dark background color (hsl(222.2 84% 4.9%))
}
} else {
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
// Update iOS status bar style and theme color for light mode
const statusBarMeta = document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
if (statusBarMeta) {
statusBarMeta.setAttribute('content', 'default');
}
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute('content', '#ffffff'); // Light background color
}
}
}, [isDarkMode]);
// Listen for system theme changes
useEffect(() => {
if (!window.matchMedia) return;
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e) => {
// Only update if user hasn't manually set a preference
const savedTheme = localStorage.getItem('theme');
if (!savedTheme) {
setIsDarkMode(e.matches);
}
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);
const toggleDarkMode = () => {
setIsDarkMode(prev => !prev);
};
const value = {
isDarkMode,
toggleDarkMode,
};
return (
<ThemeContext.Provider value={value}>
{children}
</ThemeContext.Provider>
);
};