Skip to content

Commit aec25ed

Browse files
inomdzhonSevereCloud
authored andcommitted
fix(storybook): migrate to v9 (#9860)
* fix(storybook): migrate to v9 - Прошелся по предупреждениям в консоли. - Исправил, что сбрасывался локальный `colorScheme`, указанный в query-параметре при перезагрузке из-за `StorybookTheme`. - Удалил наш `addons/source-tab` в пользу нативной `parameters.docs.codePanel`. * fix(storybook/HasPointer): update typo Co-authored-by: Daniil Suvorov <severecloud@gmail.com> --------- Co-authored-by: Daniil Suvorov <severecloud@gmail.com>
1 parent eeb84cb commit aec25ed

14 files changed

Lines changed: 141 additions & 124 deletions

File tree

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,44 @@
11
import * as React from 'react';
2-
import { Icon16Moon, Icon16Sun } from '@vkontakte/icons';
2+
import { SunIcon, MoonIcon } from '@storybook/icons';
33
import { useGlobals } from 'storybook/manager-api';
4-
import { IconButton } from 'storybook/internal/components';
4+
import { Select } from 'storybook/internal/components';
55
import { PARAM_KEY } from './constants';
66

77
export const ColorSchemeSwitch = () => {
88
const [globals, updateGlobals] = useGlobals();
9-
const isDarkTheme = globals[PARAM_KEY] === 'dark';
9+
const selectedOption = globals[PARAM_KEY];
1010

11-
const toggleTheme = React.useCallback(() => {
12-
updateGlobals({ [PARAM_KEY]: isDarkTheme ? 'light' : 'dark' });
13-
}, [isDarkTheme, updateGlobals]);
11+
const handleChange: React.ComponentProps<typeof Select>['onChange'] = React.useCallback(
12+
(selected) => {
13+
updateGlobals({ [PARAM_KEY]: selected[0] });
14+
},
15+
[updateGlobals],
16+
);
1417

15-
const title = isDarkTheme ? 'Turn the light theme' : 'Turn the dark theme';
18+
if (selectedOption === undefined) {
19+
return null;
20+
}
1621

1722
return (
18-
<IconButton active key="theme" onClick={toggleTheme} title={title}>
19-
{isDarkTheme ? <Icon16Sun /> : <Icon16Moon />}
20-
&nbsp;
21-
{globals[PARAM_KEY]}
22-
</IconButton>
23+
<Select
24+
key="theme"
25+
size="small"
26+
ariaLabel="Choose theme"
27+
icon={selectedOption === 'dark' ? <MoonIcon /> : <SunIcon />}
28+
defaultOptions={selectedOption}
29+
options={[
30+
{
31+
icon: <SunIcon />,
32+
title: 'light',
33+
value: 'light',
34+
},
35+
{
36+
icon: <MoonIcon />,
37+
title: 'dark',
38+
value: 'dark',
39+
},
40+
]}
41+
onChange={handleChange}
42+
/>
2343
);
2444
};
Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
import * as React from 'react';
22
import { useGlobals } from 'storybook/manager-api';
3-
import { IconButton } from 'storybook/internal/components';
3+
import { ToggleButton } from 'storybook/internal/components';
44
import { BrowserIcon } from '@storybook/icons';
55
import { PARAM_KEY } from './constants';
66

77
export const HasCustomPanelHeaderAfter = () => {
88
const [globals, updateGlobals] = useGlobals();
9-
const active = globals[PARAM_KEY];
9+
const hasCustomPanelHeaderAfter = globals[PARAM_KEY];
1010

1111
const toggle = React.useCallback(() => {
12-
updateGlobals({ [PARAM_KEY]: !active });
13-
}, [updateGlobals, active]);
12+
updateGlobals({ [PARAM_KEY]: !hasCustomPanelHeaderAfter });
13+
}, [updateGlobals, hasCustomPanelHeaderAfter]);
14+
15+
if (hasCustomPanelHeaderAfter === undefined) {
16+
return null;
17+
}
1418

1519
return (
16-
<IconButton active={active} key="customPanelHeaderAfter" onClick={toggle}>
20+
<ToggleButton
21+
key="customPanelHeaderAfter"
22+
pressed={hasCustomPanelHeaderAfter}
23+
size="small"
24+
variant="ghost"
25+
ariaLabel={`hasCustomPanelHeaderAfter property is turned ${hasCustomPanelHeaderAfter ? 'on' : 'off'}`}
26+
onClick={toggle}
27+
>
1728
<BrowserIcon />
18-
&nbsp; hasCustomPanelHeaderAfter
19-
</IconButton>
29+
&nbsp;hasCustomPanelHeaderAfter
30+
</ToggleButton>
2031
);
2132
};

packages/vkui/.storybook/addons/documentation-button/DocumentationButton.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IconButton } from 'storybook/internal/components';
1+
import { Button, Link } from 'storybook/internal/components';
22
import { useStorybookState, useGlobals } from 'storybook/manager-api';
33
import { DocumentIcon } from '@storybook/icons';
44
import * as React from 'react';
@@ -67,10 +67,10 @@ export const DocumentationButton = () => {
6767
const documentationUrl = getComponentUrl(componentName, parent, docsBaseUrl);
6868

6969
return (
70-
<a href={documentationUrl} target="_blank" rel="noreferrer">
71-
<IconButton>
70+
<Button asChild size="small" variant="ghost" ariaLabel="Open documentation">
71+
<a href={documentationUrl} target="_blank" rel="noreferrer">
7272
<DocumentIcon />
73-
</IconButton>
74-
</a>
73+
</a>
74+
</Button>
7575
);
7676
};
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import { useGlobals } from 'storybook/manager-api';
3-
import { IconButton } from 'storybook/internal/components';
3+
import { ToggleButton } from 'storybook/internal/components';
44
import { ButtonIcon } from '@storybook/icons';
55
import { PARAM_KEY } from './constants';
66

@@ -12,11 +12,21 @@ export const HasPointer = () => {
1212
updateGlobals({ [PARAM_KEY]: !hasPointer });
1313
}, [updateGlobals, hasPointer]);
1414

15+
if (hasPointer === undefined) {
16+
return null;
17+
}
18+
1519
return (
16-
<IconButton active={hasPointer} key="pointer" onClick={toggleHasPointer}>
20+
<ToggleButton
21+
key="pointer"
22+
pressed={hasPointer}
23+
size="small"
24+
variant="ghost"
25+
ariaLabel={`hasPointer property is turned ${hasPointer ? 'on' : 'off'}`}
26+
onClick={toggleHasPointer}
27+
>
1728
<ButtonIcon />
18-
&nbsp;
19-
{`${hasPointer ? '' : 'no '}pointer`}
20-
</IconButton>
29+
&nbsp;hasPointer
30+
</ToggleButton>
2131
);
2232
};

packages/vkui/.storybook/addons/source-button/SourceButton.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IconButton } from 'storybook/internal/components';
1+
import { Button } from 'storybook/internal/components';
22
import { useGlobals, useStorybookState } from 'storybook/manager-api';
33
import { GithubIcon } from '@storybook/icons';
44
import * as React from 'react';
@@ -28,10 +28,10 @@ export const SourceButton = () => {
2828
const sourceUrl = getComponentUrl(globals.componentsSourceBaseUrl, importPath);
2929

3030
return (
31-
<a href={sourceUrl} target="_blank" rel="noreferrer">
32-
<IconButton>
31+
<Button asChild size="small" variant="ghost" ariaLabel="Open source on GitHub">
32+
<a href={sourceUrl} target="_blank" rel="noreferrer">
3333
<GithubIcon />
34-
</IconButton>
35-
</a>
34+
</a>
35+
</Button>
3636
);
3737
};

packages/vkui/.storybook/addons/source-tab/SourceTab.tsx

Lines changed: 0 additions & 41 deletions
This file was deleted.

packages/vkui/.storybook/addons/source-tab/constants.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/vkui/.storybook/addons/source-tab/preset.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/vkui/.storybook/addons/source-tab/register.tsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

packages/vkui/.storybook/addons/storybook-theme/StorybookTheme.tsx

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import * as React from 'react';
22
import { useGlobals, addons, useStorybookApi } from 'storybook/manager-api';
33
import { styled } from 'storybook/theming';
44
import { SET_GLOBALS } from 'storybook/internal/core-events';
5-
import { IconButton } from 'storybook/internal/components';
5+
import { Select } from 'storybook/internal/components';
66
import { SunIcon, MoonIcon } from '@storybook/icons';
77
import { PARAM_KEY, SET_STORYBOOK_THEME } from './constants';
88
import { vkuiDarkTheme, vkuiLightTheme } from './vkuiThemes';
99

10-
const SidebarIconButton = styled(IconButton)(({ theme }) => ({
10+
const SidebarSelect = styled(Select)(({ theme }) => ({
1111
position: 'relative',
1212
overflow: 'visible',
1313
color: theme.textMutedColor,
@@ -19,48 +19,80 @@ const STORAGE_KEY = 'sb-dark-theme';
1919

2020
const channel = addons.getChannel();
2121

22+
type Theme = 'light' | 'dark';
23+
2224
export const getLocalStorageValue = () => {
2325
return window.localStorage.getItem(STORAGE_KEY);
2426
};
2527

26-
export const updateLocalStorageValue = (theme: 'light' | 'dark') => {
28+
export const updateLocalStorageValue = (theme: Theme) => {
2729
window.localStorage.setItem(STORAGE_KEY, theme);
2830
};
2931

3032
export const StorybookTheme = () => {
3133
const [globals, updateGlobals] = useGlobals();
3234
const { once } = useStorybookApi();
33-
const currentTheme = globals[PARAM_KEY];
34-
const isCurrentThemeDark = currentTheme === 'dark';
35-
const nextTheme = isCurrentThemeDark ? 'light' : 'dark';
35+
const selectedGlobalTheme = globals[PARAM_KEY];
3636

37-
const updateTheme = (themeProp: 'light' | 'dark') => {
38-
channel.emit(SET_STORYBOOK_THEME, themeProp);
39-
updateGlobals({ [PARAM_KEY]: themeProp, colorScheme: themeProp });
40-
updateLocalStorageValue(themeProp);
41-
};
37+
const updateTheme = React.useCallback(
38+
(globalTheme: Theme, localTheme?: Theme) => {
39+
channel.emit(SET_STORYBOOK_THEME, globalTheme);
40+
updateGlobals(
41+
localTheme
42+
? { [PARAM_KEY]: globalTheme, colorScheme: localTheme }
43+
: { [PARAM_KEY]: globalTheme },
44+
);
45+
updateLocalStorageValue(globalTheme);
46+
},
47+
[updateGlobals],
48+
);
4249

43-
const toggleTheme = React.useCallback(() => {
44-
addons.setConfig({ theme: nextTheme === 'dark' ? vkuiDarkTheme : vkuiLightTheme });
45-
updateTheme(nextTheme);
46-
}, [nextTheme, updateGlobals]);
50+
const handleChange: React.ComponentProps<typeof Select>['onChange'] = React.useCallback(
51+
(selectedOptionRaw) => {
52+
const selectedOption = selectedOptionRaw[0] as Theme;
53+
addons.setConfig({ theme: selectedOption === 'dark' ? vkuiDarkTheme : vkuiLightTheme });
54+
updateTheme(selectedOption, selectedOption);
55+
},
56+
[updateTheme],
57+
);
4758

4859
React.useEffect(() => {
4960
const { theme } = addons.getConfig();
50-
const themeNotMatched = theme && theme.base !== currentTheme;
61+
const themeNotMatched = theme && theme.base !== selectedGlobalTheme;
5162

5263
once(SET_GLOBALS, () => {
5364
if (themeNotMatched) {
5465
updateTheme(theme.base);
5566
}
5667
});
57-
}, []);
68+
}, [once, updateTheme]);
5869

59-
const title = isCurrentThemeDark ? 'Turn the light theme' : 'Turn the dark theme';
70+
if (selectedGlobalTheme === undefined) {
71+
return null;
72+
}
6073

6174
return (
62-
<SidebarIconButton key="sb-dark-theme" onClick={toggleTheme} title={title}>
63-
{isCurrentThemeDark ? <SunIcon /> : <MoonIcon />}
64-
</SidebarIconButton>
75+
<SidebarSelect
76+
key="sb-dark-theme"
77+
size="small"
78+
ariaLabel="Choose global theme"
79+
icon={selectedGlobalTheme === 'dark' ? <MoonIcon /> : <SunIcon />}
80+
defaultOptions={selectedGlobalTheme}
81+
options={[
82+
{
83+
icon: <SunIcon />,
84+
title: 'light (global)',
85+
value: 'light',
86+
},
87+
{
88+
icon: <MoonIcon />,
89+
title: 'dark (global)',
90+
value: 'dark',
91+
},
92+
]}
93+
onChange={handleChange}
94+
>
95+
{`${selectedGlobalTheme} (global)`}
96+
</SidebarSelect>
6597
);
6698
};

0 commit comments

Comments
 (0)