Skip to content

Commit a13a1e0

Browse files
committed
Restructure to expose ColorSchemeProvider for consumer use
1 parent 38e00df commit a13a1e0

10 files changed

+257
-278
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Meta, ArgsTable, Canvas, Story, Markdown } from '@storybook/addon-docs';
2+
import { ColorSchemeProvider } from '@zendeskgarden/react-theming';
3+
import { ColorSchemeProviderStory } from './stories/ColorSchemeProviderStory';
4+
import README from '../README.md';
5+
6+
<Meta title="Packages/Theming/ColorSchemeProvider" component={ColorSchemeProvider} />
7+
8+
# API
9+
10+
<ArgsTable />
11+
12+
# Demo
13+
14+
## ColorSchemeProvider
15+
16+
<Canvas>
17+
<Story name="ColorSchemeProvider" args={{ initialColorScheme: 'system' }}>
18+
{args => <ColorSchemeProviderStory {...args} />}
19+
</Story>
20+
</Canvas>
21+
22+
<Markdown>{README}</Markdown>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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+
import React, { useEffect, useState } from 'react';
9+
import styled, { ThemeProvider, useTheme } from 'styled-components';
10+
import { StoryFn } from '@storybook/react';
11+
import ClearIcon from '@zendeskgarden/svg-icons/src/16/x-stroke.svg';
12+
import DarkIcon from '@zendeskgarden/svg-icons/src/16/moon-stroke.svg';
13+
import LightIcon from '@zendeskgarden/svg-icons/src/16/sun-stroke.svg';
14+
import SystemIcon from '@zendeskgarden/svg-icons/src/16/monitor-stroke.svg';
15+
import {
16+
ColorScheme,
17+
ColorSchemeProvider,
18+
getColor,
19+
IColorSchemeProviderProps,
20+
IGardenTheme,
21+
useColorScheme,
22+
useWindow
23+
} from '@zendeskgarden/react-theming';
24+
import { Grid } from '@zendeskgarden/react-grid';
25+
import { IconButton } from '@zendeskgarden/react-buttons';
26+
import { IMenuProps, Item, ItemGroup, Menu } from '@zendeskgarden/react-dropdowns';
27+
import { Field, Input } from '@zendeskgarden/react-forms';
28+
import { Code } from '@zendeskgarden/react-typography';
29+
import { Tooltip } from '@zendeskgarden/react-tooltips';
30+
31+
const StyledGrid = styled(Grid)`
32+
background-color: ${p => getColor({ theme: p.theme, variable: 'background.default' })};
33+
`;
34+
35+
const StyledIconButton = styled(IconButton)`
36+
position: absolute;
37+
right: ${p => p.theme.space.base * 3}px;
38+
bottom: ${p => p.theme.space.base}px;
39+
`;
40+
41+
const Content = ({
42+
colorSchemeKey = 'color-scheme'
43+
}: {
44+
colorSchemeKey: IColorSchemeProviderProps['colorSchemeKey'];
45+
}) => {
46+
const win = useWindow();
47+
const localStorage = win?.localStorage;
48+
const { colorScheme, isSystem, setColorScheme } = useColorScheme();
49+
const [inputValue, setInputValue] = useState('');
50+
const _theme = useTheme() as IGardenTheme;
51+
const theme = { ..._theme, colors: { ..._theme.colors, base: colorScheme } };
52+
53+
const handleChange: IMenuProps['onChange'] = changes => {
54+
if (changes.value) {
55+
setColorScheme(changes.value as ColorScheme);
56+
}
57+
};
58+
59+
const handleClear = () => {
60+
localStorage?.removeItem(colorSchemeKey);
61+
setInputValue('');
62+
};
63+
64+
useEffect(() => {
65+
setInputValue(localStorage?.getItem(colorSchemeKey) || '');
66+
}, [colorSchemeKey, colorScheme, isSystem, localStorage]);
67+
68+
return (
69+
<ThemeProvider theme={theme}>
70+
<StyledGrid gutters="xl">
71+
<Grid.Row style={{ height: 'calc(100vh - 80px)' }}>
72+
<Grid.Col alignSelf="center" sm={5}>
73+
<div style={{ position: 'relative' }}>
74+
<Field>
75+
<Field.Label>
76+
Local {!!colorSchemeKey && <Code>{colorSchemeKey}</Code>} storage
77+
</Field.Label>
78+
<Input placeholder="unspecified" readOnly value={inputValue} />
79+
{!!inputValue && (
80+
<Tooltip content={`Clear ${colorSchemeKey} storage`}>
81+
<StyledIconButton focusInset onClick={handleClear} size="small">
82+
<ClearIcon />
83+
</StyledIconButton>
84+
</Tooltip>
85+
)}
86+
</Field>
87+
</div>
88+
</Grid.Col>
89+
<Grid.Col textAlign="center" alignSelf="center">
90+
<Menu
91+
/* eslint-disable-next-line react/no-unstable-nested-components */
92+
button={props => (
93+
<IconButton {...props}>
94+
{theme.colors.base === 'dark' ? <DarkIcon /> : <LightIcon />}
95+
</IconButton>
96+
)}
97+
onChange={handleChange}
98+
placement="bottom-end"
99+
selectedItems={[{ value: isSystem ? 'system' : colorScheme }]}
100+
>
101+
<ItemGroup type="radio">
102+
<Item icon={<LightIcon />} value="light">
103+
Light
104+
</Item>
105+
<Item icon={<DarkIcon />} value="dark">
106+
Dark
107+
</Item>
108+
<Item icon={<SystemIcon />} isSelected value="system">
109+
System
110+
</Item>
111+
</ItemGroup>
112+
</Menu>
113+
</Grid.Col>
114+
</Grid.Row>
115+
</StyledGrid>
116+
</ThemeProvider>
117+
);
118+
};
119+
120+
export const ColorSchemeProviderStory: StoryFn<IColorSchemeProviderProps> = ({
121+
colorSchemeKey,
122+
initialColorScheme
123+
}) => (
124+
<ColorSchemeProvider
125+
key={initialColorScheme}
126+
colorSchemeKey={colorSchemeKey}
127+
initialColorScheme={initialColorScheme}
128+
>
129+
<Content colorSchemeKey={colorSchemeKey} />
130+
</ColorSchemeProvider>
131+
);

packages/theming/demo/stories/ThemeProviderStory.tsx

-133
This file was deleted.

packages/theming/demo/themeProvider.stories.mdx

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Meta, ArgsTable, Canvas, Story, Markdown } from '@storybook/addon-docs';
22
import { ThemeProvider, DEFAULT_THEME, PALETTE } from '@zendeskgarden/react-theming';
3-
import { ThemeProviderStory } from './stories/ThemeProviderStory';
43
import { PaletteStory } from './stories/PaletteStory';
54
import README from '../README.md';
65

@@ -19,12 +18,8 @@ import README from '../README.md';
1918
## ThemeProvider
2019

2120
<Canvas>
22-
<Story
23-
name="ThemeProvider"
24-
args={{ initialColorScheme: 'system' }}
25-
argTypes={{ theme: { control: false } }}
26-
>
27-
{args => <ThemeProviderStory {...args} />}
21+
<Story name="ThemeProvider" args={{ theme: DEFAULT_THEME }}>
22+
{args => <ThemeProvider {...args} />}
2823
</Story>
2924
</Canvas>
3025

0 commit comments

Comments
 (0)