When developing components using React, there are some common grieves. For example, as a component’s complexity increases, its state can’t be easily traced. When you need to view a component in a certain state, you may need to manually change the properties of the component or change the data returned by the interface (data-driven components), and so on. So I went to learn about Storybook and organized a sharing meeting, which was the first time for our team to share technology.

About Storybook, I tried to use it a year or two ago. At that time, I probably had a limited understanding of componentized development. I just used it for the sake of use, but didn’t feel its usefulness. After several iterations, Storybook has moved to version 6.0, making it easier to use and more elegant.

The picture above is the cover of PPT sharing meeting. If you are interested, please send me a private message. Next, we will get to the topic.

motivation

  • The UI system for the new project needs to be redesigned
  • As the project iterates, component complexity gradually increases, and component status is not easy to trace
  • Pursue more elegant and maintainable coding

The target

This article mainly shares some points with you:

  • Introduces the Storybook
  • Through a small example to show how inNext.jsUsed in the Storybook
  • My coding habits

requirements

Because of the practice involved, there may be the following requirements, but don’t worry, as long as you can understand them:

  • The example is based onNext.jsI talked about this in the last article how to buildNext.jsThe project,You can click hereClone the scaffolding I built locally so I can follow suit.
  • Because it builds on the scaffolding of the previous article, it also has features that need to be understood, such asTypescript,styled-component.

Introduces the Storybook

Storybook is an open source tool that provides a sandbox environment for developing UI components independently of React, Vue, Angular, and other frameworks. It is more organized and efficient to build amazing UIs.

Provide a powerful UIs

  • Build components independently

    You don’t need to put up screens, process data, or build business logic to create components.

  • Simulate hard-to-reach use cases

    Rendering critical states in an application is not easy

  • Use cases as a story

    Save use cases as stories in Javascript that can be accessed during development, testing, and QA.

  • Use plug-ins to reduce workflow

    Use plug-ins to build uIs faster, document components, and simplify workflows.

More reliable components

  • Ensure a consistent user experience

    Every time you write a story, you get a visual of a state. Run through the story quickly and check that the basest UI is correct.

  • Automatic regression test code

    Use the official plugin Storyshots to launch code snapshots.

  • Unit test component

    Unit test the component to make sure it works.

  • Capture UI changes at the pixel level per commit

    Use visual testing tools to identify changes to the UI.

Share and reuse everything

  • Find any component in the project

    Storybook can search any component written, providing a single source of real information for your UI components.

  • Get timely feedback during development

    Deploy Storybook to the cloud and work with the team to implement the UI.

  • Share components across ends and applications

    Each story is a use case that team members can find and decide whether to reuse.

  • Generating documentation

    Write Markdown /MDX to generate customizable documentation for component libraries and design systems.

Using a Storybook

I’ll show you how Storybook works with an example and see how I use Typescript, Styled Components and my coding habits.

The installation

Assuming you have cloned the repository, first install the storybook in your project:

#Install the storybook
yarn add storybook
#Initialize the Storybook project, which is automatically configured based on the project type
npx sb init
#Start the Storybook service
yarn storybook
Copy the code

With that in mind, you can now access the UIs provided by Storybook at http://localhost:6006/ :

It provides several examples by default, such as Button, Header, etc., in SRC /pages/stories:

The file named story.tsx is a story that defines the presentation state of the component we want to define; You may not understand what is a story, behind you to look at the sample after will understand, I first, for example, a person is just like a story, when he has a different mood, will show different expression, at the same time can only see it is a kind of expression, but I now him with pictures of each different expressions, It helps me to analyze the character of the person; Storybooks are like cameras that record different states of components for easy traceability.

designProductOptimCardcomponent

Next, I designed and implemented the ProductOptimCard component. This component is data-driven, that is, the content changes according to the change of data. For convenience, I only defined the title, whether to do, whether to do these three attributes, their changes will show the view in different states, the default effect is as follows:

Here is the component implementation code:

// src/components/towone/ProductOptim/ProductOptimCard/index.tsx
import React from 'react';
import styled from 'styled-components';

interface IProductOptimCardProps {
  data: {
    isMustDo: boolean;
    isFinish: boolean;
    title: string;
  };
}

const Container = styled.div` width: 452px; height: 276px; background: #fefeff; border: 1px solid #edf0fa; Box-shadow: 0px 4px 14px 0px Rgba (0, 10, 71, 0.07); `;
const Content = styled.div` height: 225px; background: #fff; padding-top: 21px; padding-left: 20px; position: relative; `;
const Footer = styled.div` height: 50px; background: #f7f8fa; display: flex; align-items: center; justify-content: space-between; padding-right: 10px; padding-left: 20px; `;
const Title = styled.div` font-size: 16px; font-weight: bold; color: #333; margin-bottom: 14px; `;
const Badge = styled.div<{ isMustDo: boolean} >`
  width: 37px;
  height: 21px;
  background: ${({ isMustDo }) => (isMustDo ? '#0af' : '# 999999')};
  font-weight: bold;
  color: #fefeff;
  font-size: 12px;
  border-radius: 11px 2px 11px 11px;
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
`;
const Text = styled.div` font-size: 14px; color: #666666; margin-bottom: 14px; `;
const MoreText = styled.a` font-size: 14px; color: #333333; `;
const FinishButton = styled.div<{ isFinish: boolean} >`
  width: 60px;
  height: 28px;
  background: ${({ isFinish }) => (isFinish ? '# 999' : '#046eff')};
  color: #fefeff;
  font-size: 12px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
`;

const ProductOptimCard: React.FC<IProductOptimCardProps> = ({ data }) = > {
  const { isMustDo, isFinish, title } = data;

  return (
    <Container>
      <Content>
        <Title>{title}</Title>
        <Text>1. Size: 800 x 800px</Text>
        <Text>2, selling point refining text display (for the same type, standard category)</Text>
        <Text>3. Products account for two thirds of the picture</Text>
        <Text>4. Refer to the main drawing of five excellent similar models from Taobao and Ali (sorted by transaction amount)</Text>
        <Badge isMustDo={isMustDo}>Will do</Badge>
      </Content>
      <Footer>
        <MoreText>More tutorials</MoreText>
        <FinishButton isFinish={isFinish}>To complete the</FinishButton>
      </Footer>
    </Container>
  );
};

export default ProductOptimCard;
Copy the code

Then introduce it on the home page:

// src/pages/index.tsx

/ /...

export default function Home() {
  return (
    <Conotainer>
       <ProductOptimCard
          data={{ isMustDo: false.isFinish: false.title:'Product title optimization'}} />
    </Conotainer>
  );
}
Copy the code

Run yarn Dev to start the project, then open http://localhost:3000/ to view:

The component in the red box is the default style for ProductOptimCard. The component itself has different states: required, unnecessary, completed, unfinished; TSX: SRC /pages/index.tsx: SRC /pages/index.tsx: SRC /pages/index.tsx: SRC /pages/index.tsx: SRC /pages/index.tsx: SRC /pages/index.tsx: SRC /pages/index.tsx: So now we have our Storybook, so scroll down.

In the same directory to create a new ProductOptimCard. Stories. TSX composite file, write story, for ProductOptimCard code is as follows:

import React, { ComponentProps } from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';

import ProductOptimCard from '/';

export default {
  title: 'TWOONE/ProductOptim/ProductOptimCard'.component: ProductOptimCard,
} as Meta;

const Template: Story<ComponentProps<typeof ProductOptimCard>> = (args) = > (
  <ProductOptimCard {. args} / >
);

export const DefaultCard = Template.bind({});
DefaultCard.args = {
  data: {
    isMustDo: false.isFinish: false.title: 'Single product Title Optimization',}};export const MustDoCard = Template.bind({});
MustDoCard.args = {
  data: {
    isMustDo: true.isFinish: false.title: 'Single product Title Optimization',}};export const FinishCard = Template.bind({});
FinishCard.args = {
  data: {
    isMustDo: false.isFinish: true.title: 'Single product Title Optimization',}};export const UnFinishCard = Template.bind({});
UnFinishCard.args = {
  data: {
    isMustDo: false.isFinish: false.title: 'Single product Title Optimization',}};Copy the code

We introduced ProductOptimCard and wrote four states for it, namely DefaultCard, MustDoCard, FinishCard and UnFinishCard. Different data will naturally show different states. Then open http://localhost:6006/ :

The red box is the story we wrote for ProductOptimCard. Click on different states to see what the UI looks like:

As you can see, it’s easy to know and view the different states of this component. If you’re a little excited, click on Docs to view the document.

Import {Box} from ‘@/styles/common’; import {Box} from ‘@/styles/common’; This is usually configured in our tsconfig.json file, but we need to configure it in our storybook file, which allows us to customize the webpack configuration. Open.storybook/main.js and add the following code:

// .storybook/main.js
const path = require('path');

module.exports = {
  // ...
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias[The '@'] = path.resolve(__dirname, '.. /src');
    
    returnconfig; }};Copy the code

So far we’ve seen an example of how to use Storybook, and I’ll talk a little about some of my coding tips.

My coding habits and experience

classification

From the perspective of data acquisition, I divide components into container components and content components:

** Container component: ** gets data from the interface.

** Content component: ** Receive props data, can write story component driver development.

The approximate order in which the story components are written

  • Typescript defines parameters that components receive
  • Set default values for optional types
  • Write stories that describe components in different states

Component writing order

Usually the tripartite libraries introduced by a component are at the top, followed by custom components, so my order here is where the variables are defined in the component, and here is the order I’m used to defining them (from top to bottom), one line apart:

  • Three party libraries

  • Custom Components

  • Picture a constant

  • The Typescript interface

  • Style components

  • Component area

Example code for minimization:

import React from 'react';
import styled from 'styled-components';

import { MySelfComp } from '@/components';

import ICON_LOGO from '@/assets/images/icon.logo.png';

interface IProps {}

const Container = styled.div` `;

const DemoComp: React.FC<IProps> = () = > {
  return <Container></Container>
}

export default DemoComp;
Copy the code

conclusion

So far, I have introduced you to Storybook and how to use it. Of course, this is just the basic usage. In the project, you may encounter different scenarios. I wanted to include the testing process, but I felt it would be too long. I can write another article later. I can briefly introduce a component development process that I think is ideal: Component design and write -> write story -> Jest test -> Enzyme test, for the latter two test libraries, does further improve the robustness of the component, but will increase a lot of work, general small companies really do not need, interested in the class can study by themselves.

The appendix

Storybook 6.0

examples

Marketing and docs

The BBC Psammead 👏

GitLab UI 👏