Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy example stories over from renderer + addons #18824

Merged
merged 8 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions code/addons/actions/template/stories/basics.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// TODO -- for now react, going to generalise
import React, { FC } from 'react';

import { action } from '@storybook/addon-actions';

// TODO -- this needs to be a generic component
const Button: FC<{ onClick: () => void }> = ({ onClick, children }) => (
<button type="button" onClick={onClick}>
{children}
</button>
);

export default {
component: Button,
};

export const BasicExample = {
args: { onClick: action('hello-world') },
};
1 change: 1 addition & 0 deletions code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"esbuild": "^0.14.48",
"esbuild-loader": "^2.19.0",
"esbuild-plugin-alias": "^0.2.1",
"eslint": "^7.17.0",
"eslint-plugin-cypress": "^2.11.2",
Expand Down
27 changes: 27 additions & 0 deletions code/renderers/react/template/stories/decorators.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { FC } from 'react';
import type { ComponentStory, ComponentMeta } from '@storybook/react';

const Component: FC = () => <p>Story</p>;

export default {
component: Component,
decorators: [
(Story) => (
<>
<p>Component Decorator</p>
<Story />
</>
),
],
} as ComponentMeta<typeof Component>;

export const All: ComponentStory<typeof Component> = {
decorators: [
(Story) => (
<>
<p>Local Decorator</p>
<Story />
</>
),
],
};
17 changes: 17 additions & 0 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9009,6 +9009,7 @@ __metadata:
enzyme: ^3.11.0
enzyme-adapter-react-16: ^1.15.5
esbuild: ^0.14.48
esbuild-loader: ^2.19.0
esbuild-plugin-alias: ^0.2.1
eslint: ^7.17.0
eslint-plugin-cypress: ^2.11.2
Expand Down Expand Up @@ -20474,6 +20475,22 @@ __metadata:
languageName: node
linkType: hard

"esbuild-loader@npm:^2.19.0":
version: 2.19.0
resolution: "esbuild-loader@npm:2.19.0"
dependencies:
esbuild: ^0.14.39
joycon: ^3.0.1
json5: ^2.2.0
loader-utils: ^2.0.0
tapable: ^2.2.0
webpack-sources: ^2.2.0
peerDependencies:
webpack: ^4.40.0 || ^5.0.0
checksum: 309b4bd169ffd1d743ad7099182323a179dec789cd5eb4f5f0258c1c13034a154917679e2402bfcedd90c9b03d06d773e97fe4aa1056274dc43d30633c5707e1
languageName: node
linkType: hard

"esbuild-netbsd-64@npm:0.14.49":
version: 0.14.49
resolution: "esbuild-netbsd-64@npm:0.14.49"
Expand Down
1 change: 0 additions & 1 deletion sandbox/react
Submodule react deleted from 28e606
89 changes: 84 additions & 5 deletions scripts/example.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
/* eslint-disable no-restricted-syntax, no-await-in-loop */
import path from 'path';
import { remove, pathExists, readJSON, writeJSON } from 'fs-extra';
import prompts from 'prompts';

import { getOptionsOrPrompt } from './utils/options';
import { executeCLIStep } from './utils/cli-step';
import { exec } from '../code/lib/cli/src/repro-generators/scripts';
import { getInterpretedFile } from '../code/lib/core-common';
import { readConfig, writeConfig } from '../code/lib/csf-tools';
import { babelParse } from '../code/lib/csf-tools/src/babelParse';

const frameworks = ['react', 'angular'];
const addons = ['a11y', 'storysource'];
const defaultAddons = [
'actions',
'backgrounds',
'controls',
'docs',
'highlight',
'links',
'interactions',
'measure',
'outline',
'toolbars',
'viewport',
];
const examplesDir = path.resolve(__dirname, '../examples');
const codeDir = path.resolve(__dirname, '../code');

// TODO -- how to encode this information
const renderersMap = { react: 'react', angular: 'angular' };

async function getOptions() {
return getOptionsOrPrompt('yarn example', {
framework: {
Expand Down Expand Up @@ -116,11 +136,63 @@ const addPackageScripts = async ({
await writeJSON(packageJsonPath, packageJson, { spaces: 2 });
};

async function readMainConfig({ cwd }: { cwd: string }) {
const configDir = path.join(cwd, '.storybook');
const mainConfigPath = getInterpretedFile(path.resolve(configDir, 'main'));
return readConfig(mainConfigPath);
}

// NOTE: the test regexp here will apply whether the path is symlink-preserved or otherwise
const loaderPath = require.resolve('../code/node_modules/esbuild-loader');
const webpackFinalCode = `
(config) => ({
...config,
module: {
...config.modules,
rules: [
{
test: [/\\/node_modules\\/@storybook\\/[^/]*\\/template\\/stories\\//],
loader: '${loaderPath}',
options: {
loader: 'tsx',
target: 'es2015',
},
},
...config.module.rules,
],
},
})`;

// paths are of the form 'node_modules/@storybook/react'
async function addStories(paths: string[], { cwd }: { cwd: string }) {
const mainConfig = await readMainConfig({ cwd });

const stories = mainConfig.getFieldValue(['stories']) as string[];
const extraStoryDirsAndExistence = await Promise.all(
paths
.map((p) => path.join(p, 'template', 'stories'))
.map(async (p) => [p, await pathExists(path.resolve(codeDir, p))] as const)
);

const extraStories = extraStoryDirsAndExistence
.filter(([, exists]) => exists)
.map(([p]) => path.join('..', p, '*.stories.@(js|jsx|ts|tsx)'));
mainConfig.setFieldValue(['stories'], [...stories, ...extraStories]);

mainConfig.setFieldNode(
['webpackFinal'],
// @ts-ignore (not sure why TS complains here, it does exist)
babelParse(webpackFinalCode).program.body[0].expression
);

await writeConfig(mainConfig);
}

async function main() {
const optionValues = await getOptions();

const { framework, forceDelete, forceReuse, link, dryRun } = optionValues;
const cwd = path.join(examplesDir, framework as string);
const cwd = path.join(examplesDir, framework);

const exists = await pathExists(cwd);
let shouldDelete = exists && !forceReuse;
Expand All @@ -146,19 +218,26 @@ async function main() {
dryRun,
});

// TODO -- can we get the options type to return something more specific
tmeasday marked this conversation as resolved.
Show resolved Hide resolved
const renderer = renderersMap[framework as 'react' | 'angular'];

const storiesToAdd = [] as string[];
storiesToAdd.push(path.join('node_modules', '@storybook', renderer));

// TODO -- sb add <addon> doesn't actually work properly:
// - installs in `deps` not `devDeps`
// - does a `workspace:^` install (what does that mean?)
// - doesn't add to `main.js`

// eslint-disable-next-line no-restricted-syntax
for (const addon of optionValues.addon as string[]) {
for (const addon of optionValues.addon) {
const addonName = `@storybook/addon-${addon}`;
// eslint-disable-next-line no-await-in-loop
await executeCLIStep(steps.add, { argument: addonName, cwd, dryRun });
}

// TODO copy stories
for (const addon of [...defaultAddons, ...optionValues.addon]) {
storiesToAdd.push(path.join('node_modules', '@storybook', `addon-${addon}`));
}
await addStories(storiesToAdd, { cwd });

if (link) {
await executeCLIStep(steps.link, {
Expand Down