Skip to content

Instantly share code, notes, and snippets.

@juliencrn
Last active January 19, 2022 21:57
Show Gist options
  • Save juliencrn/8424b2965793aea4889e045a29409a3c to your computer and use it in GitHub Desktop.
Save juliencrn/8424b2965793aea4889e045a29409a3c to your computer and use it in GitHub Desktop.
import React from 'react'
import { useTernaryDarkMode } from 'usehooks-ts'
export default function Component() {
const {
isDarkMode,
useSystemPrefers,
setTernaryMode,
toggleSystemPrefers,
toggleTheme,
} = useTernaryDarkMode()
return (
<div>
<p>
Current theme: {isDarkMode ? 'dark' : 'light'} (I use{' '}
{useSystemPrefers ? 'system theme mode' : 'my own theme mode'})
</p>
<p>Use system preference: {useSystemPrefers ? 'YES' : 'NO'}</p>
<div>
<button onClick={toggleTheme}>
{isDarkMode ? 'Set light mode' : 'Set dark mode'}
</button>
<button onClick={toggleSystemPrefers}>
{useSystemPrefers ? "don't use system prefers" : 'use system prefers'}
</button>
</div>
<br />
<div>
<button onClick={() => setTernaryMode('light')}>Set light mode</button>
<button onClick={() => setTernaryMode('dark')}>Set dark mode</button>
<button onClick={() => setTernaryMode('system')}>
Set system prefers
</button>
</div>
</div>
)
}
import { useEffect } from 'react'
// See: https://usehooks-ts.com/react-hook/use-local-storage
import { useLocalStorage } from '../useLocalStorage'
// See: https://usehooks-ts.com/react-hook/use-media-query
import { useMediaQuery } from '../useMediaQuery'
const COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'
export enum TernaryDarkMode {
system = 'system',
dark = 'dark',
light = 'light',
}
type TernaryDarkModeKeys = keyof typeof TernaryDarkMode
interface UseTernaryDarkModeOutput {
isDarkMode: boolean
useSystemPrefers: boolean
setTernaryMode: (mode: TernaryDarkModeKeys) => void
toggleSystemPrefers: () => void
toggleTheme: () => void
}
function useTernaryDarkMode(): UseTernaryDarkModeOutput {
const systemMatchesDark = useMediaQuery(COLOR_SCHEME_QUERY)
const [isDarkMode, setDarkMode] = useLocalStorage(
'usehooks-is-dark-theme',
true,
)
const [useSystemPrefers, setUseSystemPrefers] = useLocalStorage(
'usehooks-use-system-prefers-color-scheme',
true,
)
const toggleTheme = () => {
if (useSystemPrefers) {
setUseSystemPrefers(false)
}
setDarkMode(prev => !prev)
}
const toggleSystemPrefers = () => {
setUseSystemPrefers(prev => !prev)
}
const setTernaryMode = (mode: TernaryDarkModeKeys) => {
setUseSystemPrefers(mode === TernaryDarkMode.system)
setDarkMode(mode === TernaryDarkMode.dark)
}
useEffect(() => {
if (useSystemPrefers) {
setDarkMode(systemMatchesDark)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [useSystemPrefers, systemMatchesDark])
return {
isDarkMode,
useSystemPrefers,
setTernaryMode,
toggleTheme,
toggleSystemPrefers,
}
}
export default useTernaryDarkMode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment