如何使用 React 和 Storybook 构建 UI 组件

介绍

Storybook是一个可以用于文档组件的用户界面(UI)库。

<$>[注] 注: 本文建立在 介绍剧本上,它涵盖了如何使用它来组织和构建 JavaScript 组件。

在本文中,您将使用 React 和 Storybook 构建一个交互式 UI 组件。

Screenshot of the Storybook UI component dashboard.

在教程结束时,您将部署故事书作为一个独立的应用程序,作为风格指南。

前提条件

要完成本教程,您将需要:

本教程已通过 Node v14.4.0、npm v6.14.5、react v16.13.1 和@storybook/react v5.3.19 进行验证。

步骤1 - 设置项目

要开始,我们需要创建一个新的 React 项目,为此,我们将使用 create-react-app,这是一个伟大的工具来设置 React 应用程序。

1npx create-react-app storybook-app

然后导航到新创建的项目目录:

1cd storybook-app

下一步将是将故事书包安装到我们的项目中:

1npx -p @storybook/cli sb init

该命令可以自动从package.json文件中检测我们正在使用的框架,并安装该框架的 Storybook 版本。

在运行这两个命令后,我们可以通过打开package.json文件来确认我们已安装了@storybook/react依赖性,以验证这些包是否已安装,然后我们可以运行应用程序以及运行 Storybook。

1npm start

Screenshot of the React welcome page.

1npm run storybook

Screenshot of the Storybook welcome page.

运行这两个命令后,我们将有 React 应用程序和 Storybook 应用程序在不同的端口上运行。

手动添加配置

如果我们在已经存在的React项目中安装了@storybook/react包,那么我们需要遵循这些步骤来设置 Storybook。

我们首先要在我们的React项目的根目录中创建一个文件夹 .storybook,然后在文件夹中创建一个名为 config.js的文件,并添加以下代码行:

1[label .storybook/config.js]
2import { configure } from '@storybook/react';
3
4function loadStories() {
5  require('../src/stories');
6}
7
8configure(loadStories, module);

上面的代码块是 Storybook 的配置,它告诉 Storybook 在src/stories目录中找到故事. 如果我们没有它已经设置,我们将创建该文件夹。

<$>[注] 注: Storybook 5.3.0 或更高版本引入了 main.js,它处理了过去所做的config.js

如果您正在使用 Storybook 5.3.0 或更高版本,则不需要config.js文件,您可以忽略此步骤。

官方文件也建议不同的方法,在哪里放置故事

此时, Storybook 已设置为使用。

步骤 2 — 将故事添加到 React 应用程序

现在我们已经完成了设置,我们可以使用 Storybook 创建组件。

在本教程中,我们将创建一个<Button>组件,对于这个组件,我们将在stories文件夹中记录他们的故事。

 1[label src/components/Button.js]
 2import React from 'react';
 3import './Button.css';
 4
 5const Button = props => (
 6  <button onClick={props.onClick} style={props.style}>
 7    {props.label && <span>{props.label}</span>}
 8  </button>
 9);
10
11export default Button;

并为组件添加风格:

 1[label src/components/Button.css]
 2button {
 3  padding: 20px;
 4  width: 20em;
 5  margin: 10px;
 6  color: white;
 7  font-size: 19px;
 8  cursor: pointer;
 9  border: 2px solid #fecd43;
10  background: #fecd43;
11}

现在,我们可以为创建的<Button>组件添加一个故事,在stories目录中创建一个文件,并将其命名为buttonStories.js,然后在文件中添加以下代码行:

 1[label src/stories/buttonStories.js]
 2import React from 'react';
 3import { storiesOf } from '@storybook/react';
 4
 5import Button from '../components/Button';
 6
 7storiesOf('Button', module)
 8  .add('with primary', () => <Button label="Primary Button" />)
 9  .add('with outline', () => <Button
10    label="Ouline Button"
11    style={{ background: 'transparent', border: '3px solid #fecd43' }}
12  />)
13  .add('with rounder corners', () => <Button
14    label="Rounded Button"
15    style={{ borderRadius: '15px' }}
16  />)
17  .add('disabled', () => <Button disabled
18    label="Disabled Button"
19    style={{ background: 'gray' , border: 'gray', cursor: 'not-allowed' }}
20  />);

然后,创建一个index.js文件,导入buttonStories.js文件:

1[label src/stories/index.js]
2import './buttonStories';

这将作为所有故事的基本文件,我们可以将它们全部导入到这个文件中。

<$>[注] 注: Storybook 5.3.0 并稍后采用一个文件名模式: * .stories.js. 为了适应这一惯例, buttonStories.js应更名为button.stories.js。

您还可能遇到一个生成的 1-Button.stories.js 文件,用于使用相同的 Button 标题的演示故事. 为了避免混淆,您可以评论该文件的内容。

然后,在故事目录下创建的每个新文件,我们将导入到该文件中。

步骤3 - 整合添加剂

Addons with Storybook有助于实施额外的功能,使它们更有用和互动。 Storybook 可用的所有添加剂的完整列表可以在 官方网站上找到。

在本文中,我们将为创建的故事添加动作添加器,该动作添加器可用于在 Storybook 中显示事件处理器接收的数据。

手动添加 Addons

我们可以设置插件,如果它尚未默认完成,您将需要遵循这些步骤。

注意: 如果您正在使用 Storybook 5.3.0 或更高版本,对于本教程的目的,您将不需要一个 addons.js 文件,并且可以忽略此步骤。

使用此命令安装 addon 包:

1npm install --save-dev @storybook/addon-actions

然后,将以下内容添加到 .storybook/addons.js:

1[label .storybook/addons.js]
2import '@storybook/addon-actions/register';

现在你的故事书支持addons。

步骤4 — 使用附加操作

为了使我们的按钮故事与 Storybook 互动,我们可以将以下代码添加到 buttonStories.js:

 1[label src/stories/buttonStories.js]
 2import React from 'react';
 3import { storiesOf } from '@storybook/react';
 4import { action } from '@storybook/addon-actions';
 5
 6import Button from '../components/Button';
 7
 8storiesOf('Button', module)
 9  .add('with primary', () => <Button
10    onClick={action('click')}
11    label="Primary Button"
12  />)
13  .add('with outline', () => <Button
14    label="Ouline Button"
15    onClick={action('click')}
16    style={{ background: 'transparent', border: '3px solid #fecd43' }}
17  />)
18  .add('with rounder corners', () => <Button
19    label="Rounded Button"
20    onClick={action('click')}
21    style={{ borderRadius: '15px' }}
22  />)
23  .add('disabled', () => <Button disabled
24    label="Disabled Button"
25    onClick={action('click')}
26    style={{ background: 'gray' , border: 'gray', cursor: 'not-allowed' }}
27  />);

然后运行 Storybook:

Animated gif of Storybook interface displaying the component and Actions tab.

在下面的选项卡上,你会看到一个行动选项卡,在任何我们与按钮交互时,行动都会登录。

步骤5 - 定制主题

有了 Storybook,我们有能力定制使用的默认主题,而 Storybook 附带了默认的光主题。现在,让我们探索如何将其定制为不同的东西。黑暗主题也许是完全不同的东西。

1[label .storybook/config.js]
2import { addParameters } from '@storybook/react';
3import { themes } from '@storybook/theming';
4
5addParameters({
6  options: {
7    theme: themes.dark
8  }
9});

Screenshot of the Storybook interface with dark theme.

<$>[注] 注: Storybook 5.3.0 并稍后引入 manager.js. 以此新公约为主题的步骤在 官方主题文档中讨论。

随着黑暗主题的配置,我们可以观察到整个 Storybook 主题已经切换到黑暗主题,随时可以切换回光明或黑暗主题,取决于我们的偏好。

如果我们想要一个完全不同的主题,我们还可以定义一个动态主题,第一个步骤是为我们的主题创建一个文件,在.storybook文件夹中创建一个名为yourTheme.js的新文件。

以下是pink.js主题的例子:

 1[label .storybook/pink.js]
 2import { create } from '@storybook/theming';
 3
 4export default create ({
 5  base: 'light',
 6  colorPrimary: 'hotpink',
 7  colorSecondary: 'deepskyblue',
 8  // UI
 9  appBg: 'rgb(234, 0, 133)',
10  appContentBg: 'white',
11  appBorderColor: 'white',
12  appBorderRadius: 4,
13  // Typography
14  fontBase: '"Open Sans", sans-serif',
15  fontCode: 'monospace',
16  // Text colors
17  textColor: 'rgb(255, 250, 250)',
18  textInverseColor: 'white',
19  // Toolbar default and active colors
20  barTextColor: 'white',
21  barSelectedColor: 'white',
22  barBg: 'rgb(246, 153, 190)',
23  // Form colors
24  inputBg: 'white',
25  inputBorder: 'silver',
26  inputTextColor: 'black',
27  inputBorderRadius: 4,
28  brandTitle: 'Pink Storybook'
29});

然后,我们可以继续导入pink.js到我们的 Storybook 配置文件中。

1[label .storybook/config.js]
2import pink from './pink';
3
4addParameters({
5  options: {
6    theme: pink
7  }
8});

Screenshot of the Storybook interface with the custom theme.

这给了我们一个与上一个图像相比完全不同的主题。

步骤6 - 部署剧本

一个附带到 Storybook 的功能是,我们可以将我们的 Storybook 部署为静态网站,我们可以部署到我们选择的任何托管选项。

1[label package.json]
2{
3  "scripts": {
4    "build-storybook": "build-storybook -c .storybook -o .out"
5  }
6}

这个脚本会做的是,它将我们的故事书目录构建成一个静态的Web应用程序,并将其输出到一个.out目录中。我们可以运行这个脚本并在构建完成后部署.out目录的内容。

1npm run build-storybook

当构建完成时,我们现在可以使用我们选择的任何主机部署目录的内容。

要测试本地工作,我们可以运行以下命令:

1npx http-server .out

<$>[注]: 注: 您的「package.json」可能具有类似于「build-storybook -s public」的「build-storybook」脚本,而不是指定的「.out」目录,这将静态网站文件输出到「storybook-static」目录中。

这将将文件夹的内容作为静态网站。

结论

在本文中,我们已经学习了如何使用 Storybook 和 React 构建交互式组件,现在我们已经探索了 Storybook 可以实现的可能性,并在我们的 React 项目中如何整合 Storybook 作为组件库的指南。

如果您正在寻找其他框架上的指南,请自由检查 Storybook的官方文档

您也可以在GitHub上找到这篇文章的代码(https://github.com/do-community/scotch-storybook)。

Published At
Categories with 技术
Tagged with
comments powered by Disqus