f-ui
Components

Theme Mode Toggle

Compact button that toggles light and dark appearance with animated sun and moon icons.

Theme Mode Toggle flips between light and dark only (no system option on the control itself). It does not import next-themes; connect value / onValueChange from useTheme() or your own store.

Next Themes

Mount ThemeProvider from next-themes at your app root when you integrate outside Fumadocs. This component only renders UI; it does not depend on next-themes at import time.

Installing

pnpm dlx shadcn@latest add https://ui.isaacfei.com/r/theme-mode-toggle.json
npx shadcn@latest add https://ui.isaacfei.com/r/theme-mode-toggle.json
yarn dlx shadcn@latest add https://ui.isaacfei.com/r/theme-mode-toggle.json
bun x shadcn@latest add https://ui.isaacfei.com/r/theme-mode-toggle.json

With a namespace: npx shadcn@latest add @f-ui/theme-mode-toggle — pulls lucide-react and registry button.

Usage

Use when you do not need a system option. Map next-themes “system” to a concrete value for display if needed.

import { ThemeModeToggle } from '@/components/f-ui/theme-mode-toggle';
import { useTheme } from 'next-themes';

function NavThemeToggle() {
  const { theme, setTheme } = useTheme();
  const resolved = theme === 'dark' ? 'dark' : 'light';

  return (
    <ThemeModeToggle
      value={resolved}
      onValueChange={setTheme}
      ariaLabel="Toggle theme"
    />
  );
}

Examples

Toggle drives light/dark; resolved for icon: light

"use client";

import { useTheme } from "next-themes";

import { ThemeModeToggle } from "@/components/f-ui/theme-mode-toggle";

export function ThemeModeToggleDemo() {
  const { theme, setTheme } = useTheme();
  const resolved = theme === "dark" ? "dark" : "light";

  return (
    <div className="flex max-w-sm flex-wrap items-center gap-4">
      <ThemeModeToggle
        value={resolved}
        onValueChange={setTheme}
        ariaLabel="Toggle theme"
      />
      <p className="text-muted-foreground text-xs">
        Toggle drives light/dark; resolved for icon:{" "}
        <span className="text-foreground font-medium tabular-nums">{resolved}</span>
      </p>
    </div>
  );
}

Composition

Ghost Button with stacked sun/moon icons and CSS transitions for dark mode.

API Reference

PropTypeDefault
value"light" | "dark"
onValueChange(value: "light" | "dark") => void
ariaLabelstring"Toggle theme"
classNamestring

On this page