Theme Preset Tool
shadcn-customs-ui/theme-preset-toolFreeBlock
Interactive theme builder with 12 OKLCH presets, random palette generator, per-token color editor, radius control, and CSS/JSON export. Standalone — no Redux required.
Install it
npx shadcn@latest add https://formkitcn.pro/r/theme-preset-tool.jsonSource
1"use client";23import {4 createContext,5 type ReactNode,6 useCallback,7 useContext,8 useEffect,9 useMemo,10 useState,11} from "react";1213type ThemeMode = "light" | "dark";14type ThemePreference = ThemeMode | "system";1516export type AppThemeProviderProps = {17 children: ReactNode;18 attribute?: string | string[];19 defaultTheme?: ThemePreference;20 enableSystem?: boolean;21 enableColorScheme?: boolean;22 disableTransitionOnChange?: boolean;23 storageKey?: string;24 forcedTheme?: ThemeMode;25 value?: Record<string, string>;26};2728type AppThemeContextValue = {29 theme: ThemePreference;30 resolvedTheme: ThemeMode;31 systemTheme: ThemeMode;32 setTheme: (value: ThemePreference | ((current: ThemePreference) => ThemePreference)) => void;33};3435const MEDIA = "(prefers-color-scheme: dark)";3637const AppThemeContext = createContext<AppThemeContextValue | undefined>(undefined);3839function getSystemTheme(): ThemeMode {40 if (typeof window === "undefined") {41 return "light";42 }4344 return window.matchMedia(MEDIA).matches ? "dark" : "light";45}4647function disableTransitionsTemporarily() {48 const style = document.createElement("style");49 style.appendChild(50 document.createTextNode(51 "*,*::before,*::after{-webkit-transition:none!important;transition:none!important}"52 )53 );54 document.head.appendChild(style);5556 return () => {57 window.getComputedStyle(document.body);58 window.setTimeout(() => {59 document.head.removeChild(style);60 }, 1);61 };62}6364export function AppThemeProvider({65 children,66 attribute = "class",67 defaultTheme = "dark",68 enableSystem = false,69 enableColorScheme = false,70 disableTransitionOnChange = true,71 storageKey = "app-theme",72 forcedTheme,73 value,74}: AppThemeProviderProps) {75 const [theme, setThemeState] = useState<ThemePreference>(defaultTheme);76 const [systemTheme, setSystemTheme] = useState<ThemeMode>("light");7778 useEffect(() => {79 if (typeof window === "undefined") {80 return;81 }8283 let frameId = 0;8485 try {86 const stored = window.localStorage.getItem(storageKey) as ThemePreference | null;87 if (stored === "light" || stored === "dark" || stored === "system") {88 frameId = window.requestAnimationFrame(() => {89 setThemeState(stored);90 });91 }92 } catch {93 // ignore storage failures94 }9596 return () => window.cancelAnimationFrame(frameId);97 }, [storageKey]);9899 useEffect(() => {100 if (!enableSystem || typeof window === "undefined") {101 return;102 }103104// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from shadcn-customs-ui
All 8 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Data Griddata-table-dynamic | shadcn-customs-ui | Blocks | Free | 8 deps · 17 files | |
| Login Form Templateform-dynamic-template | shadcn-customs-ui | Blocks | Free | 5 deps · 7 files | |
| Field Rendererform-field | shadcn-customs-ui | Blocks | Free | 6 deps · 26 files | |
| Form Layoutform-layout | shadcn-customs-ui | Blocks | Free | no deps · 7 files | |
| Form Layout Templateform-template-01 | shadcn-customs-ui | Blocks | Free | 3 deps | |
| Step Formmultistep-form-template | shadcn-customs-ui | Blocks | Free | 6 deps · 6 files | |
| Redux Toolredux-methods-tool | shadcn-customs-ui | Blocks | Free | 2 deps · 11 files |
