UNPKG

one-file-cli

Version:

Run shadcn/ui React components instantly with zero config - perfect for quick prototypes

113 lines (98 loc) 3.68 kB
import { useThemeStore } from "@/stores/theme" import { useUserThemesStore } from "@/stores/user-themes" import { type FetchedTheme, THEME_URLS, type ThemePreset, fetchThemeFromUrl } from "@/lib/theme-utils" import { toggleThemeMode } from "@/lib/toggle-theme-mode" import { useQuery } from "@tanstack/react-query" import { useMemo, useState } from "react" import { toast } from "sonner" export function useThemeManagement() { const { themeState, setThemeState } = useThemeStore() const { customThemeUrls, addThemeUrl, deleteThemeUrl } = useUserThemesStore() const [searchQuery, setSearchQuery] = useState("") const [selectedThemeUrl, setSelectedThemeUrl] = useState<string | null>(null) // Combine built-in and user-saved theme URLs (deduplicated) const allThemeUrls = useMemo(() => { const urlSet = new Set<string>(THEME_URLS) customThemeUrls.forEach((url) => urlSet.add(url)) return Array.from(urlSet) }, [customThemeUrls]) const { data: fetchedThemes = [], isLoading: isLoadingThemes } = useQuery({ queryKey: ["themes", allThemeUrls], queryFn: () => Promise.all(allThemeUrls.map(fetchThemeFromUrl)), enabled: allThemeUrls.length > 0, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 10 * 60 * 1000 // 10 minutes }) const applyThemePreset = (preset: ThemePreset) => { setThemeState({ currentMode: themeState.currentMode, cssVars: preset.cssVars }) } const handleThemeImported = (preset: ThemePreset, url: string) => { applyThemePreset(preset) setSelectedThemeUrl(url) if (!THEME_URLS.includes(url)) { try { addThemeUrl(url) toast.success("Theme imported successfully") } catch (error) { toast.error(error instanceof Error ? error.message : "Failed to add theme") } } } const handleThemeSelect = (theme: FetchedTheme) => { if ("error" in theme && theme.error) { return } if ("preset" in theme) { applyThemePreset(theme.preset) setSelectedThemeUrl(theme.url) } } const handleThemeDelete = (url: string) => { if (THEME_URLS.includes(url)) return deleteThemeUrl(url) toast.success("Theme deleted successfully") } const toggleMode = () => { toggleThemeMode() } const randomizeTheme = () => { const availableThemes = fetchedThemes.filter((theme) => !("error" in theme && theme.error)) if (availableThemes.length > 0) { const randomTheme = availableThemes[Math.floor(Math.random() * availableThemes.length)] handleThemeSelect(randomTheme) } } const filteredThemes = fetchedThemes.filter((theme) => theme.name.toLowerCase().includes(searchQuery.toLowerCase()) ) const customThemes = filteredThemes.filter((theme) => theme.type === "custom") const builtInThemes = filteredThemes.filter((theme) => theme.type === "built-in") return { // State themeState, searchQuery, setSearchQuery, selectedThemeUrl, setSelectedThemeUrl, isLoadingThemes, fetchedThemes, filteredThemes, customThemes, builtInThemes, // Actions handleThemeImported, handleThemeSelect, handleThemeDelete, toggleMode, randomizeTheme, applyThemePreset } }