@zendeskgarden/react-theming
Advanced tools
Comparing version 9.4.0 to 9.5.0
@@ -7,2 +7,3 @@ /** | ||
*/ | ||
export { ColorSchemeProvider } from './elements/ColorSchemeProvider.js'; | ||
export { ThemeProvider } from './elements/ThemeProvider.js'; | ||
@@ -23,2 +24,3 @@ export { default as DEFAULT_THEME } from './elements/theme/index.js'; | ||
export { default as arrowStyles } from './utils/arrowStyles.js'; | ||
export { useColorScheme } from './utils/useColorScheme.js'; | ||
export { useDocument } from './utils/useDocument.js'; | ||
@@ -25,0 +27,0 @@ export { useWindow } from './utils/useWindow.js'; |
@@ -23,2 +23,64 @@ /** | ||
const useColorScheme$1 = function (initialState) { | ||
let colorSchemeKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'color-scheme'; | ||
const localStorage = typeof window === 'undefined' ? undefined : window.localStorage; | ||
const mediaQuery = typeof window === 'undefined' ? undefined : window.matchMedia('(prefers-color-scheme: dark)'); | ||
const getState = React.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 | ||
}; | ||
}, [mediaQuery?.matches]); | ||
const [state, setState] = React.useState(getState(localStorage?.getItem(colorSchemeKey) || initialState)); | ||
React.useEffect(() => { | ||
const eventListener = () => { | ||
setState(getState('system')); | ||
}; | ||
if (state.isSystem) { | ||
mediaQuery?.addEventListener('change', eventListener); | ||
} else { | ||
mediaQuery?.removeEventListener('change', eventListener); | ||
} | ||
return () => { | ||
mediaQuery?.removeEventListener('change', eventListener); | ||
}; | ||
}, [getState, state.isSystem, mediaQuery]); | ||
return { | ||
isSystem: state.isSystem, | ||
colorScheme: state.colorScheme, | ||
setColorScheme: colorScheme => { | ||
setState(getState(colorScheme)); | ||
localStorage?.setItem(colorSchemeKey, colorScheme); | ||
} | ||
}; | ||
}; | ||
const ColorSchemeContext = React.createContext(undefined); | ||
const ColorSchemeProvider = _ref => { | ||
let { | ||
children, | ||
colorSchemeKey, | ||
initialColorScheme | ||
} = _ref; | ||
const { | ||
isSystem, | ||
colorScheme, | ||
setColorScheme | ||
} = useColorScheme$1(initialColorScheme, colorSchemeKey); | ||
const contextValue = React.useMemo(() => ({ | ||
colorScheme, | ||
isSystem, | ||
setColorScheme | ||
}), [isSystem, colorScheme, setColorScheme]); | ||
return React__default.default.createElement(ColorSchemeContext.Provider, { | ||
value: contextValue | ||
}, children); | ||
}; | ||
const PALETTE = { | ||
@@ -1337,2 +1399,10 @@ black: '#000', | ||
const useColorScheme = () => { | ||
const context = React.useContext(ColorSchemeContext); | ||
if (!context) { | ||
throw new Error('Error: this component must be rendered within a <ColorSchemeProvider>.'); | ||
} | ||
return context; | ||
}; | ||
const useDocument = theme => { | ||
@@ -1491,2 +1561,3 @@ const [controlledDocument, setControlledDocument] = React.useState(); | ||
exports.ARROW_POSITION = ARROW_POSITION; | ||
exports.ColorSchemeProvider = ColorSchemeProvider; | ||
exports.DEFAULT_THEME = DEFAULT_THEME; | ||
@@ -1513,4 +1584,5 @@ exports.MENU_POSITION = MENU_POSITION; | ||
exports.retrieveComponentStyles = retrieveComponentStyles; | ||
exports.useColorScheme = useColorScheme; | ||
exports.useDocument = useDocument; | ||
exports.useText = useText; | ||
exports.useWindow = useWindow; |
@@ -7,2 +7,3 @@ /** | ||
*/ | ||
export { ColorSchemeProvider } from './elements/ColorSchemeProvider'; | ||
export { ThemeProvider } from './elements/ThemeProvider'; | ||
@@ -23,2 +24,3 @@ export { default as DEFAULT_THEME } from './elements/theme'; | ||
export { default as arrowStyles } from './utils/arrowStyles'; | ||
export { useColorScheme } from './utils/useColorScheme'; | ||
export { useDocument } from './utils/useDocument'; | ||
@@ -30,2 +32,2 @@ export { useWindow } from './utils/useWindow'; | ||
export { StyledBaseIcon } from './utils/StyledBaseIcon'; | ||
export { ARROW_POSITION, MENU_POSITION, PLACEMENT, type IGardenTheme, type IStyledBaseIconProps, type IThemeProviderProps, type ArrowPosition, type CheckeredBackgroundParameters, type ColorParameters, type FocusBoxShadowParameters, type FocusStylesParameters, type MenuPosition, type Placement } from './types'; | ||
export { ARROW_POSITION, MENU_POSITION, PLACEMENT, type IColorSchemeContext, type IColorSchemeProviderProps, type IGardenTheme, type IStyledBaseIconProps, type IThemeProviderProps, type ArrowPosition, type CheckeredBackgroundParameters, type ColorParameters, type ColorScheme, type FocusBoxShadowParameters, type FocusStylesParameters, type MenuPosition, type Placement } from './types'; |
@@ -168,2 +168,24 @@ /** | ||
} | ||
export type ColorScheme = IGardenTheme['colors']['base'] | 'system'; | ||
export interface IColorSchemeContext { | ||
/** Returns the current color scheme */ | ||
colorScheme: IGardenTheme['colors']['base']; | ||
/** Indicates whether the `colorScheme` is determined by the system */ | ||
isSystem: boolean; | ||
/** Provides the mechanism for updating the current color scheme */ | ||
setColorScheme: (colorScheme: ColorScheme) => void; | ||
} | ||
export interface IColorSchemeProviderProps { | ||
/** | ||
* Sets the initial color scheme and provides `localStorage` persistence (see | ||
* the `useColorScheme` hook). A user's stored preference overrides this | ||
* value. | ||
*/ | ||
initialColorScheme?: ColorScheme; | ||
/** | ||
* Specifies the key used to store the user's preferred color scheme in | ||
* `localStorage` | ||
*/ | ||
colorSchemeKey?: string; | ||
} | ||
export interface IThemeProviderProps extends Partial<ThemeProviderProps<IGardenTheme>> { | ||
@@ -170,0 +192,0 @@ /** |
{ | ||
"name": "@zendeskgarden/react-theming", | ||
"version": "9.4.0", | ||
"version": "9.5.0", | ||
"description": "Theming utilities and components within the Garden Design System", | ||
@@ -50,3 +50,3 @@ "license": "Apache-2.0", | ||
"zendeskgarden:src": "src/index.ts", | ||
"gitHead": "02e3f240b6f0c776fdae785254d6fe90cbfc37e4" | ||
"gitHead": "43546784a9aa985332ddcc6dd09209a11e2c03ff" | ||
} |
@@ -45,5 +45,35 @@ # @zendeskgarden/react-theming [![npm version](https://flat.badgen.net/npm/v/@zendeskgarden/react-theming)](https://www.npmjs.com/package/@zendeskgarden/react-theming) | ||
### RTL | ||
#### Color scheme | ||
The `ColorSchemeProvider` and `useColorScheme` hook add the capability for a | ||
user to persist a preferred system color scheme (`'light'`, `'dark'`, or | ||
`'system'`). See | ||
[Storybook](https://zendeskgarden.github.io/react-components/?path=/docs/packages-theming-colorschemeprovider--color-scheme-provider) | ||
for more details. | ||
```jsx | ||
import { | ||
useColorScheme, | ||
ColorSchemeProvider, | ||
ThemeProvider, | ||
DEFAULT_THEME | ||
} from '@zendeskgarden/react-theming'; | ||
const ThemedApp = ({ children }) => { | ||
const { colorScheme } = useColorScheme(); | ||
const theme = { ...DEFAULT_THEME, colors: { ...DEFAULT_THEME.colors, base: colorScheme } }; | ||
return <ThemeProvider theme={theme}>{children}</ThemeProvider>; | ||
}; | ||
const App = ({ children }) => ( | ||
<ColorSchemeProvider> | ||
<ThemedApp>{children}</ThemedApp> | ||
</ColorSchemeProvider> | ||
); | ||
``` | ||
#### RTL | ||
```jsx | ||
import { ThemeProvider, DEFAULT_THEME } from '@zendeskgarden/react-theming'; | ||
@@ -50,0 +80,0 @@ import { Notification } from '@zendeskgarden/react-notifications'; |
147346
56
4386
85