ThemeStudio

Live editor for the active palette's CSS custom properties. Seeds its values from the currently-rendered theme via getComputedStyle and writes edits straight to document.documentElement, so changes are visible instantly.

Installation

pnpm dlx shadcn@latest add @shadmin/theme-studio

Usage

import { ThemeProvider } from "@/components/admin";
import { ThemeStudio } from "@/components/extras/theme-studio";
 
<ThemeProvider>
  <ThemeStudio />
</ThemeProvider>;

ThemeStudio takes no theme prop — it reads the live token values off :root (over a fixed list of shadcn semantic tokens), so it always reflects whatever palette and mode are currently active. Editing a value writes it to document.documentElement.style via setProperty, so the surrounding admin UI updates immediately — no rebuild, no reload. Color-valued tokens (e.g. oklch(...), #aabbcc, rgb(...)) get a swatch + color-picker; size-valued tokens get a numeric input plus a unit select. Requires a surrounding <ThemeProvider> for the light/dark mode toggle to work.

Props

PropRequiredTypeDefaultDescription
showExportOptionalbooleantrueWhether to render the Export button.
showThemeModeToggleOptionalbooleantrueWhether to render the light/dark mode toggle.
classNameOptionalstring-CSS class applied to the outer card.

showExport

Toggles the Export button (default true). Set to false to hide it entirely — useful when the studio is embedded in a settings panel that has its own save flow.

<ThemeStudio showExport={false} />

showThemeModeToggle

Toggles the built-in light/dark mode toggle in the card header (default true). The studio edits whichever mode is currently active, so flipping the mode lets you tune the light and dark variants separately.

<ThemeStudio showThemeModeToggle={false} />

className

Custom class applied to the outer Card. Combine with cn to tweak the default max-h-[60vh] overflow-y-auto.

<ThemeStudio className="max-h-[80vh]" />

Export

The Export button copies a CSS snippet to the clipboard via navigator.clipboard.writeText — a :root { … } block for the edits made in light mode and a .dark { … } block for those made in dark mode (each block is emitted only once you've edited that mode). Paste the snippet into your globals.css to persist the changes.

Edits are not persisted by the component — reload reverts to the stylesheet's values. Persistence is the caller's responsibility (typical pattern: export the CSS and paste it into your theme stylesheet).

Limitations

  • Edits the semantic shadcn tokens (--background, --primary, the chart and sidebar tokens, --radius, …); it does not expose arbitrary custom variables.
  • No undo/redo — live edits stack on document.documentElement.style.
  • No persistence — reload reverts to the stylesheet's values.