bloxa

Theme Provider

FREE

App-wide theme provider for light/dark/system mode, brand color, radius and font — remembered per visitor, with no flash on load. ThemeCustomizer lets visitors change it themselves.

Installation

Terminal
npx @bloxa/cli add theme-provider
# or: npx shadcn@latest add @bloxa/theme-provider

Install separately: theme-customizer

Terminal
npx shadcn@latest add @bloxa/theme-customizer

Examples

Theme customizer

Use the palette button to change color, radius and font. Here it only themes this box; in an app it themes the whole page.

Weekly report

NEW

Open the palette to change color, radius and font.

Goal64%

Inline panel and useTheme

ThemePanel for a settings page; read the choices with useTheme.

Color
Corner radius12px
Font
{
  "resolvedMode": "dark",
  "color": "#3b82f6",
  "radius": null,
  "font": null
}

API reference

Every component also accepts the props of the element it renders.

ThemeProvider

Wrap your root layout. Put <ThemeScript /> with the same props in <head> to avoid a flash on load.

PropTypeDefaultDescription
defaultsPartial<ThemeSettings>{ mode: "system" }Starting values before the visitor changes anything (mode, color, radius, font).
fontsThemeFont[]Sans, Serif, Mono, RoundedFonts offered: { id, label, family }. Load web fonts yourself.
colorsstring[]10 colorsPreset swatches (hex).
storageKeystring | null"bloxa-theme-settings"localStorage key; null keeps choices for this visit only.
targetRefObject<HTMLElement>—Theme only this element instead of the whole page.

useTheme()

Current values and setters.

PropTypeDefaultDescription
mode / resolvedMode"system" | "light" | "dark"—Chosen mode and the one actually shown (light/dark).
setMode, setColor, setRadius, setFont(value) => void—Change a value; null goes back to the default.
reset() => void—Reset every choice.

ThemeCustomizer

PropTypeDefaultDescription
sections("mode" | "color" | "radius" | "font")[]allSections to show, in order.
radiusRange[number, number][0, 24]Radius slider range in px.
triggerReactElement—Your own trigger; defaults to a palette icon button.
side / alignstring"bottom" / "end"Where the panel opens.

ThemePanel

The same controls without the popover; for a settings page or drawer.

ThemeModeToggle

PropTypeDefaultDescription
modes("light" | "dark" | "system")[]["light", "dark", "system"]Modes to offer, in order.
size"sm" | "md""md"Button size.