UNPKG

react-theme-system

Version:

A comprehensive React theme management system that enforces consistency, supports dark/light mode, and eliminates hardcoded styles

132 lines (131 loc) 4.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useThemeToggleWithSystem = exports.useThemeToggle = void 0; const react_1 = require("react"); const ThemeProvider_1 = require("../ThemeProvider"); /** * Headless hook for theme toggle functionality * Decouples theme logic from presentation, enabling custom UIs without fork-modifying * * @example * ```tsx * const { isDark, toggle, setTheme } = useThemeToggle(); * * return ( * <button onClick={toggle}> * {isDark ? '🌙' : '☀️'} * </button> * ); * ``` */ const useThemeToggle = () => { const { currentTheme, setTheme, isHydrated } = (0, ThemeProvider_1.useTheme)(); const isDark = currentTheme === 'dark'; const isLight = currentTheme === 'light'; const toggle = (0, react_1.useCallback)(() => { if (!isHydrated) return; setTheme(isDark ? 'light' : 'dark'); }, [isDark, setTheme, isHydrated]); const setLight = (0, react_1.useCallback)(() => { if (!isHydrated) return; setTheme('light'); }, [setTheme, isHydrated]); const setDark = (0, react_1.useCallback)(() => { if (!isHydrated) return; setTheme('dark'); }, [setTheme, isHydrated]); return { // State isDark, isLight, currentTheme, isHydrated, // Actions toggle, setLight, setDark, setTheme, // Utilities nextTheme: isDark ? 'light' : 'dark', icon: isDark ? '🌙' : '☀️', label: isDark ? 'Switch to light mode' : 'Switch to dark mode', ariaLabel: isDark ? 'Switch to light mode' : 'Switch to dark mode' }; }; exports.useThemeToggle = useThemeToggle; /** * Enhanced theme toggle hook with system theme detection * * @example * ```tsx * const { isDark, toggle, systemTheme, isSystemTheme } = useThemeToggleWithSystem(); * * return ( * <div> * <button onClick={toggle}> * {isDark ? '🌙' : '☀️'} * </button> * {systemTheme && <span>System: {systemTheme}</span>} * </div> * ); * ``` */ const useThemeToggleWithSystem = () => { const { currentTheme, setTheme, isHydrated, systemTheme } = (0, ThemeProvider_1.useTheme)(); const isDark = currentTheme === 'dark'; const isLight = currentTheme === 'light'; const isSystemTheme = currentTheme === systemTheme; const toggle = (0, react_1.useCallback)(() => { if (!isHydrated) return; setTheme(isDark ? 'light' : 'dark'); }, [isDark, setTheme, isHydrated]); const setSystem = (0, react_1.useCallback)(() => { if (!isHydrated || !systemTheme) return; setTheme(systemTheme); }, [systemTheme, setTheme, isHydrated]); const cycleTheme = (0, react_1.useCallback)(() => { if (!isHydrated) return; // Cycle: light -> dark -> system -> light if (isLight) { setTheme('dark'); } else if (isDark) { setTheme(systemTheme || 'light'); } else { setTheme('light'); } }, [isLight, isDark, systemTheme, setTheme, isHydrated]); return { // State isDark, isLight, currentTheme, isHydrated, systemTheme, isSystemTheme, // Actions toggle, setLight: () => setTheme('light'), setDark: () => setTheme('dark'), setSystem, setTheme, cycleTheme, // Utilities nextTheme: isDark ? 'light' : 'dark', icon: isDark ? '🌙' : '☀️', label: isDark ? 'Switch to light mode' : 'Switch to dark mode', ariaLabel: isDark ? 'Switch to light mode' : 'Switch to dark mode', // System theme utilities systemIcon: systemTheme === 'dark' ? '🌙' : '☀️', systemLabel: `Use system theme (${systemTheme})`, hasSystemTheme: !!systemTheme }; }; exports.useThemeToggleWithSystem = useThemeToggleWithSystem;