UNPKG

@zendeskgarden/react-theming

Version:

Theming utilities and components within the Garden Design System

76 lines (73 loc) 2.35 kB
/** * Copyright Zendesk, Inc. * * Use of this source code is governed under the Apache License, Version 2.0 * found at http://www.apache.org/licenses/LICENSE-2.0. */ import React, { createContext, useMemo, useEffect, useCallback, useState } from 'react'; import PropTypes from 'prop-types'; const mediaQuery = typeof window === 'undefined' ? undefined : window.matchMedia('(prefers-color-scheme: dark)'); const useColorScheme = (initialState, colorSchemeKey) => { const localStorage = typeof window === 'undefined' ? undefined : window.localStorage; const getState = useCallback(_state => { const isSystem = _state === 'system' || _state === undefined || _state === null; let colorScheme; if (isSystem) { colorScheme = mediaQuery?.matches ? 'dark' : 'light'; } else { colorScheme = _state; } return { isSystem, colorScheme }; }, []); const [state, setState] = useState(getState(localStorage?.getItem(colorSchemeKey) || initialState)); return { isSystem: state.isSystem, colorScheme: state.colorScheme, setColorScheme: colorScheme => { setState(getState(colorScheme)); localStorage?.setItem(colorSchemeKey, colorScheme); } }; }; const ColorSchemeContext = createContext(undefined); const ColorSchemeProvider = _ref => { let { children, colorSchemeKey = 'color-scheme', initialColorScheme = 'system' } = _ref; const { isSystem, colorScheme, setColorScheme } = useColorScheme(initialColorScheme, colorSchemeKey); const contextValue = useMemo(() => ({ colorScheme, isSystem, setColorScheme }), [isSystem, colorScheme, setColorScheme]); useEffect(() => { const eventListener = () => { setColorScheme('system'); }; if (isSystem) { mediaQuery?.addEventListener('change', eventListener); } else { mediaQuery?.removeEventListener('change', eventListener); } return () => { mediaQuery?.removeEventListener('change', eventListener); }; }, [isSystem, setColorScheme]); return React.createElement(ColorSchemeContext.Provider, { value: contextValue }, children); }; ColorSchemeProvider.propTypes = { colorSchemeKey: PropTypes.string, initialColorScheme: PropTypes.oneOf(['light', 'dark', 'system']) }; export { ColorSchemeContext, ColorSchemeProvider };