Noțiuni introductive cu Storybook în React

Ați încercat vreodată să plasați toate componentele UI într-un loc în React?

Dacă ești nou în lumea React, atunci probabil că nu o vei face.

Ce se înțelege prin asta?

Vezi reactiona-frumos-dnd exemple.

Ceea ce ați văzut în exemple se numește povești. Și instrumentul care este folosit pentru a crea povești se numește Storybook.

Acum, ați înțeles despre ce vom vorbi în acest articol. Fără să întâmpinăm să explorăm.

Ce este Storybook?

Storybook este un mediu de dezvoltare izolat cu interfață de utilizator care oferă un loc de joacă pentru componentele dumneavoastră. Ne putem juca cu componentele noastre în diferite moduri fără a rula aplicația noastră principală. Putem rula cartea de povești în portul său cu configurarea.

Nu se limitează la React. Putem folosi cartea de povești cu majoritatea cadrelor frontend precum Vue, Angular, Mithril, Marko, Svelte etc..,

Puteți afla mai multe despre cartea de povești Aici.

Ce este o poveste?

O poveste definește starea redată a componentei dvs. Dacă luăm o componentă comună, o putem folosi în moduri diferite cu recuzită. Putem scrie o poveste pentru fiecare dintre aceste state.

Să presupunem că avem o componentă Button.

Un buton poate exista în diferite stări, cum ar fi dezactivat, încărcare, primar, secundar, mic, mare, mediu etc.. Dacă vom enumera toate stările, atunci va fi foarte dificil să avansăm în tutorial. Cred că înțelegi. Veți obține mai mult atunci când începeți să lucrați cu cartea de povești.

Puteți vedea poveștile butonului în diferite cazuri (Mare, Medie, Mică).

Configurarea Storybook într-un proiect

Vom configura o carte de povești într-un proiect react.

Sa mergem.

  • Creați un proiect react cu următoarea comandă. Puteți numi orice doriți.
npx create-react-app storybook-demo
  • Acum, instalați cartea de povești în proiectul dvs. cu următoarea comandă.
npx sb init

Am finalizat configurarea pentru cartea de povești.

Cartea de povești ne oferă un server separat.

Cum să-l pornești?

Cartea de povești adaugă automat o comandă în fișierul nostru script. Îl puteți verifica în fișierul package.json din secțiunea scripturi. Deocamdată, rulați următoarea comandă pentru a porni serverul de carte de povești.

npm run storybook

Storybook va porni un nou server cu portul dat în secțiunea de scripturi a fișierului package.json. Acesta va deschide automat cartea de povești în browserul nostru implicit (la fel ca și serverul react).

Veți vedea diferite povești în el în mod implicit. Puteți să le eliminați dacă nu doriți sau să le păstrați pentru referință. După cum am discutat în secțiunea anterioară, un buton poate avea mai multe stări, le puteți vedea în cartea de povești (nu toate stările menționate). Vom scrie un set mare de povești pentru buton în ultima secțiune a acestui tutorial.

Explorați diferite secțiuni ale cărții de povești și familiarizați-vă cu diferitele secțiuni. Vom acoperi câteva dintre ele în tutorial.

Să scriem prima noastră poveste.

Testarea cărții de povești

Am văzut cartea de povești rulând și câteva exemple în ea.

  • Creați un folder numit Button în folderul src.
  • Creați fișiere numite Button.jsx, Button.css și constants.js
  • Puneți codul respectiv din fragmentele de mai jos în fișiere.

Button.jsx

import React, { Component } from "react";
import PropTypes from "prop-types";

import "./Button.css";

import { buttonTypes, buttonVariants, buttonSizes } from "./constants";

class Button extends Component {
    static defaultProps = {
        isDisabled: false,
        type: "filled",
        variant: "oval",
        size: "medium",
        backgroundColor: "#1ea7fd",
        textColor: "#ffffff",
    };

    static buttonTypes = buttonTypes;
    static buttonVariants = buttonVariants;
    static buttonSizes = buttonSizes;

    renderButton = () => {
        const {
            text,
            isDisabled,
            type,
            variant,
            size,
            backgroundColor,
            textColor,
            onClick,
        } = this.props;
        return (
            <button
                onClick={onClick}
                className={`default ${variant} ${size} ${
                    isDisabled ? "disabled" : ""
                }`}
                style={
                    type === buttonTypes.outline
                        ? {
                              border: `1px solid ${backgroundColor}`,
                              color: "#000000",
                              backgroundColor: "transparent",
                          }
                        : {
                              backgroundColor: `${backgroundColor}`,
                              border: `1px solid ${backgroundColor}`,
                              color: textColor,
                          }
                }
                disabled={isDisabled}
            >
                {text}
            </button>
        );
    };

