feat(acessibilidade): melhorar a gestão do tema escuro e otimizar a leitura do localStorage
All checks were successful
Dev Build & Deploy Portal / build-deploy (push) Successful in 2m29s

This commit is contained in:
Gabriel Bezerra 2026-05-20 21:46:30 -03:00
parent a034446cf1
commit 222b098a35
3 changed files with 33 additions and 9 deletions

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, watch, onMounted } from 'vue'
import { ref, watch, onMounted, onUnmounted } from 'vue'
const aberto = ref(false)
const nivelFonte = ref(0)
@ -18,16 +18,38 @@ function applyFonte(nivel) {
if (nivel === 2) document.documentElement.classList.add('a11y-font-xl')
}
let darkMediaQuery = null
let systemThemeChanging = false
function onSystemThemeChange(e) {
if (localStorage.getItem('a11y-escuro') === null) {
systemThemeChanging = true
modoEscuro.value = e.matches
systemThemeChanging = false
}
}
// Toda leitura de localStorage e DOM precisa estar dentro de onMounted
// caso contrário o componente quebra no SSR.
onMounted(() => {
nivelFonte.value = Number(localStorage.getItem('a11y-fonte') || 0)
altoContraste.value = localStorage.getItem('a11y-contraste') === '1'
modoEscuro.value = localStorage.getItem('a11y-escuro') === '1'
const storedDark = localStorage.getItem('a11y-escuro')
modoEscuro.value = storedDark !== null
? storedDark === '1'
: window.matchMedia('(prefers-color-scheme: dark)').matches
applyFonte(nivelFonte.value)
document.documentElement.classList.toggle('a11y-contrast', altoContraste.value)
document.documentElement.classList.toggle('app-dark', modoEscuro.value)
darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
darkMediaQuery.addEventListener('change', onSystemThemeChange)
})
onUnmounted(() => {
darkMediaQuery?.removeEventListener('change', onSystemThemeChange)
})
watch(nivelFonte, (val) => {
@ -45,7 +67,9 @@ watch(altoContraste, (val) => {
watch(modoEscuro, (val) => {
if (!import.meta.client) return
document.documentElement.classList.toggle('app-dark', val)
if (!systemThemeChanging) {
localStorage.setItem('a11y-escuro', val ? '1' : '0')
}
})
</script>

View File

@ -105,9 +105,9 @@ function reiniciar() {
:disabled="isAuthenticated"
@keyup.enter="consultar"
/>
<p v-if="isAuthenticated" class="mt-1.5 text-xs text-slate-500 dark:text-slate-400 flex items-center gap-1.5">
<i class="pi pi-info-circle text-xs text-primary" aria-hidden="true" />
Logado como <strong class="text-slate-700 dark:text-slate-200">{{ nomeUsuario }}</strong> documento bloqueado para segurança.
<p v-if="isAuthenticated" class="mt-1.5 text-xs text-slate-500 dark:text-slate-400 flex items-start gap-1.5">
<i class="pi pi-info-circle text-xs text-primary mt-0.5 shrink-0" aria-hidden="true" />
<span>Logado como <strong class="text-slate-700 dark:text-slate-200">{{ nomeUsuario }}</strong> documento bloqueado para segurança.</span>
</p>
</div>

View File

@ -164,9 +164,9 @@ function formatarMoeda(valor) {
size="large"
@keyup.enter="consultar"
/>
<p v-if="modoConsulta === 'documento' && isAuthenticated" class="mt-1.5 text-xs text-slate-500 dark:text-slate-400 flex items-center gap-1.5">
<i class="pi pi-info-circle text-xs text-primary" aria-hidden="true" />
Logado como <strong class="text-slate-700 dark:text-slate-200">{{ nomeUsuario }}</strong> documento bloqueado para segurança.
<p v-if="modoConsulta === 'documento' && isAuthenticated" class="mt-1.5 text-xs text-slate-500 dark:text-slate-400 flex items-start gap-1.5">
<i class="pi pi-info-circle text-xs text-primary mt-0.5 shrink-0" aria-hidden="true" />
<span>Logado como <strong class="text-slate-700 dark:text-slate-200">{{ nomeUsuario }}</strong> documento bloqueado para segurança.</span>
</p>
</div>