57 lines
1.7 KiB
TypeScript
Executable File

"use client";
import React, { createContext, useContext, useEffect, useState } from 'react';
type ThemeContextType = {
theme: string;
setTheme: (theme: string) => void;
};
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [theme, setTheme] = useState<string>('system');
useEffect(() => {
const savedTheme = localStorage.getItem('theme') || 'system';
setTheme(savedTheme);
applyTheme(savedTheme);
}, []);
const applyTheme = (selectedTheme: string) => {
if (selectedTheme === 'dark') {
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
} else if (selectedTheme === 'light') {
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
} else {
localStorage.removeItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (systemPrefersDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
};
const handleThemeChange = (newTheme: string) => {
setTheme(newTheme);
applyTheme(newTheme);
};
return (
<ThemeContext.Provider value={{ theme, setTheme: handleThemeChange }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};