CLI: MDX template support (#8396)

CLI: MDX template support
This commit is contained in:
Michael Shilman 2019-10-15 00:34:42 +08:00 committed by GitHub
commit 4fcdee3607
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
144 changed files with 885 additions and 188 deletions

View File

@ -20,11 +20,12 @@ if (process.argv[1].includes('getstorybook')) {
program
.command('init')
.description('Initialize Storybook into your project.')
.option('-f --force', 'Forcely add storybook')
.option('-f --force', 'Force add storybook')
.option('-s --skip-install', 'Skip installing deps')
.option('-N --use-npm', 'Use npm to install deps')
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
.option('-t --type <type>', 'Add Storybook for a specific project type')
.option('--story-format <csf | mdx>', 'Generate stories in a specified format')
.option('-y --yes', 'Answer yes to all prompts')
.action(options => initiate(options, pkg));
@ -77,7 +78,7 @@ if (process.argv[1].includes('getstorybook')) {
invalidCmd
);
// eslint-disable-next-line
const suggestion = didYouMean(invalidCmd, program.commands.map(cmd => cmd._name));
const suggestion = didYouMean(invalidCmd, program.commands.map(cmd => cmd._name));
if (suggestion) {
logger.log(`\n Did you mean ${suggestion}?`);
}

View File

@ -3,7 +3,7 @@ const ignore = 0;
module.exports = {
overrides: [
{
files: '*/template/**',
files: '*/template[-?]*/**',
env: {
browser: true,
},

View File

@ -1,4 +1,3 @@
import fse from 'fs-extra';
import path from 'path';
import {
isDefaultProjectSet,
@ -7,29 +6,29 @@ import {
getAngularAppTsConfigPath,
} from './angular-helpers';
import {
getVersions,
getPackageJson,
getVersionedPackages,
writePackageJson,
getBabelDependencies,
installDependencies,
writeFileAsJson,
copyTemplate,
} from '../../lib/helpers';
async function addDependencies(npmOptions) {
const [
storybookVersion,
notesVersion,
actionsVersion,
linksVersion,
addonsVersion,
] = await getVersions(
npmOptions,
async function addDependencies(npmOptions, { storyFormat }) {
const packages = [
'@storybook/angular',
'@storybook/addon-notes',
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addons'
);
'@storybook/addons',
];
if (storyFormat === 'mdx') {
packages.push('@storybook/addon-docs');
}
const versionedPackages = await getVersionedPackages(npmOptions, ...packages);
const packageJson = getPackageJson();
@ -44,14 +43,7 @@ async function addDependencies(npmOptions) {
const babelDependencies = await getBabelDependencies(npmOptions, packageJson);
installDependencies(npmOptions, [
`@storybook/angular@${storybookVersion}`,
`@storybook/addon-notes@${notesVersion}`,
`@storybook/addon-actions@${actionsVersion}`,
`@storybook/addon-links@${linksVersion}`,
`@storybook/addons@${addonsVersion}`,
...babelDependencies,
]);
installDependencies(npmOptions, [...versionedPackages, ...babelDependencies]);
}
function editAngularAppTsConfig() {
@ -70,16 +62,16 @@ function editAngularAppTsConfig() {
writeFileAsJson(getAngularAppTsConfigPath(), tsConfigJson);
}
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
if (!isDefaultProjectSet()) {
throw new Error(
'Could not find a default project in your Angular workspace. Add a project and re-run the installation.'
);
}
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
await addDependencies(npmOptions);
await addDependencies(npmOptions, { storyFormat });
editAngularAppTsConfig();
editStorybookTsConfig(path.resolve('./.storybook/tsconfig.json'));
};

View File

@ -0,0 +1,3 @@
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-notes/register';

View File

@ -0,0 +1,4 @@
import { configure } from '@storybook/angular';
// automatically import all files ending in *.stories.ts
configure(require.context('../src/stories', true, /\.stories\.(ts|mdx)$/), module);

View File

@ -0,0 +1 @@
module.exports = ['@storybook/addon-docs/angular/preset'];

View File

@ -0,0 +1,9 @@
{
"extends": "%SET_DURING_SB_INIT%",
"compilerOptions": {
"types": ["node"]
},
"exclude": ["../src/test.ts", "../src/**/*.spec.ts", "../projects/**/*.spec.ts"],
"include": ["../src/**/*", "../projects/**/*"],
"files": ["./typings.d.ts"]
}

View File

@ -0,0 +1,4 @@
declare module '*.md' {
const content: string;
export default content;
}

View File

@ -0,0 +1,17 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { Welcome } from '@storybook/angular/demo';
<Meta title="Welcome" />
# Welcome
This is a test document written in MDX that defines a `Welcome` story wrapped in a `Preview` doc block:
<Preview withToolbar>
<Story name="to Storybook">
{{
component: Welcome,
props: {},
}}
</Story>
</Preview>

View File

@ -0,0 +1,49 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { action } from '@storybook/addon-actions';
import { linkTo } from '@storybook/addon-links';
import { Button } from '@storybook/angular/demo';
<Meta title="Button" />
# Button
This `Button` document defines a few stories:
<Story name="text">
{{
component: Button,
props: {
text: 'Hello Button',
},
}}
</Story>
<Story name="emoji">
{{
component: Button,
props: {
text: '😀 😎 👍 💯',
},
}}
</Story>
<Story name="with some emoji and action">
{{
component: Button,
props: {
text: '😀 😎 👍 💯',
onClick: action('This was clicked OMG'),
},
}}
</Story>
<Story name="button with link to another story">
{{
component: Button,
props: {
text: 'Go to Welcome Story',
onClick: linkTo('Welcome'),
},
}}
</Story>

View File

@ -1,14 +1,13 @@
import path from 'path';
import fse from 'fs-extra';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [storybookVersion, linksVersion, actionsVersion, addonsVersion] = await getVersions(
npmOptions,
'@storybook/ember',
@ -17,7 +16,7 @@ export default async npmOptions => {
'@storybook/addons'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();

View File

@ -1,17 +1,21 @@
import fse from 'fs-extra';
import path from 'path';
import npmInit from '../../lib/npm_init';
import {
getVersion,
getVersionedPackages,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
const storybookVersion = await getVersion(npmOptions, '@storybook/html');
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
export default async (npmOptions, { storyFormat = 'csf' }) => {
const packages = ['@storybook/html'];
const versionedPackages = await getVersionedPackages(npmOptions, ...packages);
if (storyFormat === 'mdx') {
packages.push('@storybook/addon-docs');
}
copyTemplate(__dirname, storyFormat);
let packageJson = getPackageJson();
if (!packageJson) {
@ -30,5 +34,5 @@ export default async npmOptions => {
const babelDependencies = await getBabelDependencies(npmOptions, packageJson);
installDependencies(npmOptions, [`@storybook/html@${storybookVersion}`, ...babelDependencies]);
installDependencies(npmOptions, [...versionedPackages, ...babelDependencies]);
};

View File

@ -0,0 +1,4 @@
import { configure } from '@storybook/html';
// automatically import all files ending in *.stories.js
configure(require.context('../stories', true, /\.stories\.(js|mdx)$/), module);

View File

@ -0,0 +1 @@
module.exports = ['@storybook/addon-docs/html/preset'];

View File

@ -0,0 +1,21 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
# HTML MDX Demo
Here's a few sample HTML stories in MDX. Enjoy!
<Meta title="Demo" />
<Preview withToolbar>
<Story name="heading">{() => '<h1>Hello World</h1>'}</Story>
</Preview>
<Story name="button">
{() => {
const btn = document.createElement('button');
btn.type = 'button';
btn.innerText = 'Hello Button';
btn.addEventListener('click', e => console.log(e));
return btn;
}}
</Story>

View File

@ -1,14 +1,13 @@
import path from 'path';
import fse from 'fs-extra';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [storybookVersion, addonActionVersion, addonKnobsVersion] = await getVersions(
npmOptions,
'@storybook/marko',
@ -16,7 +15,7 @@ export default async npmOptions => {
'@storybook/addon-knobs'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();

View File

@ -1,16 +1,15 @@
import path from 'path';
import fs from 'fs';
import JSON5 from 'json5';
import fse from 'fs-extra';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [
storybookVersion,
actionsVersion,
@ -32,7 +31,7 @@ export default async npmOptions => {
'@babel/preset-react'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();
packageJson.devDependencies = packageJson.devDependencies || {};

View File

@ -1,14 +1,13 @@
import path from 'path';
import fse from 'fs-extra';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions(
npmOptions,
'@storybook/mithril',
@ -17,7 +16,7 @@ export default async npmOptions => {
'@storybook/addons'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();

View File

@ -1,20 +1,19 @@
import fse from 'fs-extra';
import path from 'path';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [storybookVersion, polymerLoaderVarion] = await getVersions(
npmOptions,
'@storybook/polymer',
'polymer-webpack-loader'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson() || {}; // Maybe we are in a bower only project, still we need a package json

View File

@ -1,14 +1,13 @@
import path from 'path';
import fse from 'fs-extra';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions(
npmOptions,
'@storybook/preact',
@ -17,7 +16,7 @@ export default async npmOptions => {
'@storybook/addons'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();

View File

@ -1,14 +1,13 @@
import path from 'path';
import fse from 'fs-extra';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [
storybookVersion,
actionsVersion,
@ -24,7 +23,7 @@ export default async npmOptions => {
'rax'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();

View File

@ -1,23 +1,26 @@
import path from 'path';
import fse from 'fs-extra';
import {
getVersions,
getVersionedPackages,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions(
npmOptions,
export default async (npmOptions, { storyFormat = 'csf' }) => {
const packages = [
'@storybook/react',
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addons'
);
'@storybook/addons',
];
if (storyFormat === 'mdx') {
packages.push('@storybook/addon-docs');
}
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
const versionedPackages = await getVersionedPackages(npmOptions, ...packages);
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();
@ -32,11 +35,5 @@ export default async npmOptions => {
const babelDependencies = await getBabelDependencies(npmOptions, packageJson);
installDependencies(npmOptions, [
`@storybook/react@${storybookVersion}`,
`@storybook/addon-actions@${actionsVersion}`,
`@storybook/addon-links@${linksVersion}`,
`@storybook/addons@${addonsVersion}`,
...babelDependencies,
]);
installDependencies(npmOptions, [...versionedPackages, ...babelDependencies]);
};

View File

@ -0,0 +1,4 @@
import { configure } from '@storybook/react';
// automatically import all files ending in *.stories.js
configure(require.context('../stories', true, /\.stories\.(js|mdx)$/), module);

View File

@ -0,0 +1,6 @@
module.exports = [
{
name: '@storybook/addon-docs/react/preset',
options: { configureJSX: true },
},
];

View File

@ -0,0 +1,15 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { linkTo } from '@storybook/addon-links';
import { Welcome } from '@storybook/react/demo';
<Meta title="Welcome" />
# Welcome
This is a test document written in MDX that defines a `Welcome` story wrapped in a `Preview` doc block:
<Preview withToolbar>
<Story name="to Storybook">
<Welcome showApp={linkTo('Button')} />
</Story>
</Preview>

View File

@ -0,0 +1,21 @@
import { action } from '@storybook/addon-actions';
import { Button } from '@storybook/react/demo';
import { Meta, Story } from '@storybook/addon-docs/blocks';
<Meta title="Button" />
# Button
This `Button` document defines two stories:
<Story name="text">
<Button onClick={action('clicked')}>Hello Button</Button>
</Story>
<Story name="emoji">
<Button onClick={action('clicked')}>
<span role="img" aria-label="so cool">
😀 😎 👍 💯
</span>
</Button>
</Story>

View File

@ -1,5 +1,3 @@
import fse from 'fs-extra';
import path from 'path';
import shell from 'shelljs';
import chalk from 'chalk';
import {
@ -9,9 +7,10 @@ import {
paddedLog,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async (npmOptions, installServer) => {
export default async (npmOptions, installServer, { storyFormat = 'csf' }) => {
const [storybookVersion, addonsVersion, actionsVersion, linksVersion] = await getVersions(
npmOptions,
'@storybook/react-native',
@ -20,8 +19,7 @@ export default async (npmOptions, installServer) => {
'@storybook/addon-links'
);
// copy all files from the template directory to project directory
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
// set correct project name on entry files if possible
const dirname = shell.ls('-d', 'ios/*.xcodeproj').stdout;

View File

@ -1,25 +1,30 @@
import fse from 'fs-extra';
import path from 'path';
import fs from 'fs';
import semver from 'semver';
import {
getVersions,
getPackageJson,
getVersionedPackages,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions(
npmOptions,
export default async (npmOptions, { storyFormat = 'csf' }) => {
const packages = [
'@storybook/react',
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addons'
);
'@storybook/addons',
];
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
if (storyFormat === 'mdx') {
packages.push('@storybook/addon-docs');
}
const versionedPackages = await getVersionedPackages(npmOptions, ...packages);
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();
@ -46,11 +51,5 @@ export default async npmOptions => {
babelDependencies = await getBabelDependencies(npmOptions, packageJson);
}
installDependencies(npmOptions, [
`@storybook/react@${storybookVersion}`,
`@storybook/addon-actions@${actionsVersion}`,
`@storybook/addon-links@${linksVersion}`,
`@storybook/addons@${addonsVersion}`,
...babelDependencies,
]);
installDependencies(npmOptions, [...versionedPackages, ...babelDependencies]);
};

View File

@ -0,0 +1,4 @@
import { configure } from '@storybook/react';
// automatically import all files ending in *.stories.js
configure(require.context('../src/stories', true, /\.stories\.(js|mdx)$/), module);

View File

@ -0,0 +1,8 @@
module.exports = [
{
name: '@storybook/addon-docs/react/preset',
options: {
configureJSX: true,
},
},
];

View File

@ -0,0 +1,15 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { linkTo } from '@storybook/addon-links';
import { Welcome } from '@storybook/react/demo';
<Meta title="Welcome" />
# Welcome
This is a test document written in MDX that defines a `Welcome` story wrapped in a `Preview` doc block:
<Preview withToolbar>
<Story name="to Storybook">
<Welcome showApp={linkTo('Button')} />
</Story>
</Preview>

View File

@ -0,0 +1,21 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { action } from '@storybook/addon-actions';
import { Button } from '@storybook/react/demo';
<Meta title="Button" />
# Button
This `Button` document defines two stories:
<Story name="text">
<Button onClick={action('clicked')}>Hello Button</Button>
</Story>
<Story name="emoji">
<Button onClick={action('clicked')}>
<span role="img" aria-label="so cool">
😀 😎 👍 💯
</span>
</Button>
</Story>

View File

@ -1,14 +1,13 @@
import fse from 'fs-extra';
import path from 'path';
import {
getVersions,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
export default async (npmOptions, { storyFormat = 'csf' }) => {
const [
storybookVersion,
actionsVersion,
@ -24,7 +23,7 @@ export default async npmOptions => {
'riot-tag-loader'
);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();

View File

@ -1,23 +1,25 @@
import fse from 'fs-extra';
import path from 'path';
import {
getVersions,
getVersionedPackages,
getPackageJson,
writePackageJson,
getBabelDependencies,
installDependencies,
copyTemplate,
} from '../../lib/helpers';
export default async npmOptions => {
const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions(
npmOptions,
export default async (npmOptions, { storyFormat = 'csf' }) => {
const packages = [
'@storybook/vue',
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addons'
);
'@storybook/addons',
];
if (storyFormat === 'mdx') {
packages.push('@storybook/addon-docs');
}
const versionedPackages = await getVersionedPackages(npmOptions, ...packages);
fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true });
copyTemplate(__dirname, storyFormat);
const packageJson = getPackageJson();
@ -32,11 +34,5 @@ export default async npmOptions => {
const babelDependencies = await getBabelDependencies(npmOptions, packageJson);
installDependencies(npmOptions, [
`@storybook/vue@${storybookVersion}`,
`@storybook/addon-actions@${actionsVersion}`,
`@storybook/addon-links@${linksVersion}`,
`@storybook/addons@${addonsVersion}`,
...babelDependencies,
]);
installDependencies(npmOptions, [...versionedPackages, ...babelDependencies]);
};

Some files were not shown because too many files have changed in this diff Show More