Cambio de tema
En esta página
sitelo-ui resuelve el modo oscuro por su cuenta a partir de prefers-color-scheme: un sitio contento con seguir al sistema operativo no necesita nada de esta página. El conmutador está para dejar que el lector lo sobrescriba.
Es uno de los cinco componentes que necesitan script, porque la elección vive en localStorage y solo un script puede leerla. El botón se descarga ese script él mismo, en la primera pulsación.
Puesta en marcha
Dos cosas en el head, y el botón donde corresponda:
import { styles, themeScript, themeToggle } from 'sitelo/ui'
head(
themeScript(), // aplica la elección guardada antes del primer pintado
styles(),
)
body(
appBar({ brand: 'Mi sitio' },
appBarSpacer(),
appBarActions(themeToggle()),
),
)No hay un tercer archivo. themeScript() es bloqueante y en línea a propósito — todo lo diferido pinta antes, que es justo el destello oscuro que existe para evitar — y el cambio en sí viaja en el botón:
<button data-su-theme-toggle
onclick="import('/su/theme.js').then(m=>m.toggle(this))">Empareja los dos. themeScript() es además lo que marca el conmutador con aria-pressed al cargar: todavía no se ha pulsado nada, así que el botón por sí solo no puede saber qué tema salió.
El conmutador
El icono es CSS puro, leído directamente del atributo de tema, así que ya es correcto en el primer pintado, antes de que corra ningún script. Muestra hacia qué tema cambiará un clic.
stack({ direction: 'row', gap: 'md', align: 'center' },
themeToggle(),
themeToggle({ variant: 'soft' }),
themeToggle({ variant: 'outline' }),
)Esos botones funcionan: esta página carga el runtime. Al pulsar uno se pone data-su-theme en <html>, que es el atributo propio de sitelo-ui, así que solo cambian los componentes de sitelo-ui de esta página. El resto del sitio sigue su propio data-theme, que fija el conmutador de la barra superior. En tu sitio solo habría uno de ellos.
En una barra de aplicación
appBar({ brand: 'sitelo' },
appBarNav(navLink({ href: '#docs', current: true }, 'Documentación')),
appBarSpacer(),
appBarActions(
themeToggle(),
button({ size: 'sm' }, 'Empezar'),
),
)Cómo se resuelve el tema
Por orden: un data-theme o data-su-theme explícito en cualquier ancestro manda; a falta de eso, decide prefers-color-scheme. Se respetan los dos nombres de atributo para que sitelo-ui pueda vivir dentro de un sitio que ya tenga su propio interruptor de tema, que es exactamente lo que hace esta documentación.
Manejarlo tú
El runtime exporta las mismas funciones que usa el botón, para un control a medida o un selector de tres posiciones claro / oscuro / sistema.
import { getTheme, setTheme, toggleTheme } from 'sitelo/ui/client'
getTheme() // 'light' | 'dark' — resuelto, no guardado
toggleTheme() // cambia
setTheme('dark') // fija
setTheme('system') // borra la anulación y vuelve a seguir al sistemaProps
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
label | string | 'Toggle dark mode' | Nombre accesible y tooltip. |
variant | 'solid' | 'soft' | 'outline' | 'ghost' | 'link' | 'ghost' | Variante del botón. |
color | 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'neutral' | De qué paleta bebe. |
themeScript() admite un nonce opcional, para un sitio con política de seguridad de contenidos.