Iniziare con Storybook in React

Hai mai provato a posizionare tutti i componenti dell’interfaccia utente in un posto in React?

Se sei nuovo nel mondo di React, probabilmente non lo farai.

Cosa si intende con questo?

Vedi il reagire-bella-dnd esempi.

Quelle che hai visto negli esempi si chiamano storie. E lo strumento utilizzato per creare storie si chiama Storybook.

Ora hai capito di cosa parleremo in questo articolo. Senza indugi, esploriamo.

Cos’è il libro delle fiabe?

Storybook è un ambiente di sviluppo isolato dall’interfaccia utente che fornisce un parco giochi per i tuoi componenti. Possiamo giocare con i nostri componenti in modi diversi senza eseguire la nostra app principale. Possiamo eseguire il libro di fiabe nella sua porta con l’installazione.

Non è limitato a React. Possiamo usare storybook con la maggior parte dei framework di frontend come Vue, Angular, Mithril, Marko, Svelte, ecc.,

Puoi trovare ulteriori informazioni sul libro di fiabe qui.

Cos’è una storia?

Una storia definisce lo stato di rendering del tuo componente. Se prendiamo un componente comune, possiamo usarlo in modi diversi con gli oggetti di scena. Possiamo scrivere una storia per ciascuno di questi stati.

Supponiamo di avere un componente Button.

Un pulsante può esistere in diversi stati come disabilitato, in caricamento, primario, secondario, piccolo, grande, medio, ecc., Se elenchiamo tutti gli stati, sarà molto difficile andare avanti nel tutorial. Penso che tu lo capisca. Lo otterrai di più quando inizi a lavorare con il libro di fiabe.

Puoi vedere le storie del pulsante in diversi casi (Grande, Medio, Piccolo).

Impostazione di Storybook in un progetto

Prepareremo un libro di fiabe in un progetto di reazione.

Andiamo.

  • Crea un progetto di reazione con il seguente comando. Puoi nominare quello che vuoi.
npx create-react-app storybook-demo
  • Ora installa lo storybook nel tuo progetto con il seguente comando.
npx sb init

Abbiamo completato la configurazione del libro di fiabe.

Il libro di fiabe fornisce un server separato per noi.

Come avviarlo?

Il libro di fiabe aggiunge automaticamente un comando nel nostro file di script. Puoi verificarlo nel file package.json all’interno della sezione degli script. Per il momento, esegui il seguente comando per avviare il server del libro di fiabe.

npm run storybook

Storybook avvierà un nuovo server con la porta indicata nella sezione degli script del file package.json. Aprirà automaticamente il libro di fiabe nel nostro browser predefinito (lo stesso del server di reazione).

Vedrai diverse storie in esso per impostazione predefinita. Puoi rimuoverli se non vuoi o tenerli come riferimento. Come abbiamo discusso nella sezione precedente, un pulsante può avere più stati, puoi vederli nello storybook (non tutti gli stati menzionati). Scriveremo un’ampia serie di storie per il pulsante nell’ultima sezione di questo tutorial.

Esplora diverse sezioni del libro di fiabe e acquisisci familiarità con le diverse sezioni. Ne parleremo alcuni nel tutorial.

Scriviamo la nostra prima storia.

Test libro di fiabe

Abbiamo visto il libro di fiabe in esecuzione e alcuni esempi in esso.

  • Crea una cartella chiamata Button all’interno della cartella src.
  • Crea file chiamati Button.jsx, Button.css e constants.js
  • Inserisci il rispettivo codice dai frammenti di seguito nei file.

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 };

Button.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;
}

costanti.js

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

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

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

Cos’è quel codice?

Abbiamo scritto un componente comune per Button che può essere utilizzato in diversi modi. Ora abbiamo un componente che può avere stati diversi.

Scriviamo la nostra prima storia seguendo i passaggi seguenti.

  • Crea un file chiamato Button.stories.jsx
  • Importa React e il nostro componente Button nel file.
  • Ora, definisci un titolo o un percorso per le nostre storie componenti. Lo definiremo usando il seguente codice.
export default {
   title: ‘common/Button’,
}

Il codice precedente inserirà tutte le storie che si trovano nel file corrente all’interno della directory common/Button/.

  • Esporta un pulsante con oggetti di scena obbligatori come segue.
export const defaultButton = () => (
    <Button text=”Default Button” onClick={() => {}} />
);

Abbiamo completato la nostra prima storia. Esegui lo storybook con il seguente comando e guarda l’output.

npm run storybook

Scriveremo altre storie, alla fine, non ti preoccupare.

In che modo è utile nello sviluppo di frontend?

Qual è il principale vantaggio di utilizzare un libro di fiabe?

Diciamo che stiamo lavorando in un team di 10 membri. E dobbiamo controllare i componenti comuni che tutti hanno scritto per l’attuale progetto di lavoro.

Come possiamo farlo?

Dobbiamo andare in ogni componente comune per controllarli. Ma richiede tempo e non è un modo preferito per noi. Ecco che arriva il nostro nuovo libro di fiabe per gli ospiti.

Come utilizzarlo per superare il nostro problema?

Possiamo scrivere storie per i componenti comuni (qualsiasi componente dell’interfaccia utente) utilizzando il libro di fiabe. E ogni volta che il tuo compagno di squadra vuole controllare i componenti comuni degli altri, esegue semplicemente il server del libro di fiabe e vedrà lì tutti i componenti dell’interfaccia utente come abbiamo visto sopra.

Possiamo fare molto di più con i componenti renderizzati nel libro di fiabe. Storybook ha un concetto chiamato Addons che conferisce superpoteri alle nostre storie.

Diciamo che dobbiamo controllare la reattività dei componenti dell’interfaccia utente nel libro di fiabe stesso, possiamo usare un componente aggiuntivo chiamato Viewport nel libro di fiabe. Impareremo di più sui componenti aggiuntivi nelle prossime sezioni.

Lavorare con Storybook

In questa sezione, scriveremo storie diverse che definiscono diversi stati del nostro componente comune Button.

Scrivere storie non è così difficile. Una storia definisce uno stato di un componente. Se vedi gli oggetti di scena di un componente, capirai facilmente i diversi casi d’uso del componente.

Scriviamo alcune storie fornendo oggetti di scena facoltativi.

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"
    />
);

Le tre storie precedenti definiscono diversi casi d’uso del nostro componente Button. Ora tocca a te aggiungere altri casi di storie per la nostra componente comune. Prova ad aggiungere disabledSamllRectangularButton, dangerButton, successDisabledButton, ecc.,

Non fornirò il codice per i casi di cui sopra. Devi scriverlo da solo per capirlo. Puoi vedere il codice completo delle storie che abbiamo scritto fino ad ora.

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"
    />
);

Ora hai una presa completa sulla scrittura di storie per un componente.

Passiamo alla sezione successiva in cui impareremo a conoscere i componenti aggiuntivi e come potenziano le nostre storie.

Componenti aggiuntivi del libro di fiabe

Avremo più componenti aggiuntivi disponibili per impostazione predefinita. Nella sezione esploreremo gli addon più utili per il nostro sviluppo.

Potenziamo le nostre storie Button.

Controlli

I controlli aggiungono una funzionalità per fornire oggetti di scena personalizzati al componente nel libro di fiabe stesso. Per il nostro componente Button, possiamo aggiungere controlli per modificare i diversi oggetti di scena nel libro di fiabe.

Supponiamo di dover trovare il colore migliore per il colore di sfondo del pulsante. Richiederà molto tempo se lo testiamo per controllare il colore di sfondo dando uno per uno al componente. Invece, possiamo aggiungere un controllo che ci permetta di scegliere il colore diverso nel libro delle fiabe. Possiamo testare il colore di sfondo nel libro di fiabe stesso.

Vediamo come aggiungere controlli alle nostre storie Button.

