jotai-dark
v0.4.0
Published
A Jōtai utility package for toggling dark mode
Downloads
30
Readme
jotai-dark
A Jōtai utility package for toggling dark mode
Install
ni jotai jotai-effect jotai-dark
Usage
import { atomDark } from 'jotai-dark'
const isDarkAtom = atomDark({
// all options are optional (default values are shown)
storageKey: 'use-dark',
disableTransition: false,
disableTransitionExclude: [],
applyDarkMode: (isDark: boolean) => {
document.documentElement.classList.toggle('dark', isDark)
},
})
Snippets
use-dark.ts
import { useAtom } from 'jotai'
import { atomDark } from 'jotai-dark'
const isDarkAtom = atomDark({
disableTransition: true,
disableTransitionExclude: ['.i-lucide-sun', '.i-lucide-moon'],
})
export function useDark() {
const [isDark, setIsDark] = useAtom(isDarkAtom)
return {
isDark,
toggleDark: setIsDark as () => void,
theme: (isDark ? 'dark' : 'light') as 'dark' | 'light',
}
}
appearance-switch.tsx
'use client'
import { useDark } from '~/hooks/use-dark'
export function AppearanceSwitch({ className = '' }: { className?: string }) {
const { toggleDark } = useDark()
return (
<button
aria-label="Toggle dark mode"
title="Toggle dark mode"
type="button"
onClick={toggleDark}
className={`flex ${className}`}
>
<div
role="img"
aria-hidden="true"
className="i-lucide-sun scale-100 dark:scale-0 transition-transform duration-500 rotate-0 dark:-rotate-90"
/>
<div
role="img"
aria-hidden="true"
className="i-lucide-moon absolute scale-0 dark:scale-100 transition-transform duration-500 rotate-90 dark:rotate-0"
/>
</button>
)
}
layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html suppressHydrationWarning>
<body>
{
// eslint-disable-next-line @eslint-react/dom/no-dangerously-set-innerhtml
<script
dangerouslySetInnerHTML={{
__html: `!function(){var e=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches,t=localStorage.getItem("use-dark")||'"system"';('"dark"'===t||e&&'"light"'!==t)&&document.documentElement.classList.toggle("dark",!0)}();`,
}}
></script>
}
{children}
</body>
</html>
)
}
index.html
<script>
!(function () {
var e =
window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches,
t = localStorage.getItem('use-dark') || '"system"'
;('"dark"' === t || (e && '"light"' !== t)) &&
document.documentElement.classList.toggle('dark', !0)
})()
</script>