# ThemeSwitcher

> A round icon button with a Light, Dark and System menu that sets the next-themes theme.

## Facts

- **Product**: Max
- **Family**: Navigation
- **Global**: `window.DigitalCrew.ThemeSwitcher`
- **Source**: `max-agent: src/components/theme-switcher.tsx`
- **Import in the app**: `import { ThemeSwitcher } from "@/components/theme-switcher";`
- **Live preview**: /design/components/theme-switcher/preview.html
- **Page**: /design/components/theme-switcher

## Guidelines

**Use it for** the app header, next to the notification bell. It takes no props.

**Behaviour**: calls `setTheme("light" | "dark" | "system")` from `useTheme()` (next-themes, through `@/contexts/theme-provider`) and ticks the active item. When the resolved theme changes it updates `<meta name="theme-color">` to `#090706` for dark and `#ffffff` for light. The menu is non-modal (`modal={false}`) and aligned to the end.

**Anatomy**:
- A ghost icon [`Button`](/design/components/button.md), `scale-95 rounded-full`.
- The icon is a `Sun` and a `Moon` at `size-[1.2rem]`, stacked on top of each other. The `dark:` variant swaps them: the outgoing icon goes to `scale-0` and rotates by 90° while the other scales in, with `transition-all`.
- Menu items are Light, Dark and System, each followed by a 14px `Check` pushed right (`ms-auto`) and hidden unless active.

**In this preview**: it sits in its own next-themes provider (`DC.NextThemesProvider`) that writes to a harmless attribute. Choosing an item ticks it but leaves the page's theme alone. The sun or moon follows the page's own dark variant.

**Don't** use it outside the app's `ThemeProvider`, where `setTheme` does nothing. Don't add more themes to its menu: the rest of the appearance options live in Settings › Appearance.

## API

```ts
export declare function ThemeSwitcher(): JSX.Element;
```

## Example

```html
<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
  function App() {
    var ref = React.useRef(null);
    React.useEffect(function () {
      // Open the menu once so the card shows it; Radix opens on a primary-button pointerdown.
      var t = setTimeout(function () {
        var btn = ref.current && ref.current.querySelector("button");
        if (btn) btn.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true, button: 0, pointerType: "mouse" }));
      }, 150);
      return function () { clearTimeout(t); };
    }, []);
    return h("div", { className: "flex justify-end" },
      h("div", { ref: ref, className: "flex items-center gap-1 rounded-full border border-glass bg-background/70 px-2 py-1" },
        h("span", { className: "px-2 text-xs text-muted-foreground" }, "Theme"),
        h(DC.ThemeSwitcher)));
  }
  ReactDOM.createRoot(document.getElementById("root")).render(
    // Its own next-themes provider, writing to a harmless attribute: picking an item ticks it without re-theming this page.
    h(DC.NextThemesProvider, { attribute: "data-nt", storageKey: "ds-theme-switcher-demo", defaultTheme: "system", enableColorScheme: false },
      h(DC.TooltipProvider, { delayDuration: 80 }, h(App))));
})();
</script>
```

## More in Navigation

- [Breadcrumb](/design/components/breadcrumb.md): A page trail that shows where the current page sits in the hierarchy, built from composable parts inside a `<nav aria-label="breadcrumb">`.
- [Header](/design/components/header.md): The app's top bar: a sidebar toggle and a divider, followed by whatever you pass in.
- [ListMapToggle](/design/components/list-map-toggle.md): A two-button segmented switch between a List view and a Map view.
- [Pagination](/design/components/pagination.md): Numbered page links with previous/next and an ellipsis.
- [Sidebar](/design/components/sidebar.md): The app shell: a collapsible left sidebar beside an inset content panel (`SidebarProvider` › `Sidebar` + `SidebarInset`).
- [Tabs](/design/components/tabs.md): A segmented list that switches panels in place: a 36px `muted` track with 3px padding; the active tab lifts onto `background`.
