UNPKG

react-use-system-theme

Version:

React Hook to get the system theme (OS theme: light or dark) based on prefers-colors-scheme. Subscribes to changes as well.

63 lines (53 loc) 1.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useSystemTheme; exports.colorSchemes = void 0; var _react = require("react"); var _useIsomorphicLayoutEffect = _interopRequireDefault(require("./use-isomorphic-layout-effect")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const colorSchemes = { light: '(prefers-color-scheme: light)', dark: '(prefers-color-scheme: dark)' }; exports.colorSchemes = colorSchemes; function onThemeChange(callback) { return event => { if (!event || !event.matches) { return; } callback(); }; } function useSystemTheme(initialTheme) { const [theme, setTheme] = (0, _react.useState)(initialTheme || null); (0, _react.useEffect)(() => { // SSR or matchMedia not supported if (typeof window === 'undefined' || !window.matchMedia) { return; } const lightMatch = window.matchMedia(colorSchemes.light); const onLightMatches = onThemeChange(() => setTheme('light')); lightMatch.addListener(onLightMatches); const darkMatch = window.matchMedia(colorSchemes.dark); const onDarkMatches = onThemeChange(() => setTheme('dark')); darkMatch.addListener(onDarkMatches); return () => { lightMatch.removeListener(onLightMatches); darkMatch.removeListener(onDarkMatches); }; }, []); (0, _useIsomorphicLayoutEffect.default)(() => { // SSR or matchMedia not supported if (typeof window === 'undefined' || !window.matchMedia) { return; } if (window.matchMedia(colorSchemes.dark).matches && theme !== 'dark') { setTheme('dark'); } else if (window.matchMedia(colorSchemes.light).matches && theme !== 'light') { setTheme('light'); } }, [theme]); return theme; }