Alternador de tema

O sitelo-ui resolve o modo escuro sozinho a partir do prefers-color-scheme — um site que se contenta em seguir o sistema operativo não precisa de nada desta página. O alternador serve para deixar o leitor sobrepor-se a isso.

É um dos cinco componentes que precisam de script, porque a escolha vive no localStorage e só um script a consegue ler. O botão vai buscar esse script sozinho, ao primeiro toque.

Configuração

Duas coisas no head, e o botão onde lhe compete:

import { styles, themeScript, themeToggle } from 'sitelo/ui'

head(
  themeScript(), // aplica a escolha guardada antes do primeiro desenho
  styles(),
)

body(
  appBar({ brand: 'O meu site' },
    appBarSpacer(),
    appBarActions(themeToggle()),
  ),
)

Não há um terceiro ficheiro. O themeScript() é bloqueante e inline de propósito — tudo o que for adiado desenha primeiro, e é precisamente esse clarão escuro que ele existe para evitar — e a troca em si viaja no botão:

<button data-su-theme-toggle
        onclick="import('/su/theme.js').then(m=>m.toggle(this))">

Usa os dois em conjunto. O themeScript() é também o que marca o alternador com aria-pressed ao carregar: ainda nada foi premido, por isso o botão sozinho não pode saber que tema saiu.

O alternador

O ícone é CSS puro, lido diretamente do atributo de tema — por isso já está certo no primeiro desenho, antes de qualquer script correr. Mostra para onde um clique vai trocar.

stack({ direction: 'row', gap: 'md', align: 'center' },
  themeToggle(),
  themeToggle({ variant: 'soft' }),
  themeToggle({ variant: 'outline' }),
)

Estes botões funcionam — esta página carrega o runtime. Clicar num deles define data-su-theme no <html>, que é o atributo próprio do sitelo-ui, por isso só mudam os componentes sitelo-ui desta página. O resto deste site segue o seu próprio data-theme, definido pelo alternador da barra de topo. No teu site só existiria um deles.

Numa barra da aplicação

appBar({ brand: 'sitelo' },
  appBarNav(navLink({ href: '#docs', current: true }, 'Documentação')),
  appBarSpacer(),
  appBarActions(
    themeToggle(),
    button({ size: 'sm' }, 'Começar'),
  ),
)

Como o tema é resolvido

Por ordem: um data-theme ou data-su-theme explícito em qualquer antepassado ganha; falhando isso, decide o prefers-color-scheme. Os dois nomes de atributo são respeitados para o sitelo-ui poder viver dentro de um site que já tem o seu próprio interruptor de tema — que é exatamente o que esta documentação faz.

Conduzi-lo tu

O runtime exporta as mesmas funções que o botão usa, para um controlo à medida ou um seletor de três posições claro / escuro / sistema.

import { getTheme, setTheme, toggleTheme } from 'sitelo/ui/client'

getTheme()          // 'light' | 'dark' — resolvido, não guardado
toggleTheme()       // trocar
setTheme('dark')    // fixar
setTheme('system')  // limpar a preferência e voltar a seguir o SO

Props

PropTipoPredefiniçãoDescrição
labelstring'Toggle dark mode'Nome acessível e dica.
variant'solid' | 'soft' | 'outline' | 'ghost' | 'link''ghost'Variante do botão.
color'primary' | 'neutral' | 'success' | 'warning' | 'danger''neutral'De que paleta bebe.

O themeScript() aceita um nonce opcional, para um site com política de segurança de conteúdo.