    render() {
        return this.renderButton();
    }
}

Button.propTypes = {
    text: PropTypes.string,
    isDisabled: PropTypes.bool,
    type: PropTypes.oneOf([buttonTypes.outline, buttonTypes.filled]),
    variant: PropTypes.oneOf([buttonVariants.oval, buttonVariants.rectangular]),
    size: PropTypes.oneOf([
        buttonSizes.small,
        buttonSizes.medium,
        buttonSizes.large,
    ]),
    backgroundColor: PropTypes.string,
    textColor: PropTypes.string,
    onClick: PropTypes.func,
};

export { Button };

Buton.css

.default {
    border: none;
    cursor: pointer;
    background-color: transparent;
}

.default:focus {
    outline: none;
}

.disabled {
    opacity: 0.75; 
    cursor: not-allowed;
}
.small {
    font-size: 12px;
    padding: 4px 8px;
}

.medium {
    font-size: 14px;
    padding: 8px 12px;
}

.large {
    font-size: 16px;
    padding: 12px 16px;
}

.oval {
    border-radius: 4px;
}

.rectangular {
    border-radius: 0;
}

constante.js

export const buttonTypes = {
    outline: "outline",
    filled: "filled",
};

export const buttonVariants = {
    oval: "oval",
    rectangular: "rectangular",
};

export const buttonSizes = {
    small: "small",
    medium: "medium",
    large: "large",
};

Ce este acel cod?

  Ce este frauda pe facturi și cum puteți rămâne în siguranță?

Am scris o componentă comună pentru Button, care poate fi folosită în moduri diferite. Acum, avem o componentă care poate avea stări diferite.

Să scriem prima noastră poveste urmând pașii de mai jos.

  • Creați un fișier numit Button.stories.jsx
  • Importați React și componenta noastră Button în fișier.
  • Acum, definiți un titlu sau o cale pentru poveștile noastre componente. O vom defini folosind următorul cod.
export default {
   title: ‘common/Button’,
}

Codul de mai sus va plasa toate poveștile care se află în fișierul curent în directorul common/Button/.

  • Exportați un buton cu elemente de recuzită obligatorii, după cum urmează.
export const defaultButton = () => (
    <Button text=”Default Button” onClick={() => {}} />
);

Am finalizat prima noastră poveste. Rulați cartea de povești cu următoarea comandă și vedeți rezultatul.

npm run storybook

Vom scrie mai multe povești, până la urmă, nu vă faceți griji.

Cum este util în dezvoltarea Frontend?

Care este principalul avantaj al folosirii unei cărți de povești?

Să presupunem că lucrăm într-o echipă de 10 membri. Și trebuie să verificăm componentele comune pe care toată lumea le-a scris pentru proiectul de lucru curent.

Cum putem face asta?

Trebuie să mergem la fiecare componentă comună pentru a le verifica. Dar, este consumator de timp și nu este o modalitate preferată pentru noi. Iată noua noastră carte de povești pentru oaspeți.

Cum să-l folosim pentru a depăși problema noastră?

Putem scrie povești pentru componentele comune (orice componente ale interfeței de utilizare) folosind cartea de povești. Și ori de câte ori coechipierul tău dorește să verifice componentele comune ale altora, atunci pur și simplu rulează serverul de carte de povești și vor vedea toate componentele UI acolo, așa cum am văzut mai sus.

Putem face mult mai mult cu componentele redate din cartea de povești. Storybook are un concept numit Addons care conferă superputeri poveștilor noastre.

Să presupunem că trebuie să verificăm capacitatea de răspuns a componentelor UI în cartea de povești în sine, putem folosi un supliment numit Viewport în cartea de povești. Vom afla mai multe despre suplimente în secțiunile următoare.

Lucrul cu Storybook

În această secțiune, vom scrie diferite povești care definesc diferite stări ale componentei noastre comune Button.

A scrie povești nu este atât de dificil. O poveste definește o stare a unei componente. Dacă vedeți recuzita unei componente, atunci veți înțelege cu ușurință diferite cazuri de utilizare ale componentei.

Să scriem câteva povești oferind recuzită opțională.

export const largeButton = () => (
    <Button text="Large Button" onClick={() => {}} size="large" />
);
export const outlineSmallButton = () => (
    <Button
        text="Outline Small Button"
        onClick={() => {}}
        size="small"
        type="outline"
    />
);
export const rectangularLargeButton = () => (
    <Button
        text="Rectangular Large Button"
        onClick={() => {}}
        size="large"
        variant="rectangular"
    />
);


export const disabledButton = () => (
    <Button text="Disabled Button" onClick={() => {}} isDisabled={true} />
);


