t-convex-nextjs-saas/src/components/core/ThemeChanger.tsx
nxtkofi e8d557b0d2 feat(shell): add shared app shell primitives
Add AppShell, AppNav components and refactor ThemeChanger for header use

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-21 23:26:21 +02:00

52 lines
1.5 KiB
TypeScript

"use client";
import { useTheme } from "@wrksz/themes/client";
import { useSyncExternalStore } from "react";
import { Button } from "@/components/ui/button";
import { HugeiconsIcon } from "@hugeicons/react";
import { Sun01Icon, Moon02Icon } from "@hugeicons/core-free-icons";
import { cn } from "@/lib/utils";
interface ThemeChangerProps {
className?: string;
}
export function ThemeChanger({ className }: ThemeChangerProps) {
const { theme, setTheme } = useTheme();
const mounted = useSyncExternalStore(
() => () => undefined,
() => true,
() => false,
);
if (!mounted) {
return (
<div data-testid="theme-switcher" className={cn("flex items-center gap-1", className)}>
<Button variant="ghost" size="icon" disabled>
<HugeiconsIcon icon={Sun01Icon} className="h-4 w-4" />
</Button>
</div>
);
}
return (
<div data-testid="theme-switcher" className={cn("flex items-center gap-1", className)}>
<Button
variant={theme === "light" ? "default" : "ghost"}
size="icon"
onClick={() => setTheme("light")}
aria-label="Light mode"
>
<HugeiconsIcon icon={Sun01Icon} className="h-4 w-4" />
</Button>
<Button
variant={theme === "dark" ? "default" : "ghost"}
size="icon"
onClick={() => setTheme("dark")}
aria-label="Dark mode"
>
<HugeiconsIcon icon={Moon02Icon} className="h-4 w-4" />
</Button>
</div>
);
}