UNPKG

flowbite-react

Version:

Official React components built for Flowbite and Tailwind CSS

77 lines (74 loc) 2.45 kB
'use client'; import { useState, useEffect } from 'react'; import { isClient } from '../helpers/is-client.mjs'; import { useWatchLocalStorageValue } from './use-watch-localstorage-value.mjs'; import { getThemeMode } from '../theme-store/index.mjs'; const DEFAULT_MODE = "light"; const LS_THEME_MODE = "flowbite-theme-mode"; const SYNC_THEME_MODE = "flowbite-theme-mode-sync"; const useThemeMode = () => { const [mode, setMode] = useState(getInitialMode(getThemeMode())); useEffect(() => { setModeInLS(mode); setModeInDOM(mode); }, []); useWatchLocalStorageValue({ key: LS_THEME_MODE, onChange(newValue) { if (newValue) return handleSetMode(newValue); } }); useSyncMode((mode2) => setMode(mode2)); const handleSetMode = (mode2) => { setMode(mode2); setModeInLS(mode2); setModeInDOM(mode2); document.dispatchEvent(new CustomEvent(SYNC_THEME_MODE, { detail: mode2 })); }; const toggleMode = () => { let newMode = mode; if (newMode === "auto") newMode = computeModeValue(newMode); newMode = newMode === "dark" ? "light" : "dark"; handleSetMode(newMode); }; const clearMode = () => { const newMode = getThemeMode() ?? DEFAULT_MODE; handleSetMode(newMode); }; return { mode, computedMode: computeModeValue(mode), setMode: handleSetMode, toggleMode, clearMode }; }; const useSyncMode = (onChange) => { useEffect(() => { function handleSync(e) { const mode = e.detail; onChange(mode); } document.addEventListener(SYNC_THEME_MODE, handleSync); return () => document.removeEventListener(SYNC_THEME_MODE, handleSync); }, []); }; const setModeInLS = (mode) => localStorage.setItem(LS_THEME_MODE, mode); const setModeInDOM = (mode) => { const computedMode = computeModeValue(mode); if (computedMode === "dark") { document.documentElement.classList.add("dark"); } else { document.documentElement.classList.remove("dark"); } }; const getInitialMode = (defaultMode) => { if (!isClient()) return DEFAULT_MODE; const LSMode = localStorage.getItem(LS_THEME_MODE); return LSMode ?? defaultMode ?? DEFAULT_MODE; }; const computeModeValue = (mode) => { return mode === "auto" ? prefersColorScheme() : mode; }; const prefersColorScheme = () => { return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light"; }; export { useThemeMode }; //# sourceMappingURL=use-theme-mode.mjs.map