Skip to content

Instantly share code, notes, and snippets.

@fResult
Created January 14, 2021 10:23
Show Gist options
  • Save fResult/f529d146b08a1844381e4acc3575265a to your computer and use it in GitHub Desktop.
Save fResult/f529d146b08a1844381e4acc3575265a to your computer and use it in GitHub Desktop.
Create ThemeContext provider in `src` folder
import React, { useState, useEffect } from 'react'
function getInitialTheme(): string {
if (typeof window !== 'undefined' && window.localStorage) {
const storedPrefs = window.localStorage.getItem('theme')
if (typeof storedPrefs === 'string') {
return storedPrefs
}
const userMedia = window.matchMedia('(prefers-color-scheme: dark)')
if (userMedia.matches) {
return 'dark'
}
}
return 'dark'
}
type ThemeProviderProps = {
initialTheme?: string
children: React.ReactNode
}
interface ThemeContextProps {
theme?: string
setTheme?: React.Dispatch<React.SetStateAction<string>>
}
export const ThemeContext = React.createContext<ThemeContextProps>({})
function ThemeProvider({ initialTheme, children }: ThemeProviderProps) {
const [theme, setTheme] = useState(getInitialTheme)
useEffect(() => rawSetTheme(theme), [theme])
const rawSetTheme = (theme: string) => {
const root = window.document.documentElement
const isDark = theme === 'dark'
root.classList.remove(isDark ? 'light' : 'dark')
root.classList.add(theme)
localStorage.setItem('theme', theme)
}
if (initialTheme) {
rawSetTheme(initialTheme)
}
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
)
}
export default ThemeProvider
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment