Skip to content

fix(pwa): barra de status segue o tema e reveal de troca mais fluido#67

Merged
johnlaff merged 2 commits into
mainfrom
fix/pwa-status-bar-theme-e-reveal
Jul 22, 2026
Merged

fix(pwa): barra de status segue o tema e reveal de troca mais fluido#67
johnlaff merged 2 commits into
mainfrom
fix/pwa-status-bar-theme-e-reveal

Conversation

@johnlaff

Copy link
Copy Markdown
Owner

O que e por quê

No app instalado (PWA), a barra de status do sistema ficava verde — a cor de destaque — em vez de acompanhar o tema claro/escuro. E a animação de troca de tema (circular reveal) parecia lenta e hesitante no celular.

Barra de status

A cor da barra de status de um PWA vem do theme_color do manifest (na abertura) e do <meta name="theme-color"> (em runtime). Ambos apontavam para o accent.

  • O <meta name="theme-color"> passa a refletir o fundo do tema resolvido (claro/escuro, já tingido pelo accent/preset). Fonte única em theme-color.ts, sincronizada por ThemeColorSync (observa tema, accent, preset e o tinge do documentElement).
  • O fundo é lido do valor renderizado e normalizado de oklch para #rrggbb via canvas 2D — o <meta> não aceita oklch de forma confiável, e o Chromium serializa getComputedStyle em oklch.
  • manifest.json abre com theme_color/background_color no fundo escuro (o app abre escuro), não no accent. Ícones e link do manifest continuam seguindo o accent.
  • browser-accent.ts deixa de ser dono do theme-color (segue dono só dos ícones e do link do manifest).

Circular reveal

O reveal partia do raio 0 com ease-in-out — que quase não cresce nos primeiros quadros, passando sensação de lentidão. Passa a emphasized decelerate (ease-out, cubic-bezier(0.05, 0.7, 0.1, 1)) e 320 ms: abre rápido e assenta suave. Mantém a decisão de produto de não respeitar prefers-reduced-motion.

Como verificar

  • e2e/theme-color.spec.ts: com accent rosa saturado, a barra fica escura no tema escuro e clara no claro — nunca o accent.
  • Unit: theme-color.test.ts (conversão oklch→hex e sincronização) e manifest.json/route.test.ts.
  • No device: instale/atualize o PWA e alterne o tema — a barra do sistema acompanha o fundo e o reveal fica mais rápido.

Gates locais verdes: lint, tsc, 310 testes unit, react-doctor (changed) sem issues, e2e do theme-color e next build.

johnlaff added 2 commits July 22, 2026 14:24
No PWA a barra de status ficava verde (cor de destaque) em vez de acompanhar
o tema. O <meta name="theme-color"> e o theme_color do manifest apontavam para
o accent; agora o meta reflete, em runtime, o fundo do tema resolvido (claro/
escuro, já tingido pelo accent/preset) e o manifest abre na cor do fundo escuro.
A cor de destaque continua identificando ícones e manifest.

O circular reveal parecia lento e hesitante: usava ease-in-out, que quase não
cresce nos primeiros quadros. Passa a emphasized decelerate (ease-out) e 320ms,
que abre rápido e assenta suave.

- theme-color.ts: fonte única do <meta theme-color>; lê o fundo renderizado
  (normaliza oklch via canvas 2D) e mantém sincronizado via ThemeColorSync
  (observa tema, accent, preset e tinge do documentElement).
- browser-accent.ts deixa de tocar no theme-color (segue dono só de ícones e
  do link do manifest).
Ajustes após validar as decisões contra o padrão de 2026 (as escolhas centrais
— meta única em runtime, ler o fundo do DOM, canvas para oklch, View Transitions
com ease-out — já estavam alinhadas):

- ThemeColorSync passa a usar useSyncExternalStore, o hook próprio para ler uma
  fonte mutável externa (o fundo do documentElement), com o MutationObserver como
  subscribe e snapshot cacheado. Tearing-safe sob concurrent rendering; o guia do
  React desaconselha o padrão anterior (useEffect + observer disparando o efeito).
- theme-color.ts separa writeThemeColorMeta de readResolvedBackgroundColor.
- Documenta o alcance por plataforma: em runtime a meta só é lida pelo Chromium;
  a partir do Safari/iOS 26 o WebKit deriva a cor do fundo do <body> no primeiro
  paint (carimbo de frescor), então "não muda no iPhone" não é bug.
- Corrige comentários que afirmavam "o app abre escuro por padrão": com
  defaultTheme="system", um usuário com SO claro abre claro. A cor fixa do
  manifest é âncora de marca para a splash, com o flash inicial como limitação de
  plataforma conhecida.
- e2e força prefers-color-scheme divergente do tema (emulateMedia), provando que
  o runtime vence a media query do SO — o motivo de não usar meta media estática.
@johnlaff
johnlaff merged commit fd7869d into main Jul 22, 2026
1 check passed
@johnlaff
johnlaff deleted the fix/pwa-status-bar-theme-e-reveal branch July 22, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant