feat: sb verses extracted
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import { useTheme } from "next-themes";
|
||||
import { Moon, Sun } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { useSyncExternalStore } from "react";
|
||||
|
||||
const emptySubscribe = () => () => {};
|
||||
|
||||
function useMounted() {
|
||||
return useSyncExternalStore(
|
||||
emptySubscribe,
|
||||
() => true,
|
||||
() => false,
|
||||
);
|
||||
}
|
||||
|
||||
export function ThemeToggle() {
|
||||
const { resolvedTheme, setTheme } = useTheme();
|
||||
const mounted = useMounted();
|
||||
|
||||
// Avoid hydration mismatch — on the server and during hydration, render a placeholder
|
||||
if (!mounted) {
|
||||
return (
|
||||
<Button variant="ghost" size="icon-sm" aria-label="Toggle theme">
|
||||
<Sun className="size-4" />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
const isDark = resolvedTheme === "dark";
|
||||
|
||||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={() => setTheme(isDark ? "light" : "dark")}
|
||||
aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{isDark ? <Sun className="size-4" /> : <Moon className="size-4" />}
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">
|
||||
{isDark ? "Light mode" : "Dark mode"}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user