From 7be806a81ec43f2b9ab9c5970df142a5cfd6fe6f Mon Sep 17 00:00:00 2001 From: Artur Oliveira Date: Tue, 16 Dec 2025 18:57:27 -0300 Subject: [PATCH] chore(theme): alinhar modo escuro ao SO - remove o provedor e o toggle manual de tema - aplica a classe dark conforme matchMedia ao inicializar o app - ajusta o toaster para acompanhar as cores do sistema --- frontend/src/main.tsx | 11 ++++++++++- frontend/src/theme.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 frontend/src/theme.ts diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 59d5805..121e9d9 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -2,12 +2,21 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import App from './App.tsx'; import { Toaster } from 'react-hot-toast'; +import { initSystemThemeWatcher } from './theme.ts'; + +initSystemThemeWatcher(); createRoot(document.getElementById('root')!).render( <> - + , ); diff --git a/frontend/src/theme.ts b/frontend/src/theme.ts new file mode 100644 index 0000000..524cfd2 --- /dev/null +++ b/frontend/src/theme.ts @@ -0,0 +1,34 @@ +const applyThemeToDocument = (isDark: boolean) => { + if (typeof document === "undefined") { + return; + } + const theme = isDark ? "dark" : "light"; + const root = document.documentElement; + const body = document.body; + + root.classList.toggle("dark", isDark); + root.setAttribute("data-theme", theme); + + if (body) { + body.classList.toggle("dark", isDark); + body.setAttribute("data-theme", theme); + body.style.colorScheme = isDark ? "dark" : "light"; + } +}; + +export const initSystemThemeWatcher = () => { + if (typeof window === "undefined" || typeof window.matchMedia === "undefined") { + return; + } + + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + const applyMatch = (matches: boolean) => applyThemeToDocument(matches); + const handleChange = (event: MediaQueryListEvent) => applyMatch(event.matches); + + applyMatch(mediaQuery.matches); + if (typeof mediaQuery.addEventListener === "function") { + mediaQuery.addEventListener("change", handleChange); + } else if (typeof mediaQuery.addListener === "function") { + mediaQuery.addListener(handleChange); + } +};