0001 — Borda e placeholder dos campos de formulário fora dos tokens¶
| Status | CORRIGIDO |
| Branch | fix/0001-borda-placeholder-campos-formulario |
| Aberto em | 2026-07-29 |
| Severidade | MÉDIA |
| Apps afetados | web (api · e2e sem impacto) |
Status:
RASCUNHO→DIAGNOSTICADO→EM CORREÇÃO→CORRIGIDO
1. Sintoma¶
Nos formulários de cadastro (imobiliárias, imóveis, inquilinos, etc.), no tema claro, os campos (TextField MUI outlined, size="small") têm:
- Borda genérica e fraca, que não é o cinza da marca.
- Placeholder apagado, com aparência de desabilitado / pouca legibilidade.
O conjunto destoa dos tokens de design e passa impressão de acabamento pobre.
2. Reprodução¶
- Abrir qualquer formulário no tema claro — ex.:
/app/renters/create,/app/properties/create,/app/agencies/create. -
Observar a borda dos campos em repouso e o texto de placeholder.
-
Ambiente: web, tema claro (dev-remote ou local). Qualquer papel com acesso a cadastro.
- Pré-condições: nenhuma — vale para todo
TextFieldoutlined.
3. Esperado × Atual¶
- Esperado: borda na cor
border.subtledos tokens (#E2E8F0no claro), com hover/foco na cor da marca (primary); placeholder legível, derivado detext.secondary. - Atual: borda no default do MUI (
rgba(0,0,0,0.23)) e placeholder no default do MUI (opacity ~0.42sobretext.primary) — nenhum dos dois segue os tokens.
4. Causa raiz¶
apps/web/src/contexts/color-mode/index.tsx — o objeto sharedComponents (compartilhado pelos temas claro e escuro) só customiza MuiButton. Não há override de MuiOutlinedInput, MuiInputBase nem MuiInputLabel, então borda e placeholder caem inteiramente no default do MUI, que não conhece os tokens da marca.
Não é regressão de uma mudança específica: nunca houve tema de input — o gap existe desde a criação do tema. Confirmado por leitura: sharedComponents (linhas ~42–57) não referencia input algum; o palette também não define divider, então até os FormPanel (que usam borderColor: "divider") herdam o divider default.
5. Correção¶
apps/api¶
Sem impacto — é estilo de UI.
apps/web¶
- Onde:
src/contexts/color-mode/index.tsx, nosharedComponents(ou, se for preciso divergir por modo, nocomponentsde cada tema). - O quê: adicionar override de input alinhada aos tokens —
MuiOutlinedInput→.MuiOutlinedInput-notchedOutlineborderColor=border.subtle(#E2E8F0no claro);:hovernum tom mais escuro;.Mui-focusedna corprimary.input::placeholder→colorderivado detext.secondary,opacity: 1(o default do MUI aplica opacity baixa que "apaga" o texto).- avaliar
MuiInputLabelpara consistência do label. - Escopo: foco no tema claro (conforme triagem). Se a override no
sharedComponentsusar callback({ theme }) =>com cores derivadas do palette, ela naturalmente serve os dois modos — nesse caso, conferir que o escuro não regride (ver seção 6). Tratar o escuro é fora de escopo deste fix. data-testid: nenhum novo (mudança puramente de estilo).
apps/e2e¶
Sem teste de regressão automatizado: o Playwright não afere cor/borda de forma robusta e barata. Validação por screenshot manual de 2–3 formulários no tema claro (ver Plano). Registrar o antes/depois no fechamento.
6. Risco / impacto colateral¶
Baixo, mas global: uma override de MuiOutlinedInput/MuiInputBase afeta todos os inputs do app — login, onboarding, filtros de lista, campos do admin, e os campos compostos (DateField, CepField, autocompletes). Ao aplicar:
- Conferir que campos com
sxpróprio não colidem com a override. - Conferir login/onboarding e os filtros de lista, não só os cadastros.
- Se a override for theme-aware (serve os dois modos), garantir que o tema escuro não fica pior que hoje.
Sem qualquer impacto em regra de negócio, cálculo (pricing/billing/sinistro) ou dados.
7. Critérios de aceite¶
- [x] CA1. Em
/app/renters/createno tema claro, a borda dos campos usa o cinza do design system e o placeholder está legível. Estilo computado em repouso:rgb(148,163,184)=#94A3B8(verassets/0001-borda-placeholder-campos-formulario/final.png). - [x] CA2. O foco de um campo mostra a cor da marca (
primary): estilo computadorgb(0,85,119)=#005577, borda 2px. - [x] CA3. Login e cadastros renderizam sem regressão (claro em
assets/0001-borda-placeholder-campos-formulario/final.png, escuro emassets/0001-borda-placeholder-campos-formulario/dark-login.png); a override é aditiva e uniforme paraMuiOutlinedInput.
8. Plano¶
- [x] Reproduzir:
assets/0001-borda-placeholder-campos-formulario/before.png(borda lavada / default do MUI no tema claro) - [x] Corrigir no tema (
apps/web,color-mode/index.tsx) —MuiOutlinedInput+input/textarea::placeholder - [x] Validar no browser: cadastro no claro (
assets/0001-borda-placeholder-campos-formulario/final.png) + login no escuro (assets/0001-borda-placeholder-campos-formulario/dark-login.png) + estilo computado - [x] Build de produção do web (roda
tsc) sem erro; sem apontamento novo - [x] Screenshots anexados ao registro (não há regressão automatizada de cor)
9. Decisões em aberto¶
Nenhuma — triagem resolvida (borda + placeholder, tema claro, alinhar aos tokens).
- ~~(nota) Tema escuro fora de escopo~~ → incluído após feedback: no mobile PWA o login/signup "não alterou" porque o app estava no tema escuro (o claro já tinha o fix). O escuro passou a ter o mesmo tratamento (ver Registro).
10. Registro¶
O que era: nenhuma override de input no tema (sharedComponents só cobria MuiButton) → borda e placeholder no default do MUI, fora da paleta.
O que virou (apps/web/src/contexts/color-mode/index.tsx, components do tema claro): override de MuiOutlinedInput —
- borda em repouso
#94A3B8(slate-400), hover#64748B(slate-500) - foco em
primary(#005577), 2px input/textarea::placeholderem#5f6878(text.secondary),opacity: 1
Desvio do plano + iteração: o plano previa border.subtle (#E2E8F0), que é o tom de divisor e reproduziria a borda lavada. A 1ª tentativa usou #CBD5E1 (slate-300), mas o usuário achou ainda fraca demais; comparei 4 intensidades (slate-350→600) e ele escolheu slate-400 #94A3B8 no repouso, com hover #64748B (slate-500). Família slate do design system, agora com contraste claro.
Escopo: só o tema claro, conforme triagem. O escuro segue no default (fix próprio se incomodar).
Deploy: container web do dev-remote rebuildado e no ar (https://dev.garantora.com.br/app).
Evidências (nesta pasta): assets/0001-borda-placeholder-campos-formulario/before.png, after.png, after-focus.png, after-login.png. Estilo computado (claro): repouso rgb(203,213,225), foco rgb(0,85,119).
Adendo — tema escuro (feedback: mobile PWA)¶
O usuário reportou que no mobile PWA o login/signup não alterou. Investigação:
- O bundle no ar já continha o fix (login/register usam
TextFieldoutlined) — não era deploy. - No tema escuro a borda seguia no default do MUI (
rgba(255,255,255,0.23)), porque a correção inicial foi só no claro. Celulares costumam estar em dark → daí o "não alterou".
Correção: adicionada override equivalente no garantoraDarkTheme (color-mode/index.tsx): borda repouso #3a4657, hover #4b5a70, foco #4da6cc (primary do dark) 2px, placeholder rgba(232,234,240,0.7) opacity 1. Rebuild + redeploy do web; borda do login no escuro agora mede rgb(58,70,87) = #3a4657 (assets/0001-borda-placeholder-campos-formulario/dark-login.png).
Ressalva de PWA (não é bug de código): o PWA usa registerType: "autoUpdate" (vite-plugin-pwa) com precache do bundle. Um app já instalado serve o bundle cacheado até o service worker atualizar — então, no aparelho, é preciso fechar e reabrir o PWA (uma vez para baixar o novo SW, e ele aplica no load seguinte). Não há mudança de código para isso; é o comportamento esperado do cache.
Adendo 2 — labels claros na card de auth (dark)¶
Após o SW atualizar, o usuário reportou que no mobile os labels dos campos de login/signup continuavam claros. Causa: login/index.tsx e register/index.tsx hardcodam a card branca (#ffffff), mas com o app em dark os TextField usavam a cor de texto do tema escuro (clara) → label claro sobre branco, ilegível.
Correção: login e register agora renderizam sempre no tema claro, envolvendo o conteúdo num <ThemeProvider theme={garantoraLightTheme}> (a card sempre foi branca por design). Label do e-mail no dark passou de claro para rgb(95,104,120) = #5f6878, legível (assets/0001-borda-placeholder-campos-formulario/auth-dark.png).
Resolvido (mesma armadilha): verify-email e accept-invite tinham a mesma card branca e o mesmo bug em dark — receberam o mesmo wrap em garantoraLightTheme. Confirmado em assets/0001-borda-placeholder-campos-formulario/verify-dark.png (card branca, heading/label escuros e legíveis, foco na marca) com o app em dark. onboarding é multi-step, estrutura diferente — não apresentou o problema.