/node_modules/@mui/system/legacy/cssVars/useCurrentColorScheme.js

https://gitlab.com/sagefhopkins/hopkinsdev · JavaScript · 231 lines · 190 code · 39 blank · 2 comment · 51 complexity · 617d7c7af1d2b01f794d3bb21df0cc35 MD5 · raw file

  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import * as React from 'react';
  3. import { DEFAULT_MODE_STORAGE_KEY, DEFAULT_COLOR_SCHEME_STORAGE_KEY } from './getInitColorSchemeScript';
  4. export function getSystemMode(mode) {
  5. if (typeof window !== 'undefined' && mode === 'system') {
  6. var mql = window.matchMedia('(prefers-color-scheme: dark)');
  7. if (mql.matches) {
  8. return 'dark';
  9. }
  10. return 'light';
  11. }
  12. return undefined;
  13. }
  14. function processState(state, callback) {
  15. if (state.mode === 'light' || state.mode === 'system' && state.systemMode === 'light') {
  16. return callback('light');
  17. }
  18. if (state.mode === 'dark' || state.mode === 'system' && state.systemMode === 'dark') {
  19. return callback('dark');
  20. }
  21. return undefined;
  22. }
  23. export function getColorScheme(state) {
  24. return processState(state, function (mode) {
  25. if (mode === 'light') {
  26. return state.lightColorScheme;
  27. }
  28. if (mode === 'dark') {
  29. return state.darkColorScheme;
  30. }
  31. return undefined;
  32. });
  33. }
  34. function resolveValue(key, defaultValue) {
  35. if (typeof window === 'undefined') {
  36. return undefined;
  37. }
  38. var value;
  39. try {
  40. value = localStorage.getItem(key) || undefined;
  41. } catch (e) {// Unsupported
  42. }
  43. return value || defaultValue;
  44. }
  45. export default function useCurrentColorScheme(options) {
  46. var _options$defaultMode = options.defaultMode,
  47. defaultMode = _options$defaultMode === void 0 ? 'light' : _options$defaultMode,
  48. defaultLightColorScheme = options.defaultLightColorScheme,
  49. defaultDarkColorScheme = options.defaultDarkColorScheme,
  50. _options$supportedCol = options.supportedColorSchemes,
  51. supportedColorSchemes = _options$supportedCol === void 0 ? [] : _options$supportedCol,
  52. _options$modeStorageK = options.modeStorageKey,
  53. modeStorageKey = _options$modeStorageK === void 0 ? DEFAULT_MODE_STORAGE_KEY : _options$modeStorageK,
  54. _options$colorSchemeS = options.colorSchemeStorageKey,
  55. colorSchemeStorageKey = _options$colorSchemeS === void 0 ? DEFAULT_COLOR_SCHEME_STORAGE_KEY : _options$colorSchemeS;
  56. var joinedColorSchemes = supportedColorSchemes.join(',');
  57. var _React$useState = React.useState(function () {
  58. var initialMode = resolveValue(modeStorageKey, defaultMode);
  59. return {
  60. mode: initialMode,
  61. systemMode: getSystemMode(initialMode),
  62. lightColorScheme: resolveValue("".concat(colorSchemeStorageKey, "-light")) || defaultLightColorScheme,
  63. darkColorScheme: resolveValue("".concat(colorSchemeStorageKey, "-dark")) || defaultDarkColorScheme
  64. };
  65. }),
  66. state = _React$useState[0],
  67. setState = _React$useState[1];
  68. var colorScheme = getColorScheme(state);
  69. var setMode = React.useCallback(function (mode) {
  70. setState(function (currentState) {
  71. var newMode = !mode ? defaultMode : mode;
  72. if (typeof localStorage !== 'undefined') {
  73. localStorage.setItem(modeStorageKey, newMode);
  74. }
  75. return _extends({}, currentState, {
  76. mode: newMode,
  77. systemMode: getSystemMode(newMode)
  78. });
  79. });
  80. }, [modeStorageKey, defaultMode]);
  81. var setColorScheme = React.useCallback(function (value) {
  82. if (!value || typeof value === 'string') {
  83. if (value && !supportedColorSchemes.includes(value)) {
  84. console.error("`".concat(value, "` does not exist in `theme.colorSchemes`."));
  85. } else {
  86. setState(function (currentState) {
  87. var newState = _extends({}, currentState);
  88. if (!value) {
  89. // reset to default color scheme
  90. newState.lightColorScheme = defaultLightColorScheme;
  91. newState.darkColorScheme = defaultDarkColorScheme;
  92. return newState;
  93. }
  94. processState(currentState, function (mode) {
  95. localStorage.setItem("".concat(colorSchemeStorageKey, "-").concat(mode), value);
  96. if (mode === 'light') {
  97. newState.lightColorScheme = value;
  98. }
  99. if (mode === 'dark') {
  100. newState.darkColorScheme = value;
  101. }
  102. });
  103. return newState;
  104. });
  105. }
  106. } else if (value.light && !supportedColorSchemes.includes(value.light) || value.dark && !supportedColorSchemes.includes(value.dark)) {
  107. console.error("`".concat(value, "` does not exist in `theme.colorSchemes`."));
  108. } else {
  109. setState(function (currentState) {
  110. var newState = _extends({}, currentState);
  111. if (value.light || value.light === null) {
  112. newState.lightColorScheme = value.light === null ? defaultLightColorScheme : value.light;
  113. }
  114. if (value.dark || value.dark === null) {
  115. newState.darkColorScheme = value.dark === null ? defaultDarkColorScheme : value.dark;
  116. }
  117. return newState;
  118. });
  119. if (value.light) {
  120. localStorage.setItem("".concat(colorSchemeStorageKey, "-light"), value.light);
  121. }
  122. if (value.dark) {
  123. localStorage.setItem("".concat(colorSchemeStorageKey, "-dark"), value.dark);
  124. }
  125. }
  126. }, [colorSchemeStorageKey, supportedColorSchemes, defaultLightColorScheme, defaultDarkColorScheme]);
  127. var handleMediaQuery = React.useCallback(function (e) {
  128. if (state.mode === 'system') {
  129. setState(function (currentState) {
  130. return _extends({}, currentState, {
  131. systemMode: e.matches ? 'dark' : 'light'
  132. });
  133. });
  134. }
  135. }, [state.mode]); // Ref hack to avoid adding handleMediaQuery as a dep
  136. var mediaListener = React.useRef(handleMediaQuery);
  137. mediaListener.current = handleMediaQuery;
  138. React.useEffect(function () {
  139. var handler = function handler() {
  140. return mediaListener.current.apply(mediaListener, arguments);
  141. }; // Always listen to System preference
  142. var media = window.matchMedia('(prefers-color-scheme: dark)'); // Intentionally use deprecated listener methods to support iOS & old browsers
  143. media.addListener(handler);
  144. handler(media);
  145. return function () {
  146. return media.removeListener(handler);
  147. };
  148. }, []); // Save mode, lightColorScheme & darkColorScheme to localStorage
  149. React.useEffect(function () {
  150. if (state.mode) {
  151. localStorage.setItem(modeStorageKey, state.mode);
  152. }
  153. processState(state, function (mode) {
  154. if (mode === 'light') {
  155. localStorage.setItem("".concat(colorSchemeStorageKey, "-light"), state.lightColorScheme);
  156. }
  157. if (mode === 'dark') {
  158. localStorage.setItem("".concat(colorSchemeStorageKey, "-dark"), state.darkColorScheme);
  159. }
  160. });
  161. }, [state, colorSchemeStorageKey, modeStorageKey]); // Handle when localStorage has changed
  162. React.useEffect(function () {
  163. var handleStorage = function handleStorage(event) {
  164. var value = event.newValue;
  165. if (typeof event.key === 'string' && event.key.startsWith(colorSchemeStorageKey) && (!value || joinedColorSchemes.match(value))) {
  166. // If the key is deleted, value will be null then reset color scheme to the default one.
  167. if (event.key.endsWith('light')) {
  168. setColorScheme({
  169. light: value
  170. });
  171. }
  172. if (event.key.endsWith('dark')) {
  173. setColorScheme({
  174. dark: value
  175. });
  176. }
  177. }
  178. if (event.key === modeStorageKey && (!value || ['light', 'dark', 'system'].includes(value))) {
  179. setMode(value || defaultMode);
  180. }
  181. };
  182. window.addEventListener('storage', handleStorage);
  183. return function () {
  184. return window.removeEventListener('storage', handleStorage);
  185. };
  186. }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode]);
  187. return _extends({}, state, {
  188. colorScheme: colorScheme,
  189. setMode: setMode,
  190. setColorScheme: setColorScheme
  191. });
  192. }