Last active
January 19, 2022 21:57
-
-
Save juliencrn/8424b2965793aea4889e045a29409a3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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