flowbite-react
Version:
Official React components built for Flowbite and Tailwind CSS
77 lines (74 loc) • 2.45 kB
JavaScript
'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