Skip to content

Commit 9ba06ef

Browse files
authored
Merge pull request #1627 from github/koesie10/storybook-vscode-theme-addon
Create Storybook add-on for switching VSCode themes
2 parents a625a39 + a254cea commit 9ba06ef

File tree

12 files changed

+162
-60
lines changed

12 files changed

+162
-60
lines changed

extensions/ql-vscode/.storybook/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const config: StorybookConfig = {
88
addons: [
99
'@storybook/addon-links',
1010
'@storybook/addon-essentials',
11-
'@storybook/addon-interactions'
11+
'@storybook/addon-interactions',
12+
'./vscode-theme-addon/preset.ts',
1213
],
1314
framework: '@storybook/react',
1415
core: {

extensions/ql-vscode/.storybook/preview.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { action } from '@storybook/addon-actions';
44
// Allow all stories/components to use Codicons
55
import '@vscode/codicons/dist/codicon.css';
66

7-
import '../src/stories/vscode-theme-dark.css';
8-
97
// https://storybook.js.org/docs/react/configure/overview#configure-story-rendering
108
export const parameters = {
119
// All props starting with `on` will automatically receive an action as a prop
@@ -22,13 +20,8 @@ export const parameters = {
2220
theme: themes.dark,
2321
},
2422
backgrounds: {
25-
default: 'dark',
26-
values: [
27-
{
28-
name: 'dark',
29-
value: '#1e1e1e',
30-
},
31-
],
23+
// The background is injected by our theme CSS files
24+
disable: true,
3225
}
3326
};
3427

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"compilerOptions": {
3+
"module": "esnext",
4+
"moduleResolution": "node",
5+
"target": "es6",
6+
"outDir": "out",
7+
"lib": ["ES2021", "dom"],
8+
"jsx": "react",
9+
"sourceMap": true,
10+
"rootDir": "..",
11+
"strict": true,
12+
"noUnusedLocals": true,
13+
"noImplicitReturns": true,
14+
"noFallthroughCasesInSwitch": true,
15+
"experimentalDecorators": true,
16+
"skipLibCheck": true
17+
},
18+
"exclude": ["node_modules"]
19+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as React from 'react';
2+
import { FunctionComponent, useCallback } from 'react';
3+
4+
import { useGlobals } from '@storybook/api';
5+
import { IconButton, Icons, WithTooltip, TooltipLinkList, Link, WithHideFn } from '@storybook/components';
6+
7+
import { themeNames, VSCodeTheme } from './theme';
8+
9+
export const ThemeSelector: FunctionComponent = () => {
10+
const [{ vscodeTheme }, updateGlobals] = useGlobals();
11+
12+
const changeTheme = useCallback((theme: VSCodeTheme) => {
13+
updateGlobals({
14+
vscodeTheme: theme,
15+
});
16+
}, [updateGlobals]);
17+
18+
const createLinks = useCallback((onHide: () => void): Link[] => Object.values(VSCodeTheme).map((theme) => ({
19+
id: theme,
20+
onClick() {
21+
changeTheme(theme);
22+
onHide();
23+
},
24+
title: themeNames[theme],
25+
value: theme,
26+
active: vscodeTheme === theme,
27+
})), [vscodeTheme, changeTheme]);
28+
29+
return (
30+
<WithTooltip
31+
placement="top"
32+
trigger="click"
33+
closeOnClick
34+
tooltip={({ onHide }: WithHideFn) => (
35+
<TooltipLinkList
36+
links={createLinks(onHide)}
37+
/>
38+
)}
39+
>
40+
<IconButton
41+
key="theme"
42+
title="Change the theme of the preview"
43+
active={vscodeTheme !== VSCodeTheme.Dark}
44+
>
45+
<Icons icon="dashboard" />
46+
</IconButton>
47+
</WithTooltip>
48+
);
49+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as React from 'react';
2+
import { addons, types } from '@storybook/addons';
3+
import { ThemeSelector } from './ThemeSelector';
4+
5+
const ADDON_ID = 'vscode-theme-addon';
6+
7+
addons.register(ADDON_ID, () => {
8+
addons.add(ADDON_ID, {
9+
title: 'VSCode Themes',
10+
type: types.TOOL,
11+
match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
12+
render: () => <ThemeSelector />,
13+
});
14+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function config(entry = []) {
2+
return [...entry, require.resolve("./preview.ts")];
3+
}
4+
5+
export function managerEntries(entry = []) {
6+
return [...entry, require.resolve("./manager.tsx")];
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { withTheme } from './withTheme';
2+
import { VSCodeTheme } from './theme';
3+
4+
export const decorators = [withTheme];
5+
6+
export const globals = {
7+
vscodeTheme: VSCodeTheme.Dark,
8+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export enum VSCodeTheme {
2+
Dark = 'dark',
3+
Light = 'light',
4+
}
5+
6+
export const themeNames: { [key in VSCodeTheme]: string } = {
7+
[VSCodeTheme.Dark]: 'Dark+',
8+
[VSCodeTheme.Light]: 'Light+',
9+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useEffect, useGlobals } from '@storybook/addons';
2+
import type { AnyFramework, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/csf';
3+
4+
import { VSCodeTheme } from './theme';
5+
6+
const themeFiles: { [key in VSCodeTheme]: string } = {
7+
[VSCodeTheme.Dark]: require('!file-loader?modules!../../src/stories/vscode-theme-dark.css').default,
8+
[VSCodeTheme.Light]: require('!file-loader?modules!../../src/stories/vscode-theme-light.css').default,
9+
}
10+
11+
export const withTheme = (
12+
StoryFn: StoryFunction<AnyFramework>,
13+
context: StoryContext<AnyFramework>
14+
) => {
15+
const [{ vscodeTheme }] = useGlobals();
16+
17+
useEffect(() => {
18+
const styleSelectorId =
19+
context.viewMode === 'docs'
20+
? `addon-vscode-theme-docs-${context.id}`
21+
: `addon-vscode-theme-theme`;
22+
23+
const theme = Object.values(VSCodeTheme).includes(vscodeTheme) ? vscodeTheme as VSCodeTheme : VSCodeTheme.Dark;
24+
25+
document.getElementById(styleSelectorId)?.remove();
26+
27+
const link = document.createElement('link');
28+
link.id = styleSelectorId;
29+
link.href = themeFiles[theme];
30+
link.rel = 'stylesheet';
31+
32+
document.head.appendChild(link);
33+
}, [vscodeTheme]);
34+
35+
return StoryFn();
36+
};

extensions/ql-vscode/src/stories/Overview.stories.mdx

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -12,56 +12,8 @@ Welcome to the Storybook for **CodeQL for Visual Studio Code**! This Storybook c
1212

1313
### Switching themes
1414

15-
To switch between VSCode Dark+ and Light+ themes, you can make the following changes:
16-
17-
```diff
18-
diff --git a/extensions/ql-vscode/.storybook/manager.ts b/extensions/ql-vscode/.storybook/manager.ts
19-
--- a/extensions/ql-vscode/.storybook/manager.ts
20-
+++ b/extensions/ql-vscode/.storybook/manager.ts
21-
@@ -2,6 +2,6 @@ import { addons } from '@storybook/addons';
22-
import { themes } from '@storybook/theming';
23-
24-
addons.setConfig({
25-
- theme: themes.dark,
26-
+ theme: themes.light,
27-
enableShortcuts: false,
28-
});
29-
diff --git a/extensions/ql-vscode/.storybook/preview.ts b/extensions/ql-vscode/.storybook/preview.ts
30-
--- a/extensions/ql-vscode/.storybook/preview.ts
31-
+++ b/extensions/ql-vscode/.storybook/preview.ts
32-
@@ -4,7 +4,7 @@ import { action } from '@storybook/addon-actions';
33-
// Allow all stories/components to use Codicons
34-
import '@vscode/codicons/dist/codicon.css';
35-
36-
-import '../src/stories/vscode-theme-dark.css';
37-
+import '../src/stories/vscode-theme-light.css';
38-
39-
// https://storybook.js.org/docs/react/configure/overview#configure-story-rendering
40-
export const parameters = {
41-
@@ -19,14 +19,14 @@ export const parameters = {
42-
},
43-
- // Use a dark theme to be aligned with VSCode
44-
+ // Use a light theme to be aligned with VSCode
45-
docs: {
46-
- theme: themes.dark,
47-
+ theme: themes.light,
48-
},
49-
backgrounds: {
50-
- default: 'dark',
51-
+ default: 'light',
52-
values: [
53-
{
54-
- name: 'dark',
55-
- value: '#1e1e1e',
56-
+ name: 'light',
57-
+ value: '#ffffff',
58-
},
59-
],
60-
}
61-
```
62-
63-
You will need to restart Storybook to apply the theme change to the Storybook UI. The preview frame should update
64-
automatically.
15+
To switch between VSCode Dark+ and Light+ themes, use the button in the toolbar. This will not work on this document, so you'll only see
16+
the changes applied to a different story.
6517

6618
### Writing stories
6719

0 commit comments

Comments
 (0)