SWCore / Componentes / Tema dia/noite

Tema dia/noite Componentes

Alterna claro/escuro, lembra a escolha e não pisca (flash) no carregamento.

O que é

O botão flutuante de troca de tema, mais o mecanismo por trás: salva a escolha e aplica ANTES do CSS renderizar, pra nunca aparecer um flash da cor errada.

Como funciona

Um script mínimo, inline, roda antes de qualquer CSS carregar e já crava o atributo sw-theme no <html> lendo o localStorage — por isso não pisca.

Exemplos

O botão — clique e veja esta página trocar Ao vivo
Clique: a documentação inteira troca de tema, e a escolha fica salva.
<button sw-day sw-btn="ghost" aria-label="Alternar tema">
  <i class="sw-daytg-ico swi-moon"></i>
</button>

<!-- se você NÃO puser nenhum botão, ele injeta um flutuante sozinho.
     Pra não injetar: <html sw-day-no-fab> -->
Imagem diferente em cada tema Ao vivo
Troque o tema no botão acima: esta imagem muda junto.
<img src="/logo-claro.svg"
     sw-day-img-light="/logo-claro.svg"
     sw-day-img-dark="/logo-escuro.svg" alt="">

<!-- serve pra logo, ilustração, print de tela… -->
Fundo, cor e fonte por tema Ao vivo
fundo por tema
cor por tema
<div sw-day-bg-light="#eef2ff" sw-day-bg-dark="#1e1b4b">…</div>
<div sw-day-color-light="#4338ca" sw-day-color-dark="#a5b4fc">…</div>

<!-- aceita token do framework também -->
<div sw-day-bg-dark="var(--sw-sur)">…</div>

<!-- existem ainda: sw-day-text-{tema} e sw-day-font-{tema} -->
Começar escuro, ou travar um tema Ao vivo

Esses dois vão no <html>, porque valem pra página inteira — por isso não têm demonstração aqui dentro.

sw-day-default define só o primeiro acesso: depois disso vale o que o visitante escolheu. sw-day-lock é diferente — trava mesmo, e o botão some.

<!-- primeira visita começa no escuro (depois vale a escolha do visitante) -->
<html sw-day-default="dark">

<!-- trava o tema: ninguém troca -->
<html sw-day-lock="dark">

<!-- não injetar o botão flutuante automático -->
<html sw-day-no-fab>
Por que não pisca — e como fazer no seu site Ao vivo

Se o tema fosse aplicado só depois do CSS carregar, o visitante veria um flash branco antes de ficar escuro. O truque é um script minúsculo, inline, antes de qualquer CSS: ele lê a escolha salva e já crava o sw-theme no <html>.

Esta página faz exatamente isso — é por isso que ela não pisca ao recarregar no tema escuro.

<head>
  <!-- ANTES de qualquer <link rel="stylesheet"> -->
  <script>
    try {
      var t = localStorage.getItem('sw-theme');
      if (t) document.documentElement.setAttribute('sw-theme', t);
    } catch (e) {}
  </script>

  <link rel="stylesheet" href="dist/swcore.min.css">
</head>

<script>
  SW.Day.set('dark');
  SW.Day.toggle();
  document.addEventListener('sw:theme:change', (e) => console.log(e.detail));
</script>

Atributos

sw-day
num botão: transforma ele no alternador de tema
sw-day-default
no <html>: com que tema a primeira visita começa — "light" ou "dark"
sw-day-lock
no <html>: trava um tema; o visitante não troca
sw-day-no-fab
no <html>: impede o botão flutuante automático
sw-day-img-{tema}
numa <img>: troca o src naquele tema
sw-day-bg-{tema}
troca o fundo do elemento naquele tema
sw-day-color-{tema}
troca a cor do elemento naquele tema
sw-day-text-{tema}
troca a cor do texto naquele tema
sw-day-font-{tema}
troca a fonte naquele tema

Variantes

{tema} = light \| dark
o sufixo dos atributos acima — ex.: sw-day-bg-dark
(nenhum botão na página)
ele injeta sozinho um botão flutuante no canto
sw-day-no-fab
desliga essa injeção automática
sw-theme no <html>
é onde o tema fica escrito — seu CSS reage a [sw-theme="dark"]

Eventos

sw:theme:change
o tema mudou

API (JavaScript)

SW.Day.set('light' \| 'dark')
troca o tema por código
SW.Day.toggle()
alterna entre os dois

Requisitos

Nenhuma.

Limitações — o que ele não faz

  • A escolha fica no localStorage daquele navegador — em outro aparelho, começa de novo pelo sw-day-default.
  • Um elemento declara um par por tipo (fundo, cor, fonte, imagem). Pra variações mais complexas, escreva CSS em cima de [sw-theme="dark"].