This article is translated from the official website of personal understanding and interpretation of the technology. It is inevitable that there are some inappropriate points. We hope that you can give us more advice and learn together.
react-styleguidist will display all components on a page of the browser, including props documents, usage examples, and an environment for independent development of components. In Styleguidist, you can write examples in Markdown, and each code segment will be presented immediately;
principle
Styleguidist will load the components and use react-docgen to generate documentation. You may need to change the code to work properly.
React-docgen will read the component as a static text file, and then find the component (such as class or function declaration) similar to the pattern of finding React components. React-docgen does not run any JavaScript code, so if the component is dynamically generated, or packaged in a high-level component, or split into multiple files, react-docgen may not be able to understand it.
- React-docgen supports components defined by React.createClass, ES6 classes and function components;
- React-docgen supports Flow and TypeScript comments;
In some cases, the two components can be derived by deception Styleguidist and react-docgen:
- Basic components exported as named
- Enhanced components exported as default
import React from 'react'
import CSSModules from 'react-css-modules'
import styles from './Button.css'
// Base component will be used by react-docgen to generate documentation
export function Button({ color, size, children }) {
/* ... */
}
// Enhanced component will be used when you write <Button /> in your example files
export default CSSModules(Button, styles)
begin
Install Styleguidist:
// npm
npm install --save react-styleguidist
// yarn
yarn add react-styleguidist
Configure package.json script
"scripts": {
"styleguide": "NODE_ENV=development styleguidist server",
"styleguide:build": "NODE_ENV=production styleguidist build",
}
Run Styleguidist
npm run styleguide //启动styleguidist开发服务器
npm run styleguide:build //构建生产HTML版本
Component generation documentation
Styleguidist generates documentation for the component based on the comments in the component, the propTypes declaration and Readerme.md
Parse props
default behavior: Styleguidist obtains props from propType s to generate a table, and displays the description of the component according to the comment of props, and obtains the default value of props according to defaultProps.
import React from 'react'
import PropTypes from 'prop-types'
/**
* General component description in JSDoc format. Markdown is *supported*.
*/
export default class Button extends React.Component {
static propTypes = {
/** Description of prop "foo". */
foo: PropTypes.number,
/** Description of prop "baz". */
baz: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}
static defaultProps = {
foo: 42
}
render() {
/* ... */
}
}
Modify the default behavior
You can use propsParser
and resolver
change the default behavior of parsing props;
propsParser: Function
This method can reconstruct how to parse props from the source file. The default is to use react-docgen for parsing.
module.exports = {
propsParser(filePath, source, resolver, handlers) {
return require('react-docgen').parse(source, resolver, handlers)
}
}
resolver
This method can determine which classes/components need to be resolved. The default behavior is to find all exported components in each file, and it can be configured so that all found components use a custom resolution method.
module.exports = {
resolver: require('react-docgen').resolver
.findAllComponentDefinitions
}
The PropType and documentation comments of the component are parsed by the react-docgen library and can be modified using the updateDocs function.
For more information on parsing props, see the react-docgen documentation.
Sample file search and writing
default behavior of Readme.md
or [ComponentName].md
files in the component folder by default and generates sample files.
Code blocks marked with js, jsx or javascript will be rendered as React components with interactive. For backward compatibility, code blocks without language tags will also be displayed as interactive React components.
React component example:
```js
<Button size="large">Push Me</Button>
```
You can add a custom props to an example wrapper:
```js { "props": { "className": "checks" } }
<Button>I’m transparent!</Button>
```
To render an example as highlighted source code add a `static` modifier:
```jsx static
import React from 'react';
```
Modify the default behavior
The md file name can be getExampleFilename
. This method returns the new md file path through the provided component file path.
ComponentName.examples.md
with Readme.md
:
module.exports = {
getExampleFilename(componentPath) {
return componentPath.replace(/\.jsx?$/, '.examples.md')
}
}
Associate other sample files
You can use the @example doclet
syntax to associate other sample files with the component.
The Button component has an example loaded from the extra.examples.md file:
/**
* Component is described here.
*
* @example ./extra.examples.md
*/
export default class Button extends React.Component {
// ...
}
Write code
- Import dependencies: import via import
- Manage state: Each example is a function component, and you can use useState Hook to handle state.
// ```jsx inside Markdown
import React from 'react'
import Button from 'rsg-example/components/Button'
import Placeholder from 'rsg-example/components/Placeholder'
;<Button size="large">Push Me</Button>
// ```jsx inside Markdown
const [isOpen, setIsOpen] = React.useState(false)
;<div>
<button onClick={() => setIsOpen(true)}>Open</button>
<Modal isOpen={isOpen}>
<h1>Hallo!</h1>
<button onClick={() => setIsOpen(false)}>Close</button>
</Modal>
</div>
moduleAliases
Define the alias of the module, you can import these aliases in the sample file to make the sample code more practical and reproducible;
const path = require('path');
module.exports = {
moduleAliases: {
'rsg-example': path.resolve(__dirname, 'src')
}
}
- Markdown syntax is supported;
- If you need to display some JavaScript code that you don't want to be rendered interactive in the document, you can use the static modifier with the language tag;
- Styleguidist Bublé , most ES6 functions are supported;
- The rsg-example module is an alias defined by the moduleAliases option;
- If you need a more complex presentation, it is usually best to define it in a separate JavaScript file and then import it into Markdown
Public method
By default, any methods of the component are considered private methods and will not be published. Using the JSDoc @public
marking method, you can make it a public method and will be published in the document.
/**
* @param {string} name
* @public
*/
getName(name) {
// ...
}
Hide props
By default, all props of the component are public and publishable. In some cases, there are certain props in the code, and you hope that this props will not be displayed in the document. JSDoc @ignore
, and you can delete it from the document.
Button.propTypes = {
/**
* A prop that should not be visible in the documentation.
* @ignore
*/
hiddenProp: React.PropTypes.string
}
Positioning components
Find components
By default, Styleguidist will use this mode to locate components: src/components/**/*.{js,jsx,ts,tsx}
.
E.g:
src/components/Button.js
src/components/Button/Button.js
src/components/Button/index.js
But the tests file will be ignored:
__tests__
folder- The file name contains
.test.js
or.spec.js
(similar to:.jsx
,.ts
,.tsx
)
Modify the default search method
The configuration components
in the styleguide.config.js
file can modify the component search method to adapt to different projects;
For example: if the component path is components/Button/Button.js
, in order to simplify the import, export again components/Button/index.js
export { default } from './Button'
), [In order to let components/Button
replace components/Button/Button
], you need to skip index.js at this time.
module.exports = {
components: 'src/components/**/[A-Z]*.js'
}
Use ignore
to exclude certain files from the style guide
ignore:String[]
Defaults:
['**/__tests__/**', '**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}', '**/*.d.ts']
Use getComponentPathLine
change the component import path
getComponentPathLine: Function
Default value: component file name;
Return value: return component path;
For example: Import Button components/Button
components/Button /Button.js
const path = require('path');
module.exports = {
getComponentPathLine(componentPath) {
const name = path.basename(componentPath, '.js')
const dir = path.dirname(componentPath)
return `import ${name} from '${dir}';`
}
}
All paths are relative to the config folder;
Load components
Styleguidist loads components and exposes them globally for use in examples.
Identifier
Styleguidist uses the displayName of the component as the identifier by default. If it cannot understand displayName (displayName is dynamically generated), it will fall back to what it can understand.
Sections
Sections: Array[{}]
Group components or add additional Markdown documents to the style guide.
Each attribute value of the Sections array is as follows:
Attribute name | description |
---|---|
name | Sections title |
content | The location of the Markdown file containing the overview content |
components | It can be a glob pattern string, a component path array, a glob pattern string array, a function that returns a component array, or a function that returns a glob pattern string. The rules are the same as the components |
sections | Nested Sections array (can be nested) |
description | section description |
sectionDepth | The number of sections on a single page, only available in pagePerSection |
exampleMode | The initial state of the code example, using exampleMode |
usageMode | The initial state of props and methods, using usageMode |
ignore | The file to be ignored, the value can be a string or an array; |
href | Navigate URL (not the URL to navigate to the Sections content) |
external | If set, a new page will open |
expand | When setting tocMode to collapse (folded) in the general settings, confirm whether it should be unfolded; |
- All the above fields are optional;
// styleguide.config.js
module.exports = {
sections: [
{
name: 'Introduction',
content: 'docs/introduction.md'
},
{
name: 'Documentation',
sections: [
{
name: 'Installation',
content: 'docs/installation.md',
description: 'The description for the installation section'
},
{
name: 'Configuration',
content: 'docs/configuration.md'
},
{
name: 'Live Demo',
external: true,
href: 'http://example.com'
}
]
},
{
name: 'UI Components',
content: 'docs/ui.md',
components: 'lib/components/ui/*.js',
exampleMode: 'expand', // 'hide' | 'collapse' | 'expand'
usageMode: 'expand' // 'hide' | 'collapse' | 'expand'
}
]
}
Configure webpack
Styleguidist relies on webpack and uses webpack to determine how to load the project's files, but the project does not necessarily have to configure webpack.
By default, Styleguidist will look for webpack.config.js
in the root directory of the project and use it.
Custom Webpack configuration
If webpack is configured in another location, you need to load it manually:
module.exports = {
webpackConfig: require('./configs/webpack.js')
}
You can also merge multiple webpack configurations:
module.exports = {
webpackConfig: Object.assign({}, require('./configs/webpack.js'), {
/* Custom config options */
})
}
- Configurations
entry
,externals
,output
,watch
, andstats
will be ignored. In production,devtoo
will also be ignored;- Plug-ins
CommonsChunkPlugins
,HtmlWebpackPlugin
,MiniHtmlWebpackPlugin
,UglifyJsPlugin
,TerserPlugin
,HotModuleReplacementPlugin
will be ignored, because Styleguidist has already introduced them, and their re-introduction will affect Styleguidist;- If loaders do not work, try to include and exclude absolute paths;
styleguide configuration properties
Attribute name | Types of | meaning |
---|---|---|
title | String | Set page title |
serverPort | Number | The port number |
require | Array | Add user-defined js, CSS or polyfills |
assetsDir | String | Resource file name |
styleguideDir | String | Define the folder of static HTML generated by the styleguidist build command; default value: styleguide |
getComponentPathLine | Function | Get component loading path |
template | Object / Function | Change the HTML of the application. You can add favicon, meta tags, objects with embedded JavaScript or CSS. |
styles | Object / String / Function | Customize the style of the Styleguidist sample component; the configuration file path is a relative configuration file or an absolute path. |
theme | Object / String | Customize the UI fonts, colors, etc. of the Styleguidist sample component; the configuration file path is a relative configuration file or an absolute path. |
sections | Array[{}] | Set component grouping |
styleguideComponents | Object | Rewrite the styleguide React component that is used to render to the browser; |
webpackConfig | Object / String | Custom webpack configuration; |
For more configuration options, see the official document: configuration
use
How to hide a component in the style guide, which can be used in the example?
Through the skipComponentsWithoutExample
attribute, do not add sample files for components that need to be ignored (the default is Readme.md).
skipComponentsWithoutExample: Boolean
Default value: false
Ignore this component if there is no sample file; unless require
, other samples cannot access these components.
In an example to reference the ignored component:
// /Readme.md
// ```jsx
import Button from '../common/Button'
;<Button>Push Me Tender</Button>
Ignored components can be used in all examples:
// styleguide.config.js
module.exports = {
require: [path.resolve(__dirname, 'styleguide/setup.js')]
}
// styleguide/setup.js
import Button from './src/components/common/Button'
global.Button = Button
Each example does not introduce Button components, Button components can also be used;
How to change the layout of the style guide?
Any Styleguidist React component can be replaced.
In most cases, only the *Renderer
components need to be replaced-all HTML is rendered by these components. View all available components
Sometimes the component wrapper Wrapper
component is also modified-each example component is packaged. children
is rendered as-is, but you can use it to provide custom logic rendering children
.
Replace Wrapper
To replace the default Wrapper component, use react-intl's IntlProvider instead:
It is not possible to wrap the entire style guide because each example is compiled separately in the browser.
// styleguide.config.js
const path = require('path');
module.exports = {
styleguideComponents: {
Wrapper: path.join(__dirname, 'src/styleguide/Wrapper')
}
}
// src/styleguide/Wrapper.js
import React, { Component } from 'react';
import { IntlProvider } from 'react-intl';
export default class Wrapper extends Component {
render() {
return (
<IntlProvider locale="en">{this.props.children}</IntlProvider>
)
}
}
Replace StyleGuideRenderer
const path = require('path')
module.exports = {
styleguideComponents: {
StyleGuideRenderer: path.join(
__dirname,
'src/styleguide/StyleGuideRenderer'
)
}
}
// src/styleguide/StyleGuideRenderer.js
import React from 'react'
const StyleGuideRenderer = ({
title,
version,
homepageUrl,
components,
toc,
hasSidebar
}) => (
<div className="root">
<h1>{title}</h1>
{version && <h2>{version}</h2>}
<main className="wrapper">
<div className="content">
{components}
<footer className="footer">
<Markdown
text={`Created with [React Styleguidist](${homepageUrl})`}
/>
</footer>
</div>
{hasSidebar && <div className="sidebar">{toc}</div>}
</main>
</div>
)
How to change the style of the style guide?
There are two properties to change the style of the style guide: theme and styles.
- theme: You can change the font, color, etc.
- styles: You can adjust the style of any Styleguidist component;
// styleguide.config.js
module.exports = {
theme: {
color: {
link: 'firebrick',
linkHover: 'salmon'
},
fontFamily: {
base: '"Comic Sans MS", "Comic Sans", cursive'
}
},
styles: {
Logo: {
// the LogoRenderer component
logo: {
animation: '$blink ease-in-out 300ms infinite'
},
'@keyframes blink': {
to: { opacity: 0 }
}
}
}
}
can store the object values of theme and styles in separate files, and introduce the file path in the configuration file, which allows hot module replacement (HMR).
Every time you modify theme.js or styles.js, HMR will be triggered to update the styleguide in the browser.
The same example above will be converted to:
// styleguide.config.js
module.exports = {
// ...
styles: './styleguide/styles.js',
theme: './styleguide/themes.js'
}
// ./styleguide/theme.js
module.exports = {
color: {
link: 'firebrick',
linkHover: 'salmon'
},
fontFamily: {
base: '"Comic Sans MS", "Comic Sans", cursive'
}
}
// ./styleguide/styles.js
module.exports = {
Logo: {
// the LogoRenderer component
logo: {
animation: '$blink ease-in-out 300ms infinite'
},
'@keyframes blink': {
to: { opacity: 0 }
}
}
}
- View available theme variables
- Styles using a plugin following the JSS: JSS-the isolate , JSS-nested , JSS-CAMEL-Case , JSS-default-Unit , JSS-Compose and JSS-Global
How to add global styles to components?
StyleGuide
in the form of jss-global
api through 06087f4d55d7a1 attribute.
This method does not set the style on the style guide UI.
// styleguide.config.js
module.exports = {
components: 'src/components/**/[A-Z]*.js',
styles: {
StyleGuide: {
'@global body': {
fontFamily: 'Helvetica',
fontWeight: bold,
}
}
}
}
Is equivalent to:
body {
font-family: 'Helvetica';
font-weight: bold,
}
How to add custom JavaScript, CSS, polyfill?
Use the require attribute:
// styleguide.config.js
const path = require('path');
module.exports = {
require: [
'babel-polyfill',
path.join(__dirname, 'path/to/script.js'),
path.join(__dirname, 'path/to/styles.css')
]
}
How to add external JavaScript and CSS files?
Use the template attribute.
template
Change the HTML of the style guide. The attribute value supports two types: Object and Function.
- Object: An object with adding web icons, meta tags, inline JavaScript or CSS, etc. Check @vxna/mini-html-webpack-template docs .
- Function: A function that returns an HTML string. Check mini-html-webpack-plugin docs .
// styleguide.config.js
module.exports = {
template: {
head: {
scripts: [
{
src: 'assets/js/babelHelpers.min.js'
}
],
links: [
{
rel: 'stylesheet',
href: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'
}
]
}
}
}
Compared with the require attribute, the scripts and links configured in the template run in the browser, not during the webpack build process. This is useful for scripts where components produce side effects. In this case, Babel output needs to be functional.
How to use CSS animation in the style guide?
Due to the scope of internal keyframes, the animation property in CSS rules does not directly use the name of its keyframe animation. If you use CSS animation, you must define its key frame at the root of the renderer object.
// styleguide.config.js
module.exports = {
styles: {
// the LogoRenderer component
Logo: {
'@keyframes blink': {
to: { opacity: 0 }
}
}
}
}
How to add fonts from Google Fonts?
Use template and theme attributes:
// styleguide.config.js
module.exports = {
template: {
head: {
links: [
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css?family=Roboto'
}
]
}
},
theme: {
fontFamily: {
base: '"Roboto", sans-serif'
}
}
}
How to use ref
in the example?
Use ref props as functions and assign parameters to local variables:
// Button/Readme.md
const [value, setValue] = React.useState('')
let textareaRef
;<div>
<Button onClick={() => textareaRef.insertAtCursor('Pizza')}>
Insert
</Button>
<Textarea
value={value}
onChange={e lili=> setValue(e.target.value)}
ref={ref => (textareaRef = ref)}
/>
</div>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。