0.3.0 • Published 2 months ago
jotai-dark v0.3.0
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 type="button" onClick={toggleDark} className={"flex " + className}>
<div className="i-lucide-sun scale-100 dark:scale-0 transition-transform duration-500 rotate-0 dark:-rotate-90" />
<div className="i-lucide-moon absolute scale-0 dark:scale-100 transition-transform duration-500 rotate-90 dark:rotate-0" />
<span className="sr-only">Toggle theme</span>
</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>
See also
License
MIT License © 2023-PRESENT Stephen Zhou