Back to Refine

shadcn/ui ThemedLayout Component | Layout in Refine v5

documentation/docs/ui-integrations/shadcn/components/themed-layout/index.md

3.25.03.6 KB
Original Source

Modern admin dashboards should support both light and dark themes. Users often prefer dark mode for late-night work, while others prefer light mode during the day. This theme system provides everything you need to add theme switching to your Refine app.

The system includes a provider for theme management, toggle buttons for quick switching, and dropdown selectors for explicit theme choice. It automatically saves the user's preference and supports system theme detection.

Installation

Add the theme system to your project:

bash
npx shadcn@latest add https://ui.refine.dev/r/theme-provider.json

This installs the complete theme system with light/dark/system theme support.

Setup

First, wrap your app with the theme provider:

tsx
import { ThemeProvider } from "@/components/refine-ui/theme/theme-provider";

function App() {
  return (
    <ThemeProvider defaultTheme="system" storageKey="refine-ui-theme">
    </ThemeProvider>
  );
}

The defaultTheme="system" means it will automatically match the user's operating system preference. The theme choice is automatically saved to localStorage so users don't have to re-select their preference.

Adding Theme Controls

Now you can add theme switching controls to your layout. The most common approach is adding a theme toggle to your header:

tsx
import { ThemeToggle } from "@/components/refine-ui/theme/theme-toggle";
import { ThemeSelect } from "@/components/refine-ui/theme/theme-select";

function Layout() {
  return (
    <div>
      <header className="flex items-center justify-between p-4">
        <h1>My Admin Dashboard</h1>
        <ThemeToggle />
      </header>
      <nav>
        <ThemeSelect />
      </nav>
    </div>
  );
}

The ThemeToggle cycles through light → dark → system themes with each click. The ThemeSelect shows a dropdown with explicit options.

Custom Theme Control

You can also build custom theme controls using the useTheme hook:

tsx
import { useTheme } from "@/components/refine-ui/theme/theme-provider";

function CustomThemeButton() {
  const { theme, setTheme } = useTheme();

  return (
    <div className="flex gap-2">
      <span>Current: {theme}</span>
      <button onClick={() => setTheme("light")}>Light</button>
      <button onClick={() => setTheme("dark")}>Dark</button>
      <button onClick={() => setTheme("system")}>System</button>
    </div>
  );
}

API Reference

ThemeProvider

PropTypeDefaultDescription
childrenReactNode-Child components
defaultTheme"light" | "dark" | "system""system"Default theme when none is stored
storageKeystring"refine-ui-theme"localStorage key for persistence

ThemeToggle

Cycling button that switches between themes.

PropTypeDescription
classNamestringAdditional CSS classes

ThemeSelect

Dropdown menu for theme selection.

useTheme Hook

Return ValueTypeDescription
theme"light" | "dark" | "system"Current theme
setTheme(theme: "light" | "dark" | "system") => voidFunction to change theme