Closed robcresswell closed 4 years ago
To implement this we should patch webpack config. The flow should be:
README.md
files inside stories directoryinput
){[componentName]: README}
and pass it to global variable or to the process.env
I would be happy for any help.
Work to do! Okay, I will keep this in mind. Thanks for the feedback. Not sure when / if I will get time to work on this, but I'll see what I can do.
Yes, it's possible: I have done it like this:
config.js
import React from 'react'
import path from 'path'
import { ThemeDecorator } from './decorators/index'
import {
configure,
storiesOf,
getStorybook,
addDecorator,
} from '@storybook/react'
import { withKnobs } from '@storybook/addon-knobs/react'
import { withReadme } from 'storybook-readme'
import { withOptions } from '@storybook/addon-options'
const getPackageName = filePath =>
path
.dirname(filePath)
.split(path.sep)
.reverse()[1]
const req = require.context(
'../../../components',
true,
/^((?!node_modules).)*\.example\.(js|tsx)$/
)
const readMeReq = require.context(
'../../../components',
true,
/^((?!node_modules).)*\README\.md$/
)
addDecorator(
withOptions({
name: 'Components',
})
)
configure(() => {
req.keys().forEach(pathToExample => {
const { name, Example, options = {} } = req(pathToExample)
const packageName = getPackageName(pathToExample)
const readmePath = readMeReq.keys().find(rm => rm.includes(packageName))
const readme = readMeReq(readmePath)
storiesOf(packageName, module)
.addDecorator(withKnobs)
.addDecorator(withReadme(readme))
.addDecorator(withOptions(options))
.addDecorator(ThemeDecorator)
.add(name, () => <Example />, { options })
})
}, module)
export { getStorybook }
HelloWorld.example.js:
import React from 'react'
import HelloWorld from 'path/to/hello-world'
export const name = 'Default'
export const Example = () => (
<HelloWorld />
)
We're planning on making this a feature of addon-notes in the future too, so "it just works".
Great setup you discovered there @kristof0425 !
@tuchk4 - Will this implementation mentioned above from @kristof0425 still work with v5? I am only getting it to work for one of my components?
import "./styles.css";
import React from "react";
import path from "path";
import { getStorybook, storiesOf, configure } from "@storybook/react";
import { withKnobs } from "@storybook/addon-knobs";
import { addReadme } from 'storybook-readme'
let getComponentName = filePath =>
path
.dirname(filePath)
.split(path.sep)
.reverse()[0];
let getPackageName = filePath =>
path
.dirname(filePath)
.split(path.sep)
.reverse()[1];
configure(() => {
// Automatically import all examples
const req = require.context(
"../packages",
true,
/^((?!node_modules).)*\.example\.js$/
);
const readMeReq = require.context(
"../packages",
true,
/^((?!node_modules).)*\.README\.md$/
)
req.keys().forEach(pathToExample => {
const { name, Example } = req(pathToExample);
const packageName = getPackageName(pathToExample)
const componentName = `${packageName}.${getComponentName(
pathToExample
)}`;
const readmePath = readMeReq.keys().find(rm => rm.includes(packageName))
const readme = readMeReq(readmePath)
console.log(readmePath)
storiesOf(componentName, module)
.addDecorator(withKnobs)
.addDecorator(addReadme)
.addParameters({
readme: {
content: '<!-- STORY --><!-- PROPS -->',
sidebar: readme,
},
})
.add(name, () => <Example dummy="test" />);
});
}, module);
export { getStorybook };
@jephjohnson yes, it should work but maybe split into two lines. Not sure it will be parsed correctly )
readme: {
content: `
<!-- STORY -->
<!-- PROPS -->
`,
sidebar: readme,
},
})
@tuchk4 - Ah, stil no dice.
@jephjohnson
addDecorator(addReadme)
Here is working example:
import React from 'react';
import path from 'path';
import {
getStorybook,
storiesOf,
addDecorator,
configure,
} from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
import { addReadme } from 'storybook-readme';
// register decorator
addDecorator(addReadme);
let getComponentName = filePath =>
path
.dirname(filePath)
.split(path.sep)
.reverse()[0];
let getPackageName = filePath =>
path
.dirname(filePath)
.split(path.sep)
.reverse()[1];
configure(() => {
// Automatically import all examples
const req = require.context(
'../auto',
true,
/^((?!node_modules).)*\.example\.js$/,
);
const readMeReq = require.context(
'../auto',
true,
/^((?!node_modules).)*\.README\.md$/,
);
req.keys().forEach(pathToExample => {
const { name, Example } = req(pathToExample);
const packageName = getPackageName(pathToExample);
const componentName = `${packageName}.${getComponentName(pathToExample)}`;
const readmePath = readMeReq.keys().find(rm => rm.includes(packageName));
const readme = readMeReq(readmePath);
storiesOf(componentName, module)
.addParameters({
readme: {
content: '<!-- STORY --><!-- PROPS -->',
sidebar: readme,
},
})
.add(name, () => <Example dummy="test" />);
});
}, module);
export { getStorybook };
Button.example.js
import React from 'react';
import Button from './';
export const name = 'Default';
export const Example = () => <Button label="Hi" />;
// copy proptypes so <!-- PROPS --> will work
Example.propTypes = Button.propTypes;
The decorator was in there. I’m thinking it’s related to my es lint folder. Still having the same issue of it not iterating through all the readmes
Thinking that I should to add @kristof0425's solution to README and close this issue
That would be awesome! 🎉 @tuchk4 Also thanks for the v5 support!
@kristof0425 Need you advice :) Also ping @jephjohnson as I know you use such way to load stories with docs.
I would like to add to docs how to automatically add README based on the story path. Here is PR - https://github.com/tuchk4/storybook-readme/pull/166
When tests faced the problem:
require.context is not a function
In your example this function is used to get all stories and README files by specific pattern.
Found this issue https://github.com/storybooks/storybook/issues/4479
Do we need to install additional babel plugins to use your solution?
Currently, this is the setup we use for Storybook:
Package | Version |
---|---|
webpack |
v4.28.4 |
@storybook/react |
v5.0.5 |
storybook-readme |
v5.0.1 |
babel-loader |
v8.0.0 |
@tuchk4 If you could share with me how you test the package, I can dig into the problem myself as well. 🙂
@kristof0425 @tuchk4 - Hey guys, sorry for the delay...Any new feedback on this? Still haven't got it resolved on my end. Here is the pakage.json.
{
"name": "@demo",
"private": true,
"license": "ISC",
"scripts": {
"start": "start-storybook -p 9001 -c .storybook",
"test": "jest -c jest.config.unit.js",
"test:watch": "jest -c jest.config.unit.js --watch",
"test:visual": "jest -c jest.config.visual-regression.js",
"precommit": "pretty-quick --staged",
"lint": "eslint -c .eslintrc.json 'packages/**/*.js'",
"build-storybook": "build-storybook -c .storybook -o .out"
},
"devDependencies": {
"0": "^0.0.0",
"@babel/cli": "^7.2.3",
"@babel/core": "^7.3.4",
"@babel/plugin-external-helpers": "^7.2.0",
"@babel/plugin-proposal-class-properties": "^7.3.4",
"@babel/plugin-proposal-object-rest-spread": "^7.3.4",
"@babel/plugin-transform-object-assign": "^7.2.0",
"@babel/plugin-transform-react-jsx": "^7.3.0",
"@babel/polyfill": "^7.4.3",
"@babel/preset-env": "^7.3.4",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-a11y": "^5.0.6",
"@storybook/addon-actions": "^5.0.1",
"@storybook/addon-knobs": "^5.0.1",
"@storybook/addon-storysource": "^5.0.1",
"@storybook/react": "^5.0.6",
"autoprefixer": "^9.2.1",
"babel-eslint": "10.0.1",
"babel-jest": "^24.5.0",
"babel-loader": "^8.0.5",
"eslint": "^5.15.3",
"eslint-config-prettier": "^4.1.0",
"eslint-config-react-app": "^3.0.4",
"eslint-loader": "2.1.1",
"eslint-plugin-flowtype": "3.0.0",
"eslint-plugin-import": "2.14.0",
"eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "7.11.1",
"gzip-size": "^5.0.0",
"html-webpack-plugin": "^3.2.0",
"husky": "^1.1.2",
"jest": "24.4.0",
"jest-dom": "^3.1.3",
"jest-puppeteer-react": "^4.6.1",
"prettier": "^1.14.3",
"pretty-bytes": "^5.1.0",
"pretty-quick": "^1.8.0",
"puppeteer": "^1.14.0",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-testing-library": "^6.0.0",
"rollup": "^0.66.6",
"rollup-plugin-babel": "^4.0.3",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-replace": "^2.1.0",
"rollup-plugin-uglify": "^6.0.0",
"storybook-readme": "^5.0.2",
"user-event": "^1.4.7"
},
"prettier": {},
"husky": {
"hooks": {
"pre-push": "yarn run lint"
}
},
"dependencies": {
"classnames": "^2.2.6",
"prop-types": "^15.7.2"
}
}
Hey @tuchk4 This would become a much easier process once storybook config has changed to monoconfig:
@ndelangen nice new feature! Seems it will be possible to implement awesome new features much easier :)
@tuchk4 I put together a repo that demonstrates the error @jephjohnson has been describing.
https://github.com/fgaleano/readme
Just npm install
on root and then npm start
.
The main problem is that prop's type
, description
and defaultValue
are not picked up even though they are present in the component's props definition.
You can see Storybook's configuration in .storybook/config.js
and the component props at packages/core/src/button/index.js
. Then all of the examples have the same configuration as far as exporting props.
Let us know if you can reproduce the error as I'm describing it.
Thank you!
@kristof0425 @tuchk4 - Any thoughts on the repo above? Thanks, Jeph
@jephjohnson sorry for the delay, had hard working days. going to back to storybook-readme in nearest days.
@jephjohnson sorry for the delay, had hard working days. going to back to storybook-readme in nearest days.
Hi @tuchk4 - Just touching base on this. Anything new? Thanks, J
Is there any way to have the addon automatically add the local
README.md
? Given a consistent file structure, I was hoping to be able to just always load the README for a given story, without having to add the decorator to every single story.For example, I use:
for every component.