@zendeskgarden/react-theming 9.4.0 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -1
- package/dist/esm/elements/ColorSchemeProvider.js +71 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/utils/useColorScheme.js +18 -0
- package/dist/index.cjs.js +72 -0
- package/dist/typings/elements/ColorSchemeProvider.d.ts +10 -0
- package/dist/typings/index.d.ts +3 -1
- package/dist/typings/types/index.d.ts +22 -0
- package/dist/typings/utils/useColorScheme.d.ts +12 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -42,7 +42,37 @@ complex, depending on your needs:
|
|
|
42
42
|
behavior and RTL layout of Garden's tabs component with an alternate visual
|
|
43
43
|
design (i.e. closer to the look of browser tabs).
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
#### Color scheme
|
|
46
|
+
|
|
47
|
+
The `ColorSchemeProvider` and `useColorScheme` hook add the capability for a
|
|
48
|
+
user to persist a preferred system color scheme (`'light'`, `'dark'`, or
|
|
49
|
+
`'system'`). See
|
|
50
|
+
[Storybook](https://zendeskgarden.github.io/react-components/?path=/docs/packages-theming-colorschemeprovider--color-scheme-provider)
|
|
51
|
+
for more details.
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
import {
|
|
55
|
+
useColorScheme,
|
|
56
|
+
ColorSchemeProvider,
|
|
57
|
+
ThemeProvider,
|
|
58
|
+
DEFAULT_THEME
|
|
59
|
+
} from '@zendeskgarden/react-theming';
|
|
60
|
+
|
|
61
|
+
const ThemedApp = ({ children }) => {
|
|
62
|
+
const { colorScheme } = useColorScheme();
|
|
63
|
+
const theme = { ...DEFAULT_THEME, colors: { ...DEFAULT_THEME.colors, base: colorScheme } };
|
|
64
|
+
|
|
65
|
+
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const App = ({ children }) => (
|
|
69
|
+
<ColorSchemeProvider>
|
|
70
|
+
<ThemedApp>{children}</ThemedApp>
|
|
71
|
+
</ColorSchemeProvider>
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### RTL
|
|
46
76
|
|
|
47
77
|
```jsx
|
|
48
78
|
import { ThemeProvider, DEFAULT_THEME } from '@zendeskgarden/react-theming';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import React, { createContext, useMemo, useCallback, useState, useEffect } from 'react';
|
|
8
|
+
|
|
9
|
+
const useColorScheme = function (initialState) {
|
|
10
|
+
let colorSchemeKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'color-scheme';
|
|
11
|
+
const localStorage = typeof window === 'undefined' ? undefined : window.localStorage;
|
|
12
|
+
const mediaQuery = typeof window === 'undefined' ? undefined : window.matchMedia('(prefers-color-scheme: dark)');
|
|
13
|
+
const getState = useCallback(_state => {
|
|
14
|
+
const isSystem = _state === 'system' || _state === undefined || _state === null;
|
|
15
|
+
let colorScheme;
|
|
16
|
+
if (isSystem) {
|
|
17
|
+
colorScheme = mediaQuery?.matches ? 'dark' : 'light';
|
|
18
|
+
} else {
|
|
19
|
+
colorScheme = _state;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
isSystem,
|
|
23
|
+
colorScheme
|
|
24
|
+
};
|
|
25
|
+
}, [mediaQuery?.matches]);
|
|
26
|
+
const [state, setState] = useState(getState(localStorage?.getItem(colorSchemeKey) || initialState));
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const eventListener = () => {
|
|
29
|
+
setState(getState('system'));
|
|
30
|
+
};
|
|
31
|
+
if (state.isSystem) {
|
|
32
|
+
mediaQuery?.addEventListener('change', eventListener);
|
|
33
|
+
} else {
|
|
34
|
+
mediaQuery?.removeEventListener('change', eventListener);
|
|
35
|
+
}
|
|
36
|
+
return () => {
|
|
37
|
+
mediaQuery?.removeEventListener('change', eventListener);
|
|
38
|
+
};
|
|
39
|
+
}, [getState, state.isSystem, mediaQuery]);
|
|
40
|
+
return {
|
|
41
|
+
isSystem: state.isSystem,
|
|
42
|
+
colorScheme: state.colorScheme,
|
|
43
|
+
setColorScheme: colorScheme => {
|
|
44
|
+
setState(getState(colorScheme));
|
|
45
|
+
localStorage?.setItem(colorSchemeKey, colorScheme);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const ColorSchemeContext = createContext(undefined);
|
|
50
|
+
const ColorSchemeProvider = _ref => {
|
|
51
|
+
let {
|
|
52
|
+
children,
|
|
53
|
+
colorSchemeKey,
|
|
54
|
+
initialColorScheme
|
|
55
|
+
} = _ref;
|
|
56
|
+
const {
|
|
57
|
+
isSystem,
|
|
58
|
+
colorScheme,
|
|
59
|
+
setColorScheme
|
|
60
|
+
} = useColorScheme(initialColorScheme, colorSchemeKey);
|
|
61
|
+
const contextValue = useMemo(() => ({
|
|
62
|
+
colorScheme,
|
|
63
|
+
isSystem,
|
|
64
|
+
setColorScheme
|
|
65
|
+
}), [isSystem, colorScheme, setColorScheme]);
|
|
66
|
+
return React.createElement(ColorSchemeContext.Provider, {
|
|
67
|
+
value: contextValue
|
|
68
|
+
}, children);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export { ColorSchemeContext, ColorSchemeProvider };
|
package/dist/esm/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
5
|
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
6
|
*/
|
|
7
|
+
export { ColorSchemeProvider } from './elements/ColorSchemeProvider.js';
|
|
7
8
|
export { ThemeProvider } from './elements/ThemeProvider.js';
|
|
8
9
|
export { default as DEFAULT_THEME } from './elements/theme/index.js';
|
|
9
10
|
export { default as PALETTE } from './elements/palette/index.js';
|
|
@@ -19,6 +20,7 @@ export { default as getLineHeight } from './utils/getLineHeight.js';
|
|
|
19
20
|
export { getMenuPosition } from './utils/getMenuPosition.js';
|
|
20
21
|
export { default as mediaQuery } from './utils/mediaQuery.js';
|
|
21
22
|
export { default as arrowStyles } from './utils/arrowStyles.js';
|
|
23
|
+
export { useColorScheme } from './utils/useColorScheme.js';
|
|
22
24
|
export { useDocument } from './utils/useDocument.js';
|
|
23
25
|
export { useWindow } from './utils/useWindow.js';
|
|
24
26
|
export { useText } from './utils/useText.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { useContext } from 'react';
|
|
8
|
+
import { ColorSchemeContext } from '../elements/ColorSchemeProvider.js';
|
|
9
|
+
|
|
10
|
+
const useColorScheme = () => {
|
|
11
|
+
const context = useContext(ColorSchemeContext);
|
|
12
|
+
if (!context) {
|
|
13
|
+
throw new Error('Error: this component must be rendered within a <ColorSchemeProvider>.');
|
|
14
|
+
}
|
|
15
|
+
return context;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { useColorScheme };
|
package/dist/index.cjs.js
CHANGED
|
@@ -20,6 +20,68 @@ var styled__default = /*#__PURE__*/_interopDefault(styled);
|
|
|
20
20
|
var get__default = /*#__PURE__*/_interopDefault(get);
|
|
21
21
|
var memoize__default = /*#__PURE__*/_interopDefault(memoize);
|
|
22
22
|
|
|
23
|
+
const useColorScheme$1 = function (initialState) {
|
|
24
|
+
let colorSchemeKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'color-scheme';
|
|
25
|
+
const localStorage = typeof window === 'undefined' ? undefined : window.localStorage;
|
|
26
|
+
const mediaQuery = typeof window === 'undefined' ? undefined : window.matchMedia('(prefers-color-scheme: dark)');
|
|
27
|
+
const getState = React.useCallback(_state => {
|
|
28
|
+
const isSystem = _state === 'system' || _state === undefined || _state === null;
|
|
29
|
+
let colorScheme;
|
|
30
|
+
if (isSystem) {
|
|
31
|
+
colorScheme = mediaQuery?.matches ? 'dark' : 'light';
|
|
32
|
+
} else {
|
|
33
|
+
colorScheme = _state;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
isSystem,
|
|
37
|
+
colorScheme
|
|
38
|
+
};
|
|
39
|
+
}, [mediaQuery?.matches]);
|
|
40
|
+
const [state, setState] = React.useState(getState(localStorage?.getItem(colorSchemeKey) || initialState));
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
const eventListener = () => {
|
|
43
|
+
setState(getState('system'));
|
|
44
|
+
};
|
|
45
|
+
if (state.isSystem) {
|
|
46
|
+
mediaQuery?.addEventListener('change', eventListener);
|
|
47
|
+
} else {
|
|
48
|
+
mediaQuery?.removeEventListener('change', eventListener);
|
|
49
|
+
}
|
|
50
|
+
return () => {
|
|
51
|
+
mediaQuery?.removeEventListener('change', eventListener);
|
|
52
|
+
};
|
|
53
|
+
}, [getState, state.isSystem, mediaQuery]);
|
|
54
|
+
return {
|
|
55
|
+
isSystem: state.isSystem,
|
|
56
|
+
colorScheme: state.colorScheme,
|
|
57
|
+
setColorScheme: colorScheme => {
|
|
58
|
+
setState(getState(colorScheme));
|
|
59
|
+
localStorage?.setItem(colorSchemeKey, colorScheme);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const ColorSchemeContext = React.createContext(undefined);
|
|
64
|
+
const ColorSchemeProvider = _ref => {
|
|
65
|
+
let {
|
|
66
|
+
children,
|
|
67
|
+
colorSchemeKey,
|
|
68
|
+
initialColorScheme
|
|
69
|
+
} = _ref;
|
|
70
|
+
const {
|
|
71
|
+
isSystem,
|
|
72
|
+
colorScheme,
|
|
73
|
+
setColorScheme
|
|
74
|
+
} = useColorScheme$1(initialColorScheme, colorSchemeKey);
|
|
75
|
+
const contextValue = React.useMemo(() => ({
|
|
76
|
+
colorScheme,
|
|
77
|
+
isSystem,
|
|
78
|
+
setColorScheme
|
|
79
|
+
}), [isSystem, colorScheme, setColorScheme]);
|
|
80
|
+
return React__default.default.createElement(ColorSchemeContext.Provider, {
|
|
81
|
+
value: contextValue
|
|
82
|
+
}, children);
|
|
83
|
+
};
|
|
84
|
+
|
|
23
85
|
const PALETTE = {
|
|
24
86
|
black: '#000',
|
|
25
87
|
white: '#fff',
|
|
@@ -1333,6 +1395,14 @@ function arrowStyles(position) {
|
|
|
1333
1395
|
return styled.css(["position:relative;&::before,&::after{position:absolute;border-width:inherit;border-style:inherit;background-color:inherit;width:", ";height:", ";content:'';box-sizing:inherit;}&::before{border-color:inherit;clip-path:polygon(100% ", "px,", "px 100%,100% 100%);}&::after{border-color:transparent;background-clip:content-box;clip-path:polygon(100% ", "px,", "px 100%,100% 100%);}", ";", ";"], squareSizePx, squareSizePx, beforeOffset, beforeOffset, afterOffset, afterOffset, positionStyles(position, squareSizeRounded, inset, shift), options.animationModifier && animationStyles$1(position, options.animationModifier));
|
|
1334
1396
|
}
|
|
1335
1397
|
|
|
1398
|
+
const useColorScheme = () => {
|
|
1399
|
+
const context = React.useContext(ColorSchemeContext);
|
|
1400
|
+
if (!context) {
|
|
1401
|
+
throw new Error('Error: this component must be rendered within a <ColorSchemeProvider>.');
|
|
1402
|
+
}
|
|
1403
|
+
return context;
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1336
1406
|
const useDocument = theme => {
|
|
1337
1407
|
const [controlledDocument, setControlledDocument] = React.useState();
|
|
1338
1408
|
React.useEffect(() => {
|
|
@@ -1486,6 +1556,7 @@ const MENU_POSITION = ['top', 'right', 'bottom', 'left'];
|
|
|
1486
1556
|
const PLACEMENT = ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'end', 'end-top', 'end-bottom', 'start', 'start-top', 'start-bottom'];
|
|
1487
1557
|
|
|
1488
1558
|
exports.ARROW_POSITION = ARROW_POSITION;
|
|
1559
|
+
exports.ColorSchemeProvider = ColorSchemeProvider;
|
|
1489
1560
|
exports.DEFAULT_THEME = DEFAULT_THEME;
|
|
1490
1561
|
exports.MENU_POSITION = MENU_POSITION;
|
|
1491
1562
|
exports.PALETTE = PALETTE;
|
|
@@ -1507,6 +1578,7 @@ exports.getMenuPosition = getMenuPosition;
|
|
|
1507
1578
|
exports.mediaQuery = mediaQuery;
|
|
1508
1579
|
exports.menuStyles = menuStyles;
|
|
1509
1580
|
exports.retrieveComponentStyles = retrieveComponentStyles;
|
|
1581
|
+
exports.useColorScheme = useColorScheme;
|
|
1510
1582
|
exports.useDocument = useDocument;
|
|
1511
1583
|
exports.useText = useText;
|
|
1512
1584
|
exports.useWindow = useWindow;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import React, { PropsWithChildren } from 'react';
|
|
8
|
+
import { IColorSchemeContext, IColorSchemeProviderProps } from '../types';
|
|
9
|
+
export declare const ColorSchemeContext: React.Context<IColorSchemeContext | undefined>;
|
|
10
|
+
export declare const ColorSchemeProvider: ({ children, colorSchemeKey, initialColorScheme }: PropsWithChildren<IColorSchemeProviderProps>) => React.JSX.Element;
|
package/dist/typings/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
5
|
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
6
|
*/
|
|
7
|
+
export { ColorSchemeProvider } from './elements/ColorSchemeProvider';
|
|
7
8
|
export { ThemeProvider } from './elements/ThemeProvider';
|
|
8
9
|
export { default as DEFAULT_THEME } from './elements/theme';
|
|
9
10
|
export { default as PALETTE } from './elements/palette';
|
|
@@ -19,10 +20,11 @@ export { default as getLineHeight } from './utils/getLineHeight';
|
|
|
19
20
|
export { getMenuPosition } from './utils/getMenuPosition';
|
|
20
21
|
export { default as mediaQuery } from './utils/mediaQuery';
|
|
21
22
|
export { default as arrowStyles } from './utils/arrowStyles';
|
|
23
|
+
export { useColorScheme } from './utils/useColorScheme';
|
|
22
24
|
export { useDocument } from './utils/useDocument';
|
|
23
25
|
export { useWindow } from './utils/useWindow';
|
|
24
26
|
export { useText } from './utils/useText';
|
|
25
27
|
export { default as menuStyles } from './utils/menuStyles';
|
|
26
28
|
export { focusStyles, SELECTOR_FOCUS_VISIBLE } from './utils/focusStyles';
|
|
27
29
|
export { StyledBaseIcon } from './utils/StyledBaseIcon';
|
|
28
|
-
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';
|
|
30
|
+
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';
|
|
@@ -165,6 +165,28 @@ export interface IGardenTheme {
|
|
|
165
165
|
xxl: string;
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
+
export type ColorScheme = IGardenTheme['colors']['base'] | 'system';
|
|
169
|
+
export interface IColorSchemeContext {
|
|
170
|
+
/** Returns the current color scheme */
|
|
171
|
+
colorScheme: IGardenTheme['colors']['base'];
|
|
172
|
+
/** Indicates whether the `colorScheme` is determined by the system */
|
|
173
|
+
isSystem: boolean;
|
|
174
|
+
/** Provides the mechanism for updating the current color scheme */
|
|
175
|
+
setColorScheme: (colorScheme: ColorScheme) => void;
|
|
176
|
+
}
|
|
177
|
+
export interface IColorSchemeProviderProps {
|
|
178
|
+
/**
|
|
179
|
+
* Sets the initial color scheme and provides `localStorage` persistence (see
|
|
180
|
+
* the `useColorScheme` hook). A user's stored preference overrides this
|
|
181
|
+
* value.
|
|
182
|
+
*/
|
|
183
|
+
initialColorScheme?: ColorScheme;
|
|
184
|
+
/**
|
|
185
|
+
* Specifies the key used to store the user's preferred color scheme in
|
|
186
|
+
* `localStorage`
|
|
187
|
+
*/
|
|
188
|
+
colorSchemeKey?: string;
|
|
189
|
+
}
|
|
168
190
|
export interface IThemeProviderProps extends Partial<ThemeProviderProps<IGardenTheme>> {
|
|
169
191
|
/**
|
|
170
192
|
* Provides values for component styling. See styled-components
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Provides the current color scheme for the context `ThemeProvider`.
|
|
9
|
+
*
|
|
10
|
+
* @returns {object} Current color scheme accessor and mutator.
|
|
11
|
+
*/
|
|
12
|
+
export declare const useColorScheme: () => import("..").IColorSchemeContext;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zendeskgarden/react-theming",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.5.0",
|
|
4
4
|
"description": "Theming utilities and components within the Garden Design System",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Zendesk Garden <garden@zendesk.com>",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
49
|
"zendeskgarden:src": "src/index.ts",
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "43546784a9aa985332ddcc6dd09209a11e2c03ff"
|
|
51
51
|
}
|