Theme Switcher
Pick a color palette and light/dark mode. Persists in localStorage. You'll see it live in the top-right of this page.
Installation
bin/rails g shadcnrb:component theme_switcher
Usage
Put sui.theme_class on <html> so the server renders the
saved choice, then place the switcher anywhere. The choice lives in the
shadcnrb_theme and shadcnrb_mode cookies.
# In your layout — the saved theme is rendered, nothing flashes
<html class="<%= sui.theme_class %>">
# Anywhere in your UI
<%= sui.theme_switcher %>
Try it
The switcher in the header above is live. Change the theme, reload the page — your choice persists. Dark mode toggles independently.
<%= sui.theme_switcher %>
How it works
Each theme is a CSS class like .sui-theme-blue that overrides
--color-primary / --color-primary-foreground /
--color-ring on <html>. Dark mode is the same
mechanism, just a .dark class. The two combine:
<html class="sui-theme-blue dark"> gives you blue-accented dark.
Because every component uses semantic tokens (no inline bg-blue-500),
components pick up the new values automatically.
Shipped themes
default— neutral zinc (the base palette)bluegreenrosevioletorange
All six ship in app/assets/tailwind/shadcnrb_themes.css, which
application.css pulls in via @import "./shadcnrb_themes.css".
Don't want presets? Delete the import line and ship only the neutral palette.
Adding your own theme
- Open
app/assets/tailwind/shadcnrb_themes.css. - Add a
.sui-theme-<name>rule and a.dark.sui-theme-<name>pair. - Pass the name to the switcher via
themes:— or skip that and use the class directly.
/* app/assets/tailwind/shadcnrb_themes.css */ .sui-theme-brand { --color-primary: oklch(0.6 0.2 320); --color-primary-foreground: oklch(0.985 0 0); --color-ring: oklch(0.6 0.2 320); } .dark.sui-theme-brand { --color-primary: oklch(0.75 0.18 320); --color-primary-foreground: oklch(0.145 0 0); --color-ring: oklch(0.75 0.18 320); }
<%= sui.theme_switcher themes: %w[default blue green brand] %>
Themes only override --color-primary,
--color-primary-foreground, and --color-ring.
Keep it to those three so backgrounds/borders stay neutral and theme swaps
don't touch surface colors. If you want broader recolors, edit the base
application.css tokens instead.
Persisting on the server
The cookie is the default store. To keep the choice with the user's
account, pass the stored value to the helper and listen for the
change event — see
State persistence.
API
| Method | Args | Description |
|---|---|---|
theme_switcher | themes:, **opts | Dropdown with theme swatches + light/dark toggle |
theme_class | theme:, mode: | Classes for <html> from the theme and mode cookies (sui-theme-blue dark). Arguments win over the cookies; nil falls through. |