Reputation: 31
I want to create a theme customizer like the theme page on shadcn/ui, for a personal project.
But I'm having trouble. I did a git clone of the shadcn project to try to understand how it works, but I didn't have any success!
I tried three things:
import { useAtom } from "jotai"
import { atomWithStorage } from "jotai/utils"
type Config = {
theme: string
}
const configAtom = atomWithStorage<Config>("config", {
theme: "zinc",
})
export function useConfig() {
return useAtom(configAtom)
}
"use client"
import { cn } from "@/lib/utils"
import { useConfig } from "@/hooks/use-config"
export function ThemeWrapper({
children,
className,
}: React.ComponentProps<"div">) {
const [config] = useConfig()
return (
<div
className={cn(
`theme-${config.theme}`,
className
)}
>
{children}
</div>
)
}
"use client"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { Button } from "./ui/button";
import { Palette } from "lucide-react";
import { useConfig } from "@/hooks/use-config";
type Colors = "violet" | "rose" | "green" | "blue" | "yellow" | "orange"
const colors: Colors[] = ["violet", "rose", "green", "blue", "yellow", "orange"]
export function ToggleStyle() {
const [config, setConfig] = useConfig()
const bgColors = {
violet: "bg-violet-600",
rose: "bg-rose-600",
green: "bg-green-600",
blue: "bg-blue-600",
yellow: "bg-yellow-600",
orange: "bg-orange-600"
}
return (
<Popover>
<PopoverTrigger asChild>
<Button className="group" variant="ghost" size="icon">
<Palette className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all group-hover:rotate-45" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-max p-3">
<p className="text-popover-foreground text-xs font-medium mb-2">
Color
</p>
<ToggleGroup
className="grid grid-cols-2"
type="single"
variant="outline"
value={config.theme}
onValueChange={(value) => {
if (value) setConfig({ theme: value })
}}
>
{colors.map(color => (
<ToggleGroupItem size="sm" value={color} className="capitalize flex justify-start items-center gap-2 text-xs">
<div className={`w-5 h-5 rounded-full ${bgColors[color]}`} />
{color}
</ToggleGroupItem>
))}
</ToggleGroup>
</PopoverContent>
</Popover>
)
}
I did everything exactly as it was in the shadcn code! Am I forgetting something?
Upvotes: 3
Views: 939