# All files / src/components ThemeProvider.tsx

0% Statements 0/36
0% Branches 0/19
0% Functions 0/6
0% Lines 0/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65

     'use client';

    import { useEffect } from 'react';
    import { STORAGE_KEYS, THEME } from '@/constants/app';

    function applyTheme(theme: string) {
      const root = document.documentElement;
      // Remove previous theme classes
      root.classList.remove('dark', 'theme-midnight', 'theme-darkblue');

      switch (theme) {
        case THEME.DARK:
          root.classList.add('dark');
          break;
        case THEME.MIDNIGHT:
          root.classList.add('dark');
          root.classList.add('theme-midnight');
          break;
        case THEME.DARK_BLUE:
          root.classList.add('dark');
          root.classList.add('theme-darkblue');
          break;
        case THEME.SYSTEM: {
          const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
          if (prefersDark) root.classList.add('dark');
          break;
        }
        case THEME.LIGHT:
        default:
          // Light: no extra class (variables from :root)
          break;
      }
    }

    export default function ThemeProvider() {
      useEffect(() => {
        const stored = (typeof window !== 'undefined' && localStorage.getItem(STORAGE_KEYS.THEME)) || THEME.SYSTEM;
        applyTheme(stored);
        // Respond to system changes when in SYSTEM mode
        const mq = window.matchMedia('(prefers-color-scheme: dark)');
        const listener = () => {
          const current = localStorage.getItem(STORAGE_KEYS.THEME) || THEME.SYSTEM;
          if (current === THEME.SYSTEM) applyTheme(current);
        };
        mq.addEventListener?.('change', listener);
        return () => mq.removeEventListener?.('change', listener);
      }, []);
      return null;
    }

    // Optional helper for runtime theme switching from anywhere:
    // window.setAppTheme('midnight' | 'dark_blue' | 'dark' | 'light' | 'system')
    declare global {
      interface Window { setAppTheme?: (theme: string) => void }
    }

    if (typeof window !== 'undefined') {
      window.setAppTheme = (theme: string) => {
        try {
          localStorage.setItem(STORAGE_KEYS.THEME, theme);
          applyTheme(theme);
        } catch (_) { /* ignore */ }
      };
    }