@atlaskit/app-provider
Version:
A top level provider for the Design System.
48 lines (46 loc) • 1.91 kB
JavaScript
import { useContext, useEffect, useState } from 'react';
import { getGlobalTheme } from '@atlaskit/tokens/get-global-theme';
import { ThemeMutationObserver } from '@atlaskit/tokens/theme-mutation-observer';
import { ColorModeContext } from '../context/color-mode';
/**
* __useColorMode()__
*
* Returns the active (reconciled) color mode for the current theme context.
*
* When the color mode is set to `'auto'`, this hook returns the resolved value
* (`'light'` or `'dark'`) based on the system color scheme preference.
* it will never return `'auto'`. Use `useSetColorMode` to change the color mode.
*
* This hook can be used both inside and outside `AppProvider`. When used inside
* a nested `ThemeProvider`, it reflects the color mode of that sub-tree.
*
* @returns The current reconciled color mode: `'light'` or `'dark'`.
*
* @example
* ```tsx
* function MyComponent() {
* const colorMode = useColorMode();
*
* return <p>Current color mode: {colorMode}</p>;
* }
* ```
*/
export function useColorMode() {
const value = useContext(ColorModeContext);
// TODO: This will only return 'light' or 'dark' but never 'auto', which in some cases
// may be desirable. We should consider returning both the reconciled color mode (e.g. 'light' or 'dark') and the selected color mode ("auto").
const theme = getGlobalTheme();
const [resolvedColorMode, setResolvedColorMode] = useState((theme === null || theme === void 0 ? void 0 : theme.colorMode) || 'light');
useEffect(() => {
// We are using theme from context so no need to reference the DOM
if (value) {
return;
}
const observer = new ThemeMutationObserver(theme => {
setResolvedColorMode((theme === null || theme === void 0 ? void 0 : theme.colorMode) || 'light');
});
observer.observe();
return () => observer.disconnect();
}, [value]);
return value ? value : resolvedColorMode;
}