Innanzitutto, dobbiamo definire tutti gli oggetti di scena sotto il titolo come segue.

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"] },
        },
    },
};

Successivamente, separa gli oggetti di scena dal componente e forniscili come argomenti come segue.

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

Puoi vedere i controlli nella parte inferiore della finestra di anteprima del componente.

Puoi vedere la scheda dei controlli nella parte inferiore della finestra di anteprima del componente. Giocaci intorno.

Aggiorna tutte le storie come sopra. Tutto questo è più come conoscere la sintassi dei componenti aggiuntivi del libro di fiabe. Negli argTypes, abbiamo utilizzato diversi tipi di controlli. Puoi trovare tutti i controlli che sono presenti nel libro delle fiabe qui.

Le storie dei pulsanti aggiornate avranno il seguente aspetto.

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",
};

Azioni

Le azioni sono eventi in JavaScript. Possiamo fare clic su un pulsante che è un evento in JavaScript. Possiamo eseguire alcune azioni al clic del pulsante utilizzando l’addon delle azioni.

Con le azioni, possiamo verificare se gli eventi funzionano correttamente o meno. Il pulsante disabilitato non può essere cliccato e il pulsante abilitato deve essere cliccabile. Possiamo assicurarlo usando le azioni.

Vediamo come aggiungere un’azione al clic del pulsante.

In precedenza abbiamo assegnato una funzione anonima agli oggetti di scena onClick. Ora dobbiamo aggiornarlo.

  • Importa l’azione dall’addon del libro di fiabe utilizzando la seguente istruzione.
import { action } from "@storybook/addon-actions";
  • Sostituisci tutte le () => {} con la seguente istruzione.
action("Button is clicked!")

Ora vai al libro di fiabe e fai clic su un pulsante. Vedrai il messaggio stampato sotto la scheda delle azioni che si trova accanto alla scheda dei controlli. Il messaggio non verrà stampato se si fa clic sul pulsante disabilitato poiché è disabilitato.

Possiamo usare l’azione per diversi eventi come onChange, onMouseOver, onMouseOut, ecc., per assicurarci che funzionino correttamente. Prova a implementare lo stesso per onChange per un elemento di input.

Vedere la documentazione per le azioni qui.

Sfondo

Possiamo cambiare lo sfondo della finestra di anteprima usando l’addon sfondo. Non dobbiamo scrivere alcun codice. Basta cambiarlo all’interno del libro di fiabe. Puoi vedere la gif qui sotto.

Finestra

Possiamo anche testare la reattività dei nostri componenti nel libro di fiabe. Guarda la gif qui sotto per scoprire le opzioni del viewport.

Documenti

Possiamo documentare i nostri componenti nel libro di fiabe utilizzando l’addon docs. È più utile quando lavoriamo in squadra. Leggeranno il componente e lo capiranno direttamente. Fa risparmiare molto tempo agli sviluppatori.

Nella finestra di anteprima dei componenti dei libri di fiabe puoi vedere i documenti in alto a destra nella scheda Canvas. Conterrà tutti i documenti di tutte le storie di un componente. Dobbiamo usare Button.stories.mdx se vogliamo documentare per il componente che include sia il markdown che il rendering del componente. Scriviamo solo del codice di markdown extra al suo interno insieme alle storie dei componenti.

Stiamo scrivendo un documento per le nostre storie. Il codice include il markdown e il rendering dei componenti. Sta solo imparando la sintassi. Lo capirai a prima vista.

Vediamo il codice del documento 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>

Ulteriori informazioni sui componenti di documentazione qui.

Puoi trovare ulteriori informazioni sui componenti aggiuntivi qui.

Conclusione

Spero che il tutorial ti sia piaciuto e che tu abbia imparato a conoscere il libro di fiabe. E usalo in modo efficace nel tuo team per rendere produttivo il tuo lavoro.

Nuovo per reagire? Dai un’occhiata a queste risorse di apprendimento.

Buona programmazione 🙂