Skip to content

BaseThemeSwitch ​

A escolha do tema da tela: claro, escuro ou o mesmo do sistema operacional. A escolha vale para a página inteira e fica guardada no navegador. "Seguir sistema" apaga a escolha guardada, e a tela volta a acompanhar o computador ou o celular, inclusive quando ele troca de tema com a página aberta.

Nesta documentação, o seletor troca o tema do site inteiro. A chave de tema no alto da página, do próprio site, guarda a mesma escolha: mudar uma muda a outra.

Uso ​

  • Ponha um BaseThemeSwitch no menu da pessoa, no slot user-menu do BaseAppShell, antes do "Sair". É uma preferência da pessoa e vale em todas as telas.
  • A tela de login fica sem seletor. Ela tem uma ação só, entrar com a conta do Tribunal, e já abre no tema guardado ou no do sistema, porque o initTheme() roda antes de qualquer tela. Depois de entrar, a pessoa troca o tema no menu dela.
  • Chame initTheme() no main.ts, antes de montar o app. É ela que aplica a escolha guardada antes da primeira pintura e acompanha o sistema operacional quando não há escolha. O seletor só mostra e muda a escolha.
  • Um seletor por tela basta. Se houver mais de um, todos mostram a mesma escolha.
  • O seletor não cria um tema de alto contraste. Quem usa o alto contraste do Windows continua com as cores do sistema operacional, que valem por cima de qualquer tema.
  • Para trocar o tema sem o seletor, use setTheme('light'), setTheme('dark') ou setTheme('system'), da página Tokens e temas.

Anatomia ​

  1. Nome: o texto de label, "Tema" por padrão, acima das opções.
  2. Opções: "Claro", "Escuro" e "Seguir sistema", num BaseSegmented. A escolhida fica elevada e em negrito.

Tamanhos ​

O trilho das três opções tem 204 px de largura no sm, 240 px no md e 276 px no lg. Num espaço mais estreito, as opções rolam para o lado, como em qualquer BaseSegmented.

No menu da pessoa, use sm: as opções ficam mais baixas que os itens do menu e não parecem ações. Com 26 px de altura e pelo menos 44 px de largura, elas passam do alvo mínimo de 24 × 24 px do WCAG 2.2 (critério 2.5.8, nível AA). Os links da faixa do menu no celular têm 44 × 44 px porque a pessoa passa por eles a cada troca de tela; o tema se escolhe uma vez e fica guardado.

No menu da pessoa ​


Escolher um tema não fecha o menu: a pessoa vê o resultado e pode trocar de novo. "Sair" e os outros itens continuam fechando o menu.

Faça e não faça ​

FaçaNão faça
Pôr o seletor no menu da pessoa, antes do "Sair".Pôr o seletor no meio da tela ou em cada página.
Deixar "Seguir sistema" como está quando a pessoa nunca escolheu.Gravar o tema do sistema como se fosse uma escolha.
Chamar initTheme() no main.ts.Ler ou gravar o tema no localStorage direto.
Contar com o alto contraste do Windows para quem precisa dele.Apresentar o tema escuro como alto contraste.

Estilo ​

PropriedadeToken
Nome--tj-text-sm, --tj-leading-sm, --tj-weight-medium e --tj-text-secondary
Espaço entre o nome e as opções--tj-space-2
Opçõesas do BaseSegmented
No menu da pessoaespaço interno de --tj-space-2 e --tj-space-3, alinhado ao texto dos itens; o painel se alarga para caber as três opções

Código ​

ts
// main.ts
import { initTheme } from '@lab-inovacao-tjes/design-system'

initTheme()
vue
<script setup lang="ts">
import { BaseAppShell, BaseThemeSwitch, BaseUserMenuItem } from '@lab-inovacao-tjes/design-system'
</script>

<template>
  <BaseAppShell product="Gestão de Obras" user-name="Marta Coelho" user-role="Fiscal de contrato">
    <template #user-menu>
      <BaseThemeSwitch size="sm" />
      <hr>
      <BaseUserMenuItem icon="box-arrow-right" @click="signOut">Sair</BaseUserMenuItem>
    </template>
  </BaseAppShell>
</template>

Propriedades ​

Propriedade Tipo Padrão Descrição
labelstring'Tema'Nome mostrado acima das opções; também é o nome do grupo para o leitor de tela
size'sm' | 'md' | 'lg''md'Altura das opções

Não há eventos nem slots. A escolha chega ao resto do app pelo evento ds-themechange do document (THEME_CHANGE_EVENT), com o tema aplicado e a escolha.

Acessibilidade ​

  • Segue o padrão Radio Group do WAI-ARIA APG, pelo BaseSegmented: um role="radiogroup" com o nome de label e três role="radio" com aria-checked.
  • O nome visível fica escondido do leitor de tela, porque o grupo já tem o mesmo texto como nome. Assim "Tema" não é lido duas vezes.
  • A opção escolhida não depende só da cor: fica elevada, com contorno e em negrito.
  • No alto contraste do Windows (forced-colors), a escolhida ganha borda Highlight e o foco, contorno CanvasText. Isso foi conferido só na emulação do alto contraste do Chromium. Falta o teste num Windows com o alto contraste ligado.
  • O nível seguido é o WCAG 2.2, nível AA. O eMAG 3.1 (consultado em 05/11/2026), na seção 4, dos elementos padronizados do Governo Federal, pede uma opção de alto contraste com pelo menos 7:1 entre o fundo e o primeiro plano (item 4.2). Falta confirmar com a STIC se isso vale para os sistemas do TJES.
  • Teclado:
TeclaO que faz
TabEntra no grupo pela opção escolhida e sai dele na próxima vez
→ ↓Vai à próxima opção e troca o tema; da última, volta à primeira
← ↑Vai à opção anterior e troca o tema; da primeira, vai à última
Home EndVai à primeira ou à última opção e troca o tema
Espaço EnterEscolhe a opção em foco
  • Testes no navegador, em 05/11/2026, na página gerada desta documentação, no Chromium e no WebKit como iPhone e iPad (e2e/theme-switch.spec.ts): o teclado troca o tema; com "Seguir sistema", a página acompanha o sistema operacional quando ele troca de claro para escuro com a página aberta; com "Escuro", ela não acompanha quando o sistema troca para escuro e volta para claro; a escolha continua depois de recarregar a página. Só no Chromium, porque a chave de tema do site fica no alto da página a partir de 1280 px: a chave guarda a escolha e o seletor passa a mostrá-la.
  • Os testes em jsdom passam o axe com cada opção escolhida e dentro do menu da pessoa. O axe roda sem layout, então o contraste das cores é medido no tests/contrast.test.ts, nos dois temas, pelos pares do BaseSegmented.