UNPKG

@ucam/design-system

Version:
87 lines (84 loc) 15.7 kB
import { __rest } from 'tslib'; import React, { useState, useCallback, useMemo } from 'react'; import { useMediaQuery, ScopedCssBaseline, CssBaseline, ThemeProvider as ThemeProvider$1 } from '@material-ui/core'; import { light, dark } from '../themes/themes.js'; import { ThemeUpdateContext } from '../useTheme/useTheme.js'; import { ThemeRegisterContext } from '../useThemeRegister/useThemeRegister.js'; import useLocalStorage from '../../useLocalStorage/useLocalStorage.js'; import HydrationChecker from '../../HydrationChecker/HydrationChecker.js'; import PropTypes from 'prop-types'; /** * A component that provides the app with theming support */ const ThemeProvider = React.forwardRef(function ThemeProvider(props, ref) { const { children, themes = { Light: light, Dark: dark }, defaultThemeName = 'Light', darkThemeName = 'Dark', scope = 'global', disableLocalStorage: propDisableLocalStorage } = props, other = __rest(props, ["children", "themes", "defaultThemeName", "darkThemeName", "scope", "disableLocalStorage"]); // Note: false during rehydration run, regardless of browser setting... // TODO: if we switch to the useHydrated hook and use the standard browser media queries we can possibly avoid extra renders here const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); // Cannot update the disableLocalStorage value otherwise different hooks would be called on the next line // React requires that the same hooks be called in the same order const [localStorageEnabled] = useState(!propDisableLocalStorage); const [chosenTheme, setChosenTheme] = (localStorageEnabled ? () => useLocalStorage('theme') : () => useState(defaultThemeName))(); const [registeredThemes, setRegisteredThemes] = useState(new Map(Object.entries(themes))); let themeName; let theme; if (chosenTheme !== undefined && registeredThemes.has(chosenTheme)) { themeName = chosenTheme; theme = registeredThemes.get(themeName); } else { themeName = prefersDarkMode ? darkThemeName : defaultThemeName; theme = registeredThemes.get(themeName) || light; } const setTheme = useCallback((themeName) => { console.assert(themeName === undefined || registeredThemes.has(themeName), `Unrecognised theme: ${themeName}`); setChosenTheme(themeName); }, [setChosenTheme, registeredThemes]); const selectedTheme = useMemo(() => ({ requestedThemeName: chosenTheme, renderedThemeName: themeName, theme, setTheme }), [chosenTheme, themeName, setTheme]); const setThemes = useCallback((themes) => { setRegisteredThemes(new Map(Object.entries(themes))); }, [setRegisteredThemes]); const themeRegister = useMemo(() => [registeredThemes, setThemes], [registeredThemes, setThemes]); const cssBaselineWrapper = (() => { switch (scope) { case 'global': return React.createElement(CssBaseline, Object.assign({}, other), children); case 'local': return (React.createElement(ScopedCssBaseline, Object.assign({}, other, { ref: ref }), children)); default: return React.createElement(React.Fragment, null, children); } })(); return (React.createElement(ThemeRegisterContext.Provider, { value: themeRegister }, React.createElement(ThemeUpdateContext.Provider, { value: selectedTheme }, React.createElement(ThemeProvider$1, { theme: theme }, cssBaselineWrapper)))); }); ThemeProvider.propTypes = { children: PropTypes.node, themes: PropTypes.objectOf(PropTypes.object.isRequired), defaultThemeName: PropTypes.string, darkThemeName: PropTypes.string, disableLocalStorage: PropTypes.bool, scope: PropTypes.oneOf(['global', 'local', false]) }; /** * A component that provides the app with theming support. * Also providing a `<HydrationChecker/>`. */ const ThemeProviderWithHydrationChecker = React.forwardRef((props, ref) => { return (React.createElement(HydrationChecker, null, React.createElement(ThemeProvider, Object.assign({}, props, { ref: ref })))); }); ThemeProviderWithHydrationChecker.displayName = 'ThemeProvider'; export { ThemeProviderWithHydrationChecker as default }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGhlbWVQcm92aWRlci5qcyIsInNvdXJjZXMiOlsiL0B1Y2FtL2Rlc2lnbi1zeXN0ZW0vc3JjL3RoZW1lL1RoZW1lUHJvdmlkZXIvVGhlbWVQcm92aWRlci50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHVzZUNhbGxiYWNrLCB1c2VNZW1vLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7XG4gIEludGVybmFsU3RhbmRhcmRQcm9wcyBhcyBTdGFuZGFyZFByb3BzLFxuICBDc3NCYXNlbGluZSxcbiAgU2NvcGVkQ3NzQmFzZWxpbmUsXG4gIHVzZU1lZGlhUXVlcnksXG4gIFRoZW1lLFxuICBUaGVtZVByb3ZpZGVyIGFzIE11aVRoZW1lUHJvdmlkZXJcbn0gZnJvbSAnQG1hdGVyaWFsLXVpL2NvcmUnO1xuaW1wb3J0IHsgZGFyaywgbGlnaHQgfSBmcm9tICcuLi90aGVtZXMnO1xuaW1wb3J0IHsgVGhlbWVVcGRhdGUsIFRoZW1lVXBkYXRlQ29udGV4dCB9IGZyb20gJy4uL3VzZVRoZW1lL3VzZVRoZW1lJztcbmltcG9ydCB7IFRoZW1lUmVnaXN0ZXJDb250ZXh0IH0gZnJvbSAnLi4vdXNlVGhlbWVSZWdpc3Rlci91c2VUaGVtZVJlZ2lzdGVyJztcbmltcG9ydCB1c2VMb2NhbFN0b3JhZ2UgZnJvbSAnLi4vLi4vdXNlTG9jYWxTdG9yYWdlJztcbmltcG9ydCBIeWRyYXRpb25DaGVja2VyIGZyb20gJy4uLy4uL0h5ZHJhdGlvbkNoZWNrZXInO1xuaW1wb3J0IFByb3BUeXBlcywgeyBSZXF1aXJlYWJsZSB9IGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRoZW1lUHJvdmlkZXJQcm9wcyBleHRlbmRzIFN0YW5kYXJkUHJvcHM8UmVhY3QuSFRNTEF0dHJpYnV0ZXM8SFRNTERpdkVsZW1lbnQ+PiB7XG4gIC8qKlxuICAgKiBBIGNvbGxlY3Rpb24gb2YgdGhlbWVzIGFuZCB0aGVpciBuYW1lc1xuICAgKiBkZWZhdWx0OiB7XG4gICAqICAgXCJMaWdodFwiOiBsaWdodCxcbiAgICogICBcIkRhcmtcIjogZGFya1xuICAgKiB9XG4gICAqL1xuICB0aGVtZXM/OiB7XG4gICAgW3RoZW1lTmFtZTogc3RyaW5nXTogVGhlbWU7XG4gIH07XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgZGVmYXVsdCAobGlnaHQpIHRoZW1lXG4gICAqIGRlZmF1bHQ6IFwiTGlnaHRcIlxuICAgKi9cbiAgZGVmYXVsdFRoZW1lTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBkYXJrIHRoZW1lXG4gICAqIGRlZmF1bHQ6IFwiRGFya1wiXG4gICAqL1xuICBkYXJrVGhlbWVOYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogU3RvcmUgdGhlIGN1cnJlbnQgdGhlbWUgaW4gbG9jYWwgc3RvcmFnZSwgdG8gc2F2ZSBpdCBiZXR3ZWVuIGJyb3dzZXIgcmVsb2Fkc1xuICAgKiBOb3RlOiBVc2VzIHRoZSBzYW1lIHZhbHVlIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIGNvbXBvbmVudCAoY2Fubm90IGJlIHVwZGF0ZWQpXG4gICAqIGRlZmF1bHQ6IGZhbHNlXG4gICAqL1xuICBkaXNhYmxlTG9jYWxTdG9yYWdlPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEdsb2JhbCBzY29wZWQgVGhlbWVQcm92aWRlcnMgYXBwbHkgZ2xvYmFsIHN0eWxlcyB0byB0aGUgYm9keSBlbGVtZW50XG4gICAqIExvY2FsIHNjb3BlZCBUaGVtZVByb3ZpZGVycyBhcHBseSBnbG9iYWwgc3R5bGVzIHRvIGEgd3JhcHBlciBkaXZcbiAgICogVW5zY29wZWQgVGhlbWVQcm92aWRlcnMgZG8gbm90IGFwcGx5IGFueSBnbG9iYWwgc3R5bGVzXG4gICAqIGRlZmF1bHQ6IFwiZ2xvYmFsXCJcbiAgICovXG4gIHNjb3BlPzogJ2dsb2JhbCcgfCAnbG9jYWwnIHwgZmFsc2U7XG59XG5cbi8qKlxuICogQSBjb21wb25lbnQgdGhhdCBwcm92aWRlcyB0aGUgYXBwIHdpdGggdGhlbWluZyBzdXBwb3J0XG4gKi9cbmNvbnN0IFRoZW1lUHJvdmlkZXIgPSBSZWFjdC5mb3J3YXJkUmVmPEhUTUxEaXZFbGVtZW50LCBUaGVtZVByb3ZpZGVyUHJvcHM+KGZ1bmN0aW9uIFRoZW1lUHJvdmlkZXIoXG4gIHByb3BzLFxuICByZWZcbikge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgdGhlbWVzID0ge1xuICAgICAgTGlnaHQ6IGxpZ2h0LFxuICAgICAgRGFyazogZGFya1xuICAgIH0sXG4gICAgZGVmYXVsdFRoZW1lTmFtZSA9ICdMaWdodCcsXG4gICAgZGFya1RoZW1lTmFtZSA9ICdEYXJrJyxcbiAgICBzY29wZSA9ICdnbG9iYWwnLFxuICAgIGRpc2FibGVMb2NhbFN0b3JhZ2U6IHByb3BEaXNhYmxlTG9jYWxTdG9yYWdlLFxuICAgIC4uLm90aGVyXG4gIH0gPSBwcm9wcztcblxuICAvLyBOb3RlOiBmYWxzZSBkdXJpbmcgcmVoeWRyYXRpb24gcnVuLCByZWdhcmRsZXNzIG9mIGJyb3dzZXIgc2V0dGluZy4uLlxuICAvLyBUT0RPOiBpZiB3ZSBzd2l0Y2ggdG8gdGhlIHVzZUh5ZHJhdGVkIGhvb2sgYW5kIHVzZSB0aGUgc3RhbmRhcmQgYnJvd3NlciBtZWRpYSBxdWVyaWVzIHdlIGNhbiBwb3NzaWJseSBhdm9pZCBleHRyYSByZW5kZXJzIGhlcmVcbiAgY29uc3QgcHJlZmVyc0RhcmtNb2RlID0gdXNlTWVkaWFRdWVyeSgnKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKScpO1xuXG4gIC8vIENhbm5vdCB1cGRhdGUgdGhlIGRpc2FibGVMb2NhbFN0b3JhZ2UgdmFsdWUgb3RoZXJ3aXNlIGRpZmZlcmVudCBob29rcyB3b3VsZCBiZSBjYWxsZWQgb24gdGhlIG5leHQgbGluZVxuICAvLyBSZWFjdCByZXF1aXJlcyB0aGF0IHRoZSBzYW1lIGhvb2tzIGJlIGNhbGxlZCBpbiB0aGUgc2FtZSBvcmRlclxuICBjb25zdCBbbG9jYWxTdG9yYWdlRW5hYmxlZF0gPSB1c2VTdGF0ZSghcHJvcERpc2FibGVMb2NhbFN0b3JhZ2UpO1xuICBjb25zdCBbY2hvc2VuVGhlbWUsIHNldENob3NlblRoZW1lXSA9IChsb2NhbFN0b3JhZ2VFbmFibGVkXG4gICAgPyAoKSA9PiB1c2VMb2NhbFN0b3JhZ2UoJ3RoZW1lJylcbiAgICA6ICgpID0+IHVzZVN0YXRlPHN0cmluZyB8IHVuZGVmaW5lZD4oZGVmYXVsdFRoZW1lTmFtZSkpKCk7XG5cbiAgY29uc3QgW3JlZ2lzdGVyZWRUaGVtZXMsIHNldFJlZ2lzdGVyZWRUaGVtZXNdID0gdXNlU3RhdGUobmV3IE1hcChPYmplY3QuZW50cmllcyh0aGVtZXMpKSk7XG5cbiAgbGV0IHRoZW1lTmFtZTogc3RyaW5nO1xuICBsZXQgdGhlbWU6IFRoZW1lO1xuICBpZiAoY2hvc2VuVGhlbWUgIT09IHVuZGVmaW5lZCAmJiByZWdpc3RlcmVkVGhlbWVzLmhhcyhjaG9zZW5UaGVtZSkpIHtcbiAgICB0aGVtZU5hbWUgPSBjaG9zZW5UaGVtZTtcbiAgICB0aGVtZSA9IHJlZ2lzdGVyZWRUaGVtZXMuZ2V0KHRoZW1lTmFtZSkgYXMgVGhlbWU7XG4gIH0gZWxzZSB7XG4gICAgdGhlbWVOYW1lID0gcHJlZmVyc0RhcmtNb2RlID8gZGFya1RoZW1lTmFtZSA6IGRlZmF1bHRUaGVtZU5hbWU7XG4gICAgdGhlbWUgPSByZWdpc3RlcmVkVGhlbWVzLmdldCh0aGVtZU5hbWUpIHx8IGxpZ2h0O1xuICB9XG5cbiAgY29uc3Qgc2V0VGhlbWUgPSB1c2VDYWxsYmFjayhcbiAgICAodGhlbWVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQpID0+IHtcbiAgICAgIGNvbnNvbGUuYXNzZXJ0KFxuICAgICAgICB0aGVtZU5hbWUgPT09IHVuZGVmaW5lZCB8fCByZWdpc3RlcmVkVGhlbWVzLmhhcyh0aGVtZU5hbWUpLFxuICAgICAgICBgVW5yZWNvZ25pc2VkIHRoZW1lOiAke3RoZW1lTmFtZX1gXG4gICAgICApO1xuICAgICAgc2V0Q2hvc2VuVGhlbWUodGhlbWVOYW1lKTtcbiAgICB9LFxuICAgIFtzZXRDaG9zZW5UaGVtZSwgcmVnaXN0ZXJlZFRoZW1lc11cbiAgKTtcblxuICBjb25zdCBzZWxlY3RlZFRoZW1lID0gdXNlTWVtbzxUaGVtZVVwZGF0ZT4oXG4gICAgKCkgPT4gKHtcbiAgICAgIHJlcXVlc3RlZFRoZW1lTmFtZTogY2hvc2VuVGhlbWUsXG4gICAgICByZW5kZXJlZFRoZW1lTmFtZTogdGhlbWVOYW1lLFxuICAgICAgdGhlbWUsXG4gICAgICBzZXRUaGVtZVxuICAgIH0pLFxuICAgIFtjaG9zZW5UaGVtZSwgdGhlbWVOYW1lLCBzZXRUaGVtZV1cbiAgKTtcblxuICBjb25zdCBzZXRUaGVtZXMgPSB1c2VDYWxsYmFjayhcbiAgICAodGhlbWVzOiB7IFtuYW1lOiBzdHJpbmddOiBUaGVtZSB9KSA9PiB7XG4gICAgICBzZXRSZWdpc3RlcmVkVGhlbWVzKG5ldyBNYXAoT2JqZWN0LmVudHJpZXModGhlbWVzKSkpO1xuICAgIH0sXG4gICAgW3NldFJlZ2lzdGVyZWRUaGVtZXNdXG4gICk7XG5cbiAgY29uc3QgdGhlbWVSZWdpc3RlcjogW01hcDxzdHJpbmcsIFRoZW1lPiwgKHRoZW1lczogeyBbbmFtZTogc3RyaW5nXTogVGhlbWUgfSkgPT4gdm9pZF0gPSB1c2VNZW1vKFxuICAgICgpID0+IFtyZWdpc3RlcmVkVGhlbWVzLCBzZXRUaGVtZXNdLFxuICAgIFtyZWdpc3RlcmVkVGhlbWVzLCBzZXRUaGVtZXNdXG4gICk7XG5cbiAgY29uc3QgY3NzQmFzZWxpbmVXcmFwcGVyID0gKCgpID0+IHtcbiAgICBzd2l0Y2ggKHNjb3BlKSB7XG4gICAgICBjYXNlICdnbG9iYWwnOlxuICAgICAgICByZXR1cm4gPENzc0Jhc2VsaW5lIHsuLi5vdGhlcn0+e2NoaWxkcmVufTwvQ3NzQmFzZWxpbmU+O1xuICAgICAgY2FzZSAnbG9jYWwnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxTY29wZWRDc3NCYXNlbGluZSB7Li4ub3RoZXJ9IHJlZj17cmVmfT5cbiAgICAgICAgICAgIHtjaGlsZHJlbn1cbiAgICAgICAgICA8L1Njb3BlZENzc0Jhc2VsaW5lPlxuICAgICAgICApO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIDw+e2NoaWxkcmVufTwvPjtcbiAgICB9XG4gIH0pKCk7XG5cbiAgcmV0dXJuIChcbiAgICA8VGhlbWVSZWdpc3RlckNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3RoZW1lUmVnaXN0ZXJ9PlxuICAgICAgPFRoZW1lVXBkYXRlQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17c2VsZWN0ZWRUaGVtZX0+XG4gICAgICAgIDxNdWlUaGVtZVByb3ZpZGVyIHRoZW1lPXt0aGVtZX0+e2Nzc0Jhc2VsaW5lV3JhcHBlcn08L011aVRoZW1lUHJvdmlkZXI+XG4gICAgICA8L1RoZW1lVXBkYXRlQ29udGV4dC5Qcm92aWRlcj5cbiAgICA8L1RoZW1lUmVnaXN0ZXJDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufSk7XG5cblRoZW1lUHJvdmlkZXIucHJvcFR5cGVzID0ge1xuICBjaGlsZHJlbjogUHJvcFR5cGVzLm5vZGUsXG4gIHRoZW1lczogUHJvcFR5cGVzLm9iamVjdE9mKChQcm9wVHlwZXMub2JqZWN0IGFzIFJlcXVpcmVhYmxlPFRoZW1lPikuaXNSZXF1aXJlZCksXG4gIGRlZmF1bHRUaGVtZU5hbWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGRhcmtUaGVtZU5hbWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGRpc2FibGVMb2NhbFN0b3JhZ2U6IFByb3BUeXBlcy5ib29sLFxuICBzY29wZTogUHJvcFR5cGVzLm9uZU9mKFsnZ2xvYmFsJywgJ2xvY2FsJywgZmFsc2VdKVxufTtcblxuLyoqXG4gKiBBIGNvbXBvbmVudCB0aGF0IHByb3ZpZGVzIHRoZSBhcHAgd2l0aCB0aGVtaW5nIHN1cHBvcnQuXG4gKiBBbHNvIHByb3ZpZGluZyBhIGA8SHlkcmF0aW9uQ2hlY2tlci8+YC5cbiAqL1xuY29uc3QgVGhlbWVQcm92aWRlcldpdGhIeWRyYXRpb25DaGVja2VyID0gUmVhY3QuZm9yd2FyZFJlZjxIVE1MRGl2RWxlbWVudCwgVGhlbWVQcm92aWRlclByb3BzPihcbiAgKHByb3BzLCByZWYpID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgPEh5ZHJhdGlvbkNoZWNrZXI+XG4gICAgICAgIDxUaGVtZVByb3ZpZGVyIHsuLi5wcm9wc30gcmVmPXtyZWZ9IC8+XG4gICAgICA8L0h5ZHJhdGlvbkNoZWNrZXI+XG4gICAgKTtcbiAgfVxuKTtcblxuVGhlbWVQcm92aWRlcldpdGhIeWRyYXRpb25DaGVja2VyLmRpc3BsYXlOYW1lID0gJ1RoZW1lUHJvdmlkZXInO1xuXG5leHBvcnQgZGVmYXVsdCBUaGVtZVByb3ZpZGVyV2l0aEh5ZHJhdGlvbkNoZWNrZXI7XG4iXSwibmFtZXMiOlsiTXVpVGhlbWVQcm92aWRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQW9EQTs7O0FBR0EsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBcUMsU0FBUyxhQUFhLENBQy9GLEtBQUssRUFDTCxHQUFHO0lBRUgsTUFBTSxFQUNKLFFBQVEsRUFDUixNQUFNLEdBQUc7UUFDUCxLQUFLLEVBQUUsS0FBSztRQUNaLElBQUksRUFBRSxJQUFJO0tBQ1gsRUFDRCxnQkFBZ0IsR0FBRyxPQUFPLEVBQzFCLGFBQWEsR0FBRyxNQUFNLEVBQ3RCLEtBQUssR0FBRyxRQUFRLEVBQ2hCLG1CQUFtQixFQUFFLHVCQUF1QixLQUUxQyxLQUFLLEVBREosS0FBSyxVQUNOLEtBQUssRUFYSCwyRkFXTCxDQUFRLENBQUM7OztJQUlWLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDOzs7SUFJdEUsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUNqRSxNQUFNLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQyxHQUFHLENBQUMsbUJBQW1CO1VBQ3RELE1BQU0sZUFBZSxDQUFDLE9BQU8sQ0FBQztVQUM5QixN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