ThemeProvider
Proveedor de tema con soporte dark/light/system, persistencia en localStorage, ThemeSwitcher incluido y un efecto de ola al cambiar de tema.
pnpm dlx nuvo-ui add theme-providerThemeSwitcher (demo)
Al hacer click, una ola circular se expande desde el botón y cubre la pantalla con el nuevo tema.
Tema seleccionado: dark
Resuelto como: dark
Nota: La ola usa la View Transitions API nativa del navegador (Chrome, Edge). En navegadores sin soporte, o con
prefers-reduced-motion activado, el cambio de tema es instantáneo — nunca se bloquea el toggle.Setup en layout.tsx
// app/layout.tsx
import { ThemeProvider } from "@nuvo-ui/ui"
export default function RootLayout({ children }) {
return (
<html suppressHydrationWarning>
<body>
<ThemeProvider defaultTheme="dark">
{children}
</ThemeProvider>
</body>
</html>
)
}Uso del hook useTheme
"use client"
import { useTheme } from "@nuvo-ui/ui"
function MyHeader() {
const { theme, resolved, setTheme } = useTheme()
return (
// El segundo argumento es opcional: sin él, la ola nace en el centro de la pantalla.
<button onClick={(e) => setTheme(resolved === "dark" ? "light" : "dark", { x: e.clientX, y: e.clientY })}>
Modo actual: {resolved}
</button>
)
}ThemeSwitcher standalone
import { ThemeSwitcher } from "@nuvo-ui/ui"
// Muestra botones Dark / Light / System
<ThemeSwitcher />
// Requiere ThemeProvider en un ancestroProps — ThemeProvider
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| defaultTheme | "dark" | "light" | "system" | "dark" | Tema inicial cuando no hay nada en localStorage |
| storageKey | string | "nuvo-ui-mode" | Clave de localStorage |
| children | ReactNode | — | Árbol de componentes |
Retorno de useTheme
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| theme | "dark" | "light" | "system" | — | Tema seleccionado por el usuario |
| resolved | "dark" | "light" | — | Tema real aplicado (system se resuelve aquí) |
| setTheme | (theme: Theme, origin?: { x: number; y: number }) => void | — | Cambia el tema, persiste en localStorage y dispara la ola desde origin (o el centro si se omite) |