laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
73 lines (51 loc) • 2.09 kB
Markdown
# ThemeSwitcher
## Overview
Theme toggle with three options: system, light, dark. Uses a controlled/uncontrolled API and avoids hydration mismatch by rendering only after mount.
## Props
| Prop | Type | Default | Description |
| -------------- | ---------------- | ----------- | ------------------ | ----------- | -------------------------------- |
| `value` | `"light" | "dark" | "system"` | `undefined` | Controlled theme value. |
| `onChange` | `(theme: "light" | "dark" | "system") => void` | `undefined` | Called when theme changes. |
| `defaultValue` | `"light" | "dark" | "system"` | `"system"` | Initial value when uncontrolled. |
| `className` | `string` | `undefined` | Container classes. |
## Behavior
- **SSR safe**: Renders `null` until mounted to prevent hydration mismatch.
- **Active state**: Highlights the active option with a rounded background.
- **Control**: Works in both controlled (`value`/`onChange`) and uncontrolled (`defaultValue`) modes.
## Examples
### Default (uncontrolled)
```tsx
import { ThemeSwitcher } from "laif-ds";
export function DefaultTheme() {
return <ThemeSwitcher defaultValue="system" />;
}
```
### Controlled
```tsx
import * as React from "react";
import { ThemeSwitcher } from "laif-ds";
export function ControlledTheme() {
const [theme, setTheme] = React.useState<"light" | "dark" | "system">(
"system",
);
return (
<div className="flex flex-col items-start gap-2">
<ThemeSwitcher value={theme} onChange={setTheme} />
<div className="text-d-muted-foreground text-sm">
Current theme: <span className="font-medium">{theme}</span>
</div>
</div>
);
}
```
### Custom styling
```tsx
<ThemeSwitcher defaultValue="system" className="h-10 w-32 p-2" />
```
## Notes
- **Icons**: The component renders icons internally; no configuration required.
- **Persistence**: Persisting theme choice is up to the app (e.g., localStorage + class on `html`).