# ThemeSwitcher

> Floating theme and dark/light picker, with the same panel, labels and rows as a dropdown. Several on one page stay in step. Drives data-theme and data-mode on <html> and remembers the choice. A switch lands all at once, crossfaded where the browser has view transitions. It needs every theme in your CSS: run init with --themes=all. ThemeScript sets the attributes before paint; add suppressHydrationWarning to your <html>.

Section: Layout. Docs: https://entrepta.vercel.app/docs/components/theme-switcher

## Install

```bash
npx @entrepta/cli@latest add theme-switcher
```

Files: `layout/theme-switcher.tsx`, `hooks/use-mode.ts`, `hooks/use-theme.ts`, `lib/overlay.ts`.
npm packages: `@phosphor-icons/react`.
Comes with: `use-mode`, `use-theme`, `overlay-lib`.

## Usage

```tsx
import {
  ThemeScript, ThemeSwitcher,
} from "@/components/entrepta/theme-switcher"

// Switching needs every theme in your CSS: run init with --themes=all.
const THEMES = [
  { id: "entrepta", label: "entrepta", color: "#7C6BFF", lightColor: "#6656FF" },
  { id: "blossom",  label: "blossom",  color: "#CC2E36", lightColor: "#B02028" },
  { id: "ivy",      label: "ivy",      color: "#35A365", lightColor: "#258A50" },
] as const

// In your root <head>, before React hydrates:
<ThemeScript storageKey="myapp" />

// Anywhere in the tree (usually the root layout):
<ThemeSwitcher
  themes={THEMES}
  defaultTheme="entrepta"
  storageKey="myapp"
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `themes` | `ThemeOption[]` | - | List of themes. Each `{ id, label, color, lightColor? }`. Required. |
| `defaultTheme` | `string` | themes[0].id | Theme id to use when nothing is stored. |
| `defaultMode` | `"dark" \| "light"` | "dark" | Initial mode when nothing is stored. |
| `storageKey` | `string` | "entrepta" | Prefix for the two localStorage keys (`:theme`, `:mode`). |
| `position` | `"bottom-right" \| "bottom-left" \| "top-right" \| "top-left"` | "bottom-right" | Where the floating trigger anchors. |
| `hideModeToggle` | `boolean` | false | Hide the dark/light section and the mode label on the trigger. |
| `disableMode` | `boolean` | false | Lock mode to `defaultMode`. Useful for dark-only sites. |
