// Copyright (c) 2025-2026, RTE (https://www.rte-france.com) // This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. // If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, // you can obtain one at http://mozilla.org/MPL/2.0/. // SPDX-License-Identifier: MPL-2.0 import { useCallback, useEffect, useState } from 'react'; import { interactionLogger } from '../utils/interactionLogger'; export type Theme = 'light' | 'dark'; const STORAGE_KEY = 'cs4g-theme'; // Read the persisted choice, falling back to the OS preference. Kept // pure (no DOM writes) so the same logic can run from the pre-mount // inline script in index.html and from React without diverging. export function resolveInitialTheme(): Theme { try { const stored = localStorage.getItem(STORAGE_KEY); if (stored === 'light' || stored === 'dark') return stored; } catch { // localStorage unavailable (private mode, SSR-like envs) — fall through. } if (typeof window !== 'undefined' && window.matchMedia) { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } return 'light'; } function applyThemeToDocument(theme: Theme): void { if (typeof document === 'undefined') return; document.documentElement.setAttribute('data-theme', theme); document.documentElement.style.colorScheme = theme; } export interface ThemeState { theme: Theme; toggleTheme: () => void; setTheme: (t: Theme) => void; } export function useTheme(): ThemeState { const [theme, setThemeState] = useState(() => resolveInitialTheme()); useEffect(() => { applyThemeToDocument(theme); try { localStorage.setItem(STORAGE_KEY, theme); } catch { // ignore — same fallback as resolveInitialTheme. } }, [theme]); const setTheme = useCallback((t: Theme) => setThemeState(t), []); const toggleTheme = useCallback(() => { setThemeState(prev => { const next: Theme = prev === 'dark' ? 'light' : 'dark'; interactionLogger.record('theme_toggled', { theme: next }); return next; }); }, []); return { theme, toggleTheme, setTheme }; }