Merge pull request #1627 from github/koesie10/storybook-vscode-theme-addon

Create Storybook add-on for switching VSCode themes
This commit is contained in:
Koen Vlaswinkel
2022-10-21 10:53:14 +02:00
committed by GitHub
12 changed files with 162 additions and 60 deletions

View File

@@ -8,7 +8,8 @@ const config: StorybookConfig = {
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions'
'@storybook/addon-interactions',
'./vscode-theme-addon/preset.ts',
],
framework: '@storybook/react',
core: {

View File

@@ -4,8 +4,6 @@ import { action } from '@storybook/addon-actions';
// Allow all stories/components to use Codicons
import '@vscode/codicons/dist/codicon.css';
import '../src/stories/vscode-theme-dark.css';
// https://storybook.js.org/docs/react/configure/overview#configure-story-rendering
export const parameters = {
// All props starting with `on` will automatically receive an action as a prop
@@ -22,13 +20,8 @@ export const parameters = {
theme: themes.dark,
},
backgrounds: {
default: 'dark',
values: [
{
name: 'dark',
value: '#1e1e1e',
},
],
// The background is injected by our theme CSS files
disable: true,
}
};

View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "node",
"target": "es6",
"outDir": "out",
"lib": ["ES2021", "dom"],
"jsx": "react",
"sourceMap": true,
"rootDir": "..",
"strict": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true,
"skipLibCheck": true
},
"exclude": ["node_modules"]
}

View File

@@ -0,0 +1,49 @@
import * as React from 'react';
import { FunctionComponent, useCallback } from 'react';
import { useGlobals } from '@storybook/api';
import { IconButton, Icons, WithTooltip, TooltipLinkList, Link, WithHideFn } from '@storybook/components';
import { themeNames, VSCodeTheme } from './theme';
export const ThemeSelector: FunctionComponent = () => {
const [{ vscodeTheme }, updateGlobals] = useGlobals();
const changeTheme = useCallback((theme: VSCodeTheme) => {
updateGlobals({
vscodeTheme: theme,
});
}, [updateGlobals]);
const createLinks = useCallback((onHide: () => void): Link[] => Object.values(VSCodeTheme).map((theme) => ({
id: theme,
onClick() {
changeTheme(theme);
onHide();
},
title: themeNames[theme],
value: theme,
active: vscodeTheme === theme,
})), [vscodeTheme, changeTheme]);
return (
<WithTooltip
placement="top"
trigger="click"
closeOnClick
tooltip={({ onHide }: WithHideFn) => (
<TooltipLinkList
links={createLinks(onHide)}
/>
)}
>
<IconButton
key="theme"
title="Change the theme of the preview"
active={vscodeTheme !== VSCodeTheme.Dark}
>
<Icons icon="dashboard" />
</IconButton>
</WithTooltip>
);
};

View File

@@ -0,0 +1,14 @@
import * as React from 'react';
import { addons, types } from '@storybook/addons';
import { ThemeSelector } from './ThemeSelector';
const ADDON_ID = 'vscode-theme-addon';
addons.register(ADDON_ID, () => {
addons.add(ADDON_ID, {
title: 'VSCode Themes',
type: types.TOOL,
match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
render: () => <ThemeSelector />,
});
});

View File

@@ -0,0 +1,7 @@
export function config(entry = []) {
return [...entry, require.resolve("./preview.ts")];
}
export function managerEntries(entry = []) {
return [...entry, require.resolve("./manager.tsx")];
}

View File

@@ -0,0 +1,8 @@
import { withTheme } from './withTheme';
import { VSCodeTheme } from './theme';
export const decorators = [withTheme];
export const globals = {
vscodeTheme: VSCodeTheme.Dark,
};

View File

@@ -0,0 +1,9 @@
export enum VSCodeTheme {
Dark = 'dark',
Light = 'light',
}
export const themeNames: { [key in VSCodeTheme]: string } = {
[VSCodeTheme.Dark]: 'Dark+',
[VSCodeTheme.Light]: 'Light+',
}

View File

@@ -0,0 +1,36 @@
import { useEffect, useGlobals } from '@storybook/addons';
import type { AnyFramework, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/csf';
import { VSCodeTheme } from './theme';
const themeFiles: { [key in VSCodeTheme]: string } = {
[VSCodeTheme.Dark]: require('!file-loader?modules!../../src/stories/vscode-theme-dark.css').default,
[VSCodeTheme.Light]: require('!file-loader?modules!../../src/stories/vscode-theme-light.css').default,
}
export const withTheme = (
StoryFn: StoryFunction<AnyFramework>,
context: StoryContext<AnyFramework>
) => {
const [{ vscodeTheme }] = useGlobals();
useEffect(() => {
const styleSelectorId =
context.viewMode === 'docs'
? `addon-vscode-theme-docs-${context.id}`
: `addon-vscode-theme-theme`;
const theme = Object.values(VSCodeTheme).includes(vscodeTheme) ? vscodeTheme as VSCodeTheme : VSCodeTheme.Dark;
document.getElementById(styleSelectorId)?.remove();
const link = document.createElement('link');
link.id = styleSelectorId;
link.href = themeFiles[theme];
link.rel = 'stylesheet';
document.head.appendChild(link);
}, [vscodeTheme]);
return StoryFn();
};

View File

@@ -12,56 +12,8 @@ Welcome to the Storybook for **CodeQL for Visual Studio Code**! This Storybook c
### Switching themes
To switch between VSCode Dark+ and Light+ themes, you can make the following changes:
```diff
diff --git a/extensions/ql-vscode/.storybook/manager.ts b/extensions/ql-vscode/.storybook/manager.ts
--- a/extensions/ql-vscode/.storybook/manager.ts
+++ b/extensions/ql-vscode/.storybook/manager.ts
@@ -2,6 +2,6 @@ import { addons } from '@storybook/addons';
import { themes } from '@storybook/theming';
addons.setConfig({
- theme: themes.dark,
+ theme: themes.light,
enableShortcuts: false,
});
diff --git a/extensions/ql-vscode/.storybook/preview.ts b/extensions/ql-vscode/.storybook/preview.ts
--- a/extensions/ql-vscode/.storybook/preview.ts
+++ b/extensions/ql-vscode/.storybook/preview.ts
@@ -4,7 +4,7 @@ import { action } from '@storybook/addon-actions';
// Allow all stories/components to use Codicons
import '@vscode/codicons/dist/codicon.css';
-import '../src/stories/vscode-theme-dark.css';
+import '../src/stories/vscode-theme-light.css';
// https://storybook.js.org/docs/react/configure/overview#configure-story-rendering
export const parameters = {
@@ -19,14 +19,14 @@ export const parameters = {
},
- // Use a dark theme to be aligned with VSCode
+ // Use a light theme to be aligned with VSCode
docs: {
- theme: themes.dark,
+ theme: themes.light,
},
backgrounds: {
- default: 'dark',
+ default: 'light',
values: [
{
- name: 'dark',
- value: '#1e1e1e',
+ name: 'light',
+ value: '#ffffff',
},
],
}
```
You will need to restart Storybook to apply the theme change to the Storybook UI. The preview frame should update
automatically.
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
the changes applied to a different story.
### Writing stories

View File

@@ -628,3 +628,10 @@ body {
margin: 0;
padding: 0 20px;
}
/**
* This is used for setting the background on the Storybook preview.
*/
body {
background-color: var(--vscode-editor-background);
}

View File

@@ -626,3 +626,10 @@ body {
margin: 0;
padding: 0 20px;
}
/**
* This is used for setting the background on the Storybook preview.
*/
body {
background-color: var(--vscode-editor-background);
}