Theme switch support (#3568)

### What problem does this PR solve?
- [x] New Feature (non-breaking change which adds functionality)

---------

Co-authored-by: Yingfeng <yingfeng.zhang@gmail.com>
Co-authored-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
so95
2024-12-10 10:42:04 +07:00
committed by GitHub
parent 7d4f1c0645
commit d5a322a352
85 changed files with 1041 additions and 520 deletions

View File

@ -1,6 +1,6 @@
import { createContext, useContext, useEffect, useState } from 'react';
import React, { createContext, useContext, useEffect, useState } from 'react';
type Theme = 'dark' | 'light' | 'system';
type Theme = 'dark' | 'light';
type ThemeProviderProps = {
children: React.ReactNode;
@ -14,7 +14,7 @@ type ThemeProviderState = {
};
const initialState: ThemeProviderState = {
theme: 'system',
theme: 'light',
setTheme: () => null,
};
@ -22,7 +22,7 @@ const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export function ThemeProvider({
children,
defaultTheme = 'system',
defaultTheme = 'light',
storageKey = 'vite-ui-theme',
...props
}: ThemeProviderProps) {
@ -32,32 +32,19 @@ export function ThemeProvider({
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove('light', 'dark');
if (theme === 'system') {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)')
.matches
? 'dark'
: 'light';
root.classList.add(systemTheme);
return;
}
localStorage.setItem(storageKey, theme);
root.classList.add(theme);
}, [theme]);
const value = {
theme,
setTheme: (theme: Theme) => {
localStorage.setItem(storageKey, theme);
setTheme(theme);
},
};
}, [storageKey, theme]);
return (
<ThemeProviderContext.Provider {...props} value={value}>
<ThemeProviderContext.Provider
{...props}
value={{
theme,
setTheme,
}}
>
{children}
</ThemeProviderContext.Provider>
);