Skip to content

Commit

Permalink
Upgrade to Storybook v7 with Vite
Browse files Browse the repository at this point in the history
  • Loading branch information
jesstelford authored and gwyneplaine committed Aug 8, 2023
1 parent d85099c commit fd2767e
Show file tree
Hide file tree
Showing 15 changed files with 2,560 additions and 2,401 deletions.
5 changes: 5 additions & 0 deletions .changeset/shiny-pans-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': minor
---

Upgrade to Storybook v7 with Vite
134 changes: 134 additions & 0 deletions polaris-react/.storybook/addons/global-controls-panel/manager.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React from 'react';
import {AddonPanel, Icons, IconButton} from '@storybook/components';
import {PureArgsTable} from '@storybook/blocks';
import {addons, types} from '@storybook/manager-api';
import {styled} from '@storybook/theming';
import {useGlobals} from '@storybook/api';

addons.register('global-controls', () => {
addons.add('grid-options/panel', {
type: types.PANEL,
title: 'Grid',
match: ({viewMode}) => viewMode === 'story',
render: ({active, key}) => <GridPanel active={active} key={key} />,
});
addons.add('feature-flags/panel', {
type: types.PANEL,
title: 'Feature flags',
match: ({viewMode}) => viewMode === 'story',
render: ({active, key}) => <FeatureFlagPanel active={active} key={key} />,
});
addons.add('github/link', {
type: types.TOOLEXTRA,
title: 'GitHub',
match: ({viewMode}) => viewMode === 'story' || viewMode === 'docs',
render: GitHubToolbar,
});
});

export const featureFlagOptions = {
polarisSummerEditions2023: {
name: 'polarisSummerEditions2023',
description: 'Toggle the summer editions feature flag',
defaultValue: false,
control: {type: 'boolean'},
},
polarisSummerEditions2023ShadowBevelOptOut: {
name: 'polarisSummerEditions2023ShadowBevelOptOut',
description: 'Toggle the shadow-bevel opt out feature flag',
defaultValue: false,
control: {type: 'boolean'},
},
};

export const gridOptions = {
showGrid: {
name: 'Show grid overlay',
description: 'Show or hide a 4 / 12 column grid, overlaying components',
defaultValue: false,
control: {type: 'boolean'},
},
gridInFrame: {
name: 'Grid in frame',
description: 'Show grid within app frame context',
defaultValue: false,
control: {type: 'boolean'},
},
gridWidth: {
name: 'Grid width',
description: 'Set a max width for the grid overlay',
default: '100%',
control: {type: 'select'},
options: ['560px', '768px', '1008px', '100%'],
},
gridLayer: {
name: 'Grid layer',
description: 'Set the grid layer above or below content',
default: 'below',
control: {type: 'select'},
options: ['above', 'below'],
},
};

function GridPanel(props) {
const [globals, updateGlobals] = useGlobals();

return (
<AddonPanel {...props}>
<PureArgsTable
inAddonPanel
rows={gridOptions}
args={globals}
updateArgs={updateGlobals}
/>
</AddonPanel>
);
}

function FeatureFlagPanel(props) {
const [globals, updateGlobals] = useGlobals();
return (
<AddonPanel {...props}>
<PureArgsTable
inAddonPanel
rows={featureFlagOptions}
args={globals}
updateArgs={updateGlobals}
/>
</AddonPanel>
);
}

const IconButtonLink = styled(IconButton)({
textDecoration: 'none',
});

function GitHubToolbar() {
let link;
let title;
let buttonText;
// All of the storybook manager leverages the `@storybook/builder-manager` package, which builds with esbuild under the hood, and not vite.
// This means that we can't use the `import.meta.env` syntax to access environment variables.
// See https://github.com/storybookjs/storybook/blob/d112cbac280f23530b366918b9d54818006db963/code/builders/builder-manager/src/index.ts#L103
if (process.env.STORYBOOK_GITHUB_REPO_URL) {
link = `${process.env.STORYBOOK_GITHUB_REPO_URL}`;
title = 'View source on GitHub';
buttonText = 'GitHub';
if (process.env.STORYBOOK_GITHUB_PR) {
link = `${link}/pull/${process.env.STORYBOOK_GITHUB_PR}`;
title = `Built from PR #${process.env.STORYBOOK_GITHUB_PR}`;
buttonText = `PR #${process.env.STORYBOOK_GITHUB_PR}`;
} else if (process.env.STORYBOOK_GITHUB_SHA) {
link = `${link}/commit/${process.env.STORYBOOK_GITHUB_SHA}`;
title = `Built from commit ${process.env.STORYBOOK_GITHUB_SHA}`;
buttonText = <code>{process.env.STORYBOOK_GITHUB_SHA.slice(0, 7)}</code>;
}
}

return link ? (
<IconButtonLink as="a" href={link} title={title} target="_blank">
<Icons icon="github" />
&nbsp;{buttonText}
</IconButtonLink>
) : null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function managerEntries(entry = []) {
// Unfortunately have to do this dance for Storybook v7 to load our addon
return [...entry, require.resolve('./manager')];
}

export default {managerEntries};
85 changes: 39 additions & 46 deletions polaris-react/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
const path = require('path');
const spawn = require('child_process').spawn;
const CreateFileWebpack = require('create-file-webpack');
const postcssPlugins = require('../config/postcss-plugins');
import path from 'node:path';
import {mergeConfig} from 'vite';

module.exports = {
framework: '@storybook/react-vite',
core: {
builder: 'webpack5',
disableTelemetry: true,
},
stories: [
{
Expand All @@ -22,48 +21,42 @@ module.exports = {
'@storybook/addon-a11y',
'@storybook/addon-toolbars',
'@storybook/addon-viewport',
'./addons/global-controls-panel/preset.js',
],
webpackFinal: (config) => {
const extraRules = [
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: {
localIdentName: '[name]-[local]_[hash:base64:5]',
auto: (resourcePath) => {
return !resourcePath.includes('global');
},
},
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: postcssPlugins,
},
},
},
{
loader: 'sass-loader',
},
],
},
];

config.module.rules = [...config.module.rules, ...extraRules];
// This Vite config, is only used by Storybook, for building the preview iframe (read, the code in our stories and preview.jsx).
// This does not apply to the add-ons and any other storybook UI code.

config.resolve.alias = {
...config.resolve.alias,
'@shopify/polaris': path.resolve(__dirname, '..', 'src'),
};
return config;
// The config argument passed to viteFinakl is a merge of
// the default storybook vite config, and the config specified in our `../vite.config.js` file.
async viteFinal(config) {
console.log(config);
return mergeConfig(config, {
define: {
// We set process.env.STORYBOOK_SE23 here to normalize how we access
// process.env variables in client context.
// If we didn't then the preview.jsx file would have to access STORYBOOK_SE23 as
// import.meta.env.STORYBOOK_SE23.
'process.env.STORYBOOK_SE23':
JSON.stringify(process.env.STORYBOOK_SE23) ?? 'undefined',
},
resolve: {
alias: {
// Stories import `@shopify/polaris` so they match the actual code
// people will write. But when running in storybook, we want to use
// the actual source code (not the built code) to avoid running build
// twice (once to build Polaris, then again in storybook).
'@shopify/polaris': path.resolve(__dirname, '..', 'src'),
// Similarly, we want to link against the src version of
// polaris-patterns
'@shopify/polaris-patterns': path.resolve(
__dirname,
'..',
'..',
'polaris-patterns',
'src',
),
},
},
});
},
};
136 changes: 6 additions & 130 deletions polaris-react/.storybook/manager.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// This file is not built with vite.
// Therefore the vite config in './main.js' doesn't apply.
// All manager code is built using esbuild.
// see: https://github.com/storybookjs/storybook/blob/d112cbac280f23530b366918b9d54818006db963/code/builders/builder-manager/src/index.ts#L103
import React from 'react';
import {AddonPanel, ArgsTable, Icons, IconButton} from '@storybook/components';
import {addons, types} from '@storybook/addons';
import {useGlobals} from '@storybook/api';
import {styled, create} from '@storybook/theming';
import {create} from '@storybook/theming';
import {addons} from '@storybook/manager-api';

const colors = {
primary: '#008060',
Expand Down Expand Up @@ -49,129 +51,3 @@ addons.setConfig({
inputBorderRadius: 4,
}),
});

addons.register('polaris/global-controls', () => {
addons.add('grid/panel', {
type: types.PANEL,
title: 'Grid',
match: ({viewMode}) => viewMode === 'story',
render: ({active, key}) => <GridPanel active={active} key={key} />,
});
addons.add('provider/panel', {
type: types.PANEL,
title: 'Feature flags',
match: ({viewMode}) => viewMode === 'story',
render: ({active, key}) => <FeatureFlagPanel active={active} key={key} />,
});
addons.add('github/link', {
type: types.TOOLEXTRA,
title: 'GitHub',
match: ({viewMode}) => viewMode === 'story' || viewMode === 'docs',
render: GitHubToolbar,
});
});

export const featureFlagOptions = {
polarisSummerEditions2023: {
name: 'polarisSummerEditions2023',
description: 'Toggle the summer editions feature flag',
defaultValue: false,
control: {type: 'boolean'},
},
polarisSummerEditions2023ShadowBevelOptOut: {
name: 'polarisSummerEditions2023ShadowBevelOptOut',
description: 'Toggle the shadow-bevel opt out feature flag',
defaultValue: false,
control: {type: 'boolean'},
},
};

export const gridOptions = {
showGrid: {
name: 'Show grid overlay',
description: 'Show or hide a 4 / 12 column grid, overlaying components',
defaultValue: false,
control: {type: 'boolean'},
},
gridInFrame: {
name: 'Grid in frame',
description: 'Show grid within app frame context',
defaultValue: false,
control: {type: 'boolean'},
},
gridWidth: {
name: 'Grid width',
description: 'Set a max width for the grid overlay',
default: '100%',
control: {type: 'select'},
options: ['560px', '768px', '1008px', '100%'],
},
gridLayer: {
name: 'Grid layer',
description: 'Set the grid layer above or below content',
default: 'below',
control: {type: 'select'},
options: ['above', 'below'],
},
};

const IconButtonLink = styled(IconButton)({
textDecoration: 'none',
});

function GitHubToolbar() {
let link;
let title;
let buttonText;

if (process.env.STORYBOOK_GITHUB_REPO_URL) {
link = `${process.env.STORYBOOK_GITHUB_REPO_URL}`;
title = 'View source on GitHub';
buttonText = 'GitHub';
if (process.env.STORYBOOK_GITHUB_PR) {
link = `${link}/pull/${process.env.STORYBOOK_GITHUB_PR}`;
title = `Built from PR #${process.env.STORYBOOK_GITHUB_PR}`;
buttonText = `PR #${process.env.STORYBOOK_GITHUB_PR}`;
} else if (process.env.STORYBOOK_GITHUB_SHA) {
link = `${link}/commit/${process.env.STORYBOOK_GITHUB_SHA}`;
title = `Built from commit ${process.env.STORYBOOK_GITHUB_SHA}`;
buttonText = <code>{process.env.STORYBOOK_GITHUB_SHA.slice(0, 7)}</code>;
}
}

return link ? (
<IconButtonLink as="a" href={link} title={title} target="_blank">
<Icons icon="github" />
&nbsp;{buttonText}
</IconButtonLink>
) : null;
}

function FeatureFlagPanel(props) {
const [globals, updateGlobals] = useGlobals();
return (
<AddonPanel {...props}>
<ArgsTable
inAddonPanel
rows={featureFlagOptions}
args={globals}
updateArgs={updateGlobals}
/>
</AddonPanel>
);
}

function GridPanel(props) {
const [globals, updateGlobals] = useGlobals();

return (
<AddonPanel {...props}>
<ArgsTable
inAddonPanel
rows={gridOptions}
args={globals}
updateArgs={updateGlobals}
/>
</AddonPanel>
);
}
Loading

0 comments on commit fd2767e

Please sign in to comment.