export const warningButton = () => (
    <Button
        text="Warning Button"
        onClick={() => {}}
        backgroundColor="orange"
    />
);

Cele trei povești de mai sus definesc diferite cazuri de utilizare ale componentei noastre Button. Acum, este rândul tău să adaugi alte cazuri de povești pentru componenta noastră comună. Încercați să adăugați disabledSamllRectangularButton, dangerButton, successDisabledButton etc..,

  11 Instrumente de analiză web open-source pentru o mai bună perspectivă asupra datelor și confidențialitate

Nu voi furniza cod pentru cazurile de mai sus. Trebuie să-l scrii singur pentru a-l înțelege. Puteți vedea codul complet al poveștilor pe care l-am scris până acum.

import React from "react";

import { Button } from "./Button";

export default {
    title: "src/common/Button",
};

export const defaultButton = () => (
    <Button text="Default Button" onClick={() => {}} />
);

export const largeButton = () => (
    <Button text="Large Button" onClick={() => {}} size="large" />
);

export const outlineSmallButton = () => (
    <Button
        text="Outline Small Button"
        onClick={() => {}}
        size="small"
        type="outline"
    />
);

export const rectangularLargeButton = () => (
    <Button
        text="Rectangular Large Button"
        onClick={() => {}}
        size="large"
        variant="rectangular"
    />
);

export const disabledButton = () => (
    <Button text="Disabled Button" onClick={() => {}} isDisabled={true} />
);

export const warningButton = () => (
    <Button
        text="Disabled Button"
        onClick={() => {}}
        backgroundColor="orange"
    />
);

Acum, ai priceput complet despre scrierea poveștilor pentru o componentă.

Să trecem la următoarea secțiune, unde vom afla despre suplimente și despre cum acestea ne stimulează poveștile.

Suplimente de carte de povești

Vom avea mai multe suplimente disponibile implicit. În secțiune, vom explora cele mai utile suplimente pentru dezvoltarea noastră.

Să ne sporim poveștile Button.

Controale

Comenzile adaugă o caracteristică pentru a oferi elemente de recuzită personalizate componentei din cartea de povești în sine. Pentru componenta noastră Button, putem adăuga controale pentru a schimba diferitele elemente de recuzită din cartea de povești.

Să presupunem că trebuie să aflăm cea mai bună culoare pentru culoarea de fundal Buton. Va consuma mult timp dacă îl testăm pentru a verifica culoarea de fundal dând unul câte unul componentului. În schimb, putem adăuga un control care ne permite să alegem culoarea diferită din cartea de povești. Putem testa culoarea de fundal în cartea de povești în sine.

Să vedem cum să adăugăm controale la poveștile noastre Button.

În primul rând, trebuie să definim toate elementele de recuzită de sub titlu, după cum urmează.

export default {
    title: "src/common/Button",
    argTypes: {
        text: { control: "text" },
        backgroundColor: { control: "color" },
        isDisabled: { control: "boolean" },
        size: {
            control: { type: "select", options: ["small", "medium", "large"] },
        },
        type: {
            control: { type: "select", options: ["filled", "outline"] },
        },
        variant: {
            control: { type: "select", options: ["oval", "rectangular"] },
        },
    },
};

Apoi, separați recuzita de componentă și dați-le ca argumente, după cum urmează.

export const outlineSmallButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
outlineSmallButton.args = {
    text: "Outline Small Button",
    size: "small",
    type: "outline",
};

Puteți vedea comenzile în partea de jos a ferestrei de previzualizare a componentelor.

Puteți vedea fila de controale în partea de jos a ferestrei de previzualizare a componentelor. Joacă-te în jurul lui.

Actualizați toate poveștile ca mai sus. Acest lucru este mai degrabă ca cunoașterea sintaxei suplimentelor de carte de povești. În argTypes, am folosit diferite tipuri de controale. Puteți găsi toate comenzile care sunt prezente în cartea de povești Aici.

Poveștile cu butoane actualizate vor arăta după cum urmează.

import React from "react";

import { Button } from "./Button";

export default {
    title: "src/common/Button",
    argTypes: {
        text: { control: "text" },
        backgroundColor: { control: "color" },
        isDisabled: { control: "boolean" },
        size: {
            control: { type: "select", options: ["small", "medium", "large"] },
        },
        type: {
            control: { type: "select", options: ["filled", "outline"] },
        },
        variant: {
            control: { type: "select", options: ["oval", "rectangular"] },
        },
    },
};

export const defaultButton = (args) => <Button {...args} onClick={() => {}} />;
defaultButton.args = {
    text: "Default Button",
};

export const largeButton = (args) => (
    <Button {...args} onClick={() => {}} size="large" />
);
largeButton.args = {
    text: "Large Button",
};

export const outlineSmallButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
outlineSmallButton.args = {
    text: "Outline Small Button",
    size: "small",
    type: "outline",
};

export const rectangularLargeButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
rectangularLargeButton.args = {
    text: "Rectangular Large Button",
    size: "large",
    variant: "rectangular",
};

export const disabledButton = (args) => <Button {...args} onClick={() => {}} />;
disabledButton.args = {
    text: "Disabled Button",
    isDisabled: true,
};

export const warningButton = (args) => <Button {...args} onClick={() => {}} />;
warningButton.args = {
    text: "Warning Button",
    backgroundColor: "orange",
};

Acțiuni

Acțiunile sunt evenimente în JavaScript. Putem face clic pe un buton care este un eveniment în JavaScript. Putem face unele acțiuni la clic pe buton folosind addonul de acțiuni.

  Cum să găsești pe cineva pe LinkedIn după adresa de e-mail

Cu acțiuni, putem testa dacă evenimentele funcționează corect sau nu. Nu se poate face clic pe butonul dezactivat, iar butonul activat trebuie să fie clicat. O putem asigura folosind acțiunile.

Să vedem cum să adăugați o acțiune la clic pe buton.

Am dat o funcție anonimă elementelor de recuzită onClick anterior. Acum, trebuie să-l actualizăm.

  • Importați acțiunea din suplimentul carte de povești folosind următoarea declarație.
import { action } from "@storybook/addon-actions";
  • Înlocuiți toate () => {} cu următoarea declarație.
action("Button is clicked!")

Acum, accesați cartea de povești și faceți clic pe un buton. Veți vedea mesajul tipărit sub fila de acțiuni care se află lângă fila de controale. Mesajul nu va fi tipărit dacă faceți clic pe butonul dezactivat deoarece este dezactivat.

Putem folosi acțiunea pentru diferite evenimente precum onChange, onMouseOver, onMouseOut etc., pentru a ne asigura că funcționează corect. Încercați să implementați același lucru pentru onChange pentru un element de intrare.

Consultați documentația pentru acțiuni Aici.

fundal

Putem schimba fundalul ferestrei de previzualizare folosind addonul de fundal. Nu trebuie să scriem niciun cod. Schimbați-l în cartea de povești. Puteți vedea gif-ul mai jos.

Vizualizarea

De asemenea, putem testa capacitatea de răspuns a componentelor noastre în cartea de povești. Consultați gif-ul de mai jos pentru a afla mai multe despre opțiunile de vizualizare.

Docs

Ne putem documenta componentele în cartea de povești folosind addon-ul docs. Este mai util atunci când lucrăm în echipă. Ei vor citi componenta și o vor înțelege direct. Economisește mult timp pentru dezvoltatori.

În fereastra de previzualizare a componentelor cărților de povești, puteți vedea Documente în dreapta sus, în fila Canvas. Acesta va conține toate documentele din toate poveștile unei componente. Trebuie să folosim Button.stories.mdx dacă vrem să documentăm pentru componenta care include atât markdown, cât și redarea componentei. Doar scriem un cod suplimentar de reducere în interiorul acestuia, împreună cu poveștile componente.

Scriem un document pentru poveștile noastre. Codul include markdown și randarea componentelor. Totul este doar să înveți sintaxa. Îl vei primi la prima vedere.

Să vedem codul document Button.stories.mdx.

<!--- Button.stories.mdx -->

import {
    Meta,
    Story,
    Preview,
    ArgsTable
} from '@storybook/addon-docs/blocks';

import { Button } from './Button';

<Meta title="MDX/Button" component={Button} />

# Button Documentation

With `MDX` we can define a story for `Button` right in the middle of our
Markdown documentation.

<ArgsTable of={Button} />

export const Template = (args) => <Button {...args} />

## Default Button
We can write the documentation related to the Default Button
<Preview>
    <Story name="Default Button" args={{
        text: 'Default Button'
    }}>
    {Template.bind({})}
   </Story>
</Preview>

## Large Button
We are writing sample docs for two stories, you can write rest of them
<Preview>
    <Story name="Large Button" args={{
        text: "Large Button",
        }}>
        {Template.bind({})}
    </Story>
</Preview>

Aflați mai multe despre componentele de documentare Aici.

Puteți afla mai multe despre suplimente Aici.

Concluzie

Sper că v-a plăcut tutorialul și ați aflat despre cartea de povești. Și folosește-l eficient în echipa ta pentru a-ți face munca productivă.

Nou în React? Consultați aceste resurse de învățare.

Codare fericită 🙂