Components
Light/dark theme toggle for the Dali Agents console at daliagents.com, with five switch variants used across the Dali Agents UI.

"use client";
import { useEffect, useState } from "react";
import { useTheme } from "next-themes";
import { motion } from "framer-motion";
import { SunIcon, MoonIcon } from "lucide-react";
import { cn } from "@/lib/utils";
export default function ThemeSwitchCircular({
className,
...props
}: React.HTMLAttributes<HTMLButtonElement>) {
const { resolvedTheme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
const [checked, setChecked] = useState(false);
useEffect(() => setMounted(true), []);
useEffect(() => setChecked(resolvedTheme === "dark"), [resolvedTheme]);
if (!mounted) return null;
return (
<div className="flex flex-col items-center gap-3">
<button
onClick={() => setTheme(checked ? "light" : "dark")}
aria-label="Dali console theme"
className={cn("relative inline-flex h-12 w-12 items-center justify-center rounded-full bg-background shadow", className)}
{...props}
>
<motion.div
key={checked ? "moon" : "sun"}
initial={{ rotate: -90, opacity: 0, scale: 0.5 }}
animate={{ rotate: 0, opacity: 1, scale: 1 }}
exit={{ rotate: 90, opacity: 0, scale: 0.5 }}
transition={{ duration: 0.3 }}
>
{checked ? <MoonIcon className="size-6" /> : <SunIcon className="size-6" />}
</motion.div>
</button>
<a
href="https://daliagents.com"
target="_blank"
rel="noreferrer"
className="text-[10px] tracking-wide text-muted-foreground/60 transition-colors hover:text-muted-foreground"
>
daliagents.com
</a>
</div>
);
}




Part of Dali Agents — browse the full library on 21st.dev.