Skip to content

Commit b5d206e

Browse files
authored
feat(theming): allow null color scheme key to bypass ColorSchemeProvider local storage (#2032)
1 parent d493e50 commit b5d206e

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

packages/theming/demo/stories/ColorSchemeProviderStory.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ const Content = ({
5757
};
5858

5959
const handleClear = () => {
60-
localStorage?.removeItem(colorSchemeKey);
60+
localStorage?.removeItem(colorSchemeKey!);
6161
setInputValue('');
6262
};
6363

6464
useEffect(() => {
65-
setInputValue(localStorage?.getItem(colorSchemeKey) || '');
65+
setInputValue(localStorage?.getItem(colorSchemeKey!) || '');
6666
}, [colorSchemeKey, colorScheme, isSystem, localStorage]);
6767

6868
return (
@@ -75,7 +75,12 @@ const Content = ({
7575
<Field.Label>
7676
Local {!!colorSchemeKey && <Code>{colorSchemeKey}</Code>} storage
7777
</Field.Label>
78-
<Input placeholder="unspecified" readOnly value={inputValue} />
78+
<Input
79+
disabled={colorSchemeKey === null ? true : undefined}
80+
placeholder={colorSchemeKey === null ? 'unused' : 'unspecified'}
81+
readOnly
82+
value={inputValue}
83+
/>
7984
{!!inputValue && (
8085
<Tooltip content={`Clear ${colorSchemeKey} storage`}>
8186
<StyledIconButton focusInset onClick={handleClear} size="small">
@@ -98,7 +103,7 @@ const Content = ({
98103
placement="bottom-end"
99104
selectedItems={[{ value: isSystem ? 'system' : colorScheme }]}
100105
>
101-
<ItemGroup type="radio">
106+
<ItemGroup aria-label="appearance" type="radio">
102107
<Item icon={<LightIcon />} value="light">
103108
Light
104109
</Item>

packages/theming/src/elements/ColorSchemeProvider.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ import {
2424
const mediaQuery =
2525
typeof window === 'undefined' ? undefined : window.matchMedia('(prefers-color-scheme: dark)');
2626

27-
const useColorScheme = (initialState: ColorScheme, colorSchemeKey: string) => {
28-
/* eslint-disable-next-line n/no-unsupported-features/node-builtins */
29-
const localStorage = typeof window === 'undefined' ? undefined : window.localStorage;
27+
const useColorScheme = (
28+
initialState: ColorScheme,
29+
colorSchemeKey: IColorSchemeProviderProps['colorSchemeKey']
30+
) => {
31+
const localStorage =
32+
/* eslint-disable-next-line n/no-unsupported-features/node-builtins */
33+
typeof window === 'undefined' || colorSchemeKey === null ? undefined : window.localStorage;
3034

3135
const getState = useCallback((_state?: ColorScheme | null) => {
3236
const isSystem = _state === 'system' || _state === undefined || _state === null;
@@ -44,14 +48,14 @@ const useColorScheme = (initialState: ColorScheme, colorSchemeKey: string) => {
4448
const [state, setState] = useState<{
4549
isSystem: boolean;
4650
colorScheme: IGardenTheme['colors']['base'];
47-
}>(getState((localStorage?.getItem(colorSchemeKey) as ColorScheme) || initialState));
51+
}>(getState((localStorage?.getItem(colorSchemeKey!) as ColorScheme) || initialState));
4852

4953
return {
5054
isSystem: state.isSystem,
5155
colorScheme: state.colorScheme,
5256
setColorScheme: (colorScheme: ColorScheme) => {
5357
setState(getState(colorScheme));
54-
localStorage?.setItem(colorSchemeKey, colorScheme);
58+
localStorage?.setItem(colorSchemeKey!, colorScheme);
5559
}
5660
};
5761
};

packages/theming/src/types/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ export interface IColorSchemeProviderProps {
226226
initialColorScheme?: ColorScheme;
227227
/**
228228
* Specifies the key used to store the user's preferred color scheme in
229-
* `localStorage`
229+
* `localStorage` or `null` to bypass local storage persistence
230230
*/
231-
colorSchemeKey?: string;
231+
colorSchemeKey?: string | null;
232232
}
233233

234234
export interface IThemeProviderProps extends Partial<ThemeProviderProps<IGardenTheme>> {

packages/theming/src/utils/useColorScheme.spec.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ describe('useColorScheme', () => {
3737
});
3838
});
3939

40+
it('bypasses localStorage as expected', () => {
41+
const Test = () => (
42+
<ColorSchemeProvider colorSchemeKey={null}>
43+
<ColorSchemeConsumer />
44+
</ColorSchemeProvider>
45+
);
46+
47+
expect(() => {
48+
render(<Test />);
49+
}).not.toThrow();
50+
51+
/* eslint-disable-next-line n/no-unsupported-features/node-builtins */
52+
expect(window.localStorage.getItem('color-scheme')).toBeNull();
53+
});
54+
4055
it('sets the color scheme as expected', () => {
4156
const Test = () => (
4257
<ColorSchemeProvider initialColorScheme="light">

0 commit comments

Comments
 (0)