Primeros pasos con Storybook en React

¿Alguna vez ha intentado colocar todos los componentes de su interfaz de usuario en un lugar en React?

Si eres nuevo en el mundo de React, probablemente no lo harás.

¿Qué significa eso?

Ver el reaccionar-hermoso-dnd ejemplos

Lo que has visto en los ejemplos se llaman historias. Y la herramienta que se usa para crear historias se llama Storybook.

Ahora, has entendido de lo que te vamos a hablar en este artículo. Sin preámbulos vamos a explorar.

¿Qué es un libro de cuentos?

Storybook es un entorno de desarrollo aislado de interfaz de usuario que proporciona un campo de juego para sus componentes. Podemos jugar con nuestros componentes de diferentes maneras sin ejecutar nuestra aplicación principal. Podemos ejecutar el libro de cuentos en su puerto con la configuración.

No se limita a React. Podemos usar storybook con la mayoría de los marcos frontend como Vue, Angular, Mithril, Marko, Svelte, etc.,

Puedes encontrar más sobre el libro de cuentos aquí.

¿Qué es una historia?

Una historia define el estado renderizado de su componente. Si tomamos un componente común, podemos usarlo de diferentes maneras con accesorios. Podemos escribir una historia para cada uno de esos estados.

Digamos que tenemos un componente Button.

Un botón puede existir en diferentes estados como deshabilitado, cargando, primario, secundario, pequeño, grande, mediano, etc. Si enumeramos todos los estados, será muy difícil avanzar en el tutorial. Creo que lo entiendes. Lo obtendrás más cuando comiences a trabajar con el libro de cuentos.

Puedes ver las historias del botón en diferentes casos (Grande, Mediano, Pequeño).

Configuración de Storybook en un proyecto

Configuraremos un libro de cuentos en un proyecto de reacción.

Vamos.

  • Cree un proyecto de reacción con el siguiente comando. Puedes nombrar lo que quieras.
npx create-react-app storybook-demo
  • Ahora, instale el libro de cuentos en su proyecto con el siguiente comando.
npx sb init

Hemos completado la configuración del libro de cuentos.

El libro de cuentos proporciona un servidor separado para nosotros.

¿Cómo empezar?

El libro de cuentos agrega automáticamente un comando en nuestro archivo de script. Puede verificarlo en el archivo package.json dentro de la sección de scripts. Por el momento, ejecute el siguiente comando para iniciar el servidor de libros de cuentos.

npm run storybook

Storybook iniciará un nuevo servidor con el puerto indicado en la sección de secuencias de comandos del archivo package.json. Abrirá automáticamente el libro de cuentos en nuestro navegador predeterminado (igual que el servidor de reacción).

Verá diferentes historias en él de forma predeterminada. Puede eliminarlos si no lo desea o conservarlos como referencia. Como comentamos en la sección anterior, un botón puede tener múltiples estados, puede verlos en el libro de cuentos (no se mencionan todos los estados). Vamos a escribir un gran conjunto de historias para el botón en la última sección de este tutorial.

Explore diferentes secciones del libro de cuentos y familiarícese con las diferentes secciones. Vamos a cubrir algunos de ellos en el tutorial.

Escribamos nuestra primera historia.

Libro de cuentos de prueba

Hemos visto correr el libro de cuentos y algunos ejemplos en él.

  • Cree una carpeta llamada Botón dentro de la carpeta src.
  • Cree archivos llamados Button.jsx, Button.css y constants.js
  • Coloque el código respectivo de los fragmentos a continuación en los archivos.

Botón.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 };

Botón.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;
}

constantes.js

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

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

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

¿Qué es ese código?

Hemos escrito un componente común para Button que se puede usar de diferentes maneras. Ahora, tenemos un componente que puede tener diferentes estados.

Escribamos nuestra primera historia siguiendo los pasos a continuación.

  • Cree un archivo llamado Button.stories.jsx
  • Importe React y nuestro componente Button al archivo.
  • Ahora, defina un título o una ruta para nuestras historias componentes. Lo definiremos usando el siguiente código.
export default {
   title: ‘common/Button’,
}

El código anterior colocará todas las historias que están en el archivo actual dentro del directorio common/Button/.

  • Exporte un botón con accesorios obligatorios de la siguiente manera.
export const defaultButton = () => (
    <Button text=”Default Button” onClick={() => {}} />
);

Hemos completado nuestra primera historia. Ejecute el libro de cuentos con el siguiente comando y vea el resultado.

npm run storybook

Escribiremos más historias, al final, no te preocupes.

¿Cómo es útil en el desarrollo Frontend?

¿Cuál es la principal ventaja de usar un libro de cuentos?

Digamos que estamos trabajando en un equipo de 10 miembros. Y necesitamos verificar los componentes comunes que todos han escrito para el proyecto de trabajo actual.

¿Cómo podemos hacer eso?

Tenemos que ir a cada componente común para comprobarlos. Pero lleva mucho tiempo y no es una forma preferida para nosotros. Aquí viene nuestro nuevo libro de cuentos para invitados.

¿Cómo utilizarlo para superar nuestro problema?

Podemos escribir historias para los componentes comunes (cualquier componente de la interfaz de usuario) usando un libro de cuentos. Y cada vez que su compañero de equipo quiera verificar los componentes comunes de los demás, simplemente ejecuta el servidor del libro de cuentos y verá todos los componentes de la interfaz de usuario allí, como hemos visto anteriormente.

Podemos hacer mucho más con los componentes representados en el libro de cuentos. Storybook tiene un concepto llamado Addons que le da superpoderes a nuestras historias.

Digamos que tenemos que verificar la capacidad de respuesta de los componentes de la interfaz de usuario en el libro de cuentos, podemos usar un complemento llamado Viewport en el libro de cuentos. Aprenderemos más sobre los complementos en las próximas secciones.

Trabajar con el libro de cuentos

En esta sección, escribiremos diferentes historias definiendo diferentes estados de nuestro componente común Botón.

Escribir historias no es tan difícil. Una historia define un estado de un componente. Si ve los accesorios de un componente, comprenderá fácilmente los diferentes casos de uso del componente.

Escribamos algunas historias dando accesorios opcionales.

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

Las tres historias anteriores definen diferentes casos de uso de nuestro componente Button. Ahora, es su turno de agregar algunos otros casos de historias para nuestro componente común. Intente agregar disabledSamllRectangularButton, dangerButton, successDisabledButton, etc.,

No voy a proporcionar código para los casos anteriores. Tienes que escribirlo por tu cuenta para entenderlo. Puedes ver el código completo de las historias que hemos escrito hasta ahora.

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

Ahora, tiene un control total sobre la escritura de historias para un componente.

Pasemos a la siguiente sección, donde aprenderemos sobre los complementos y cómo mejoran nuestras historias.

Complementos de libros de cuentos

Tendremos varios complementos disponibles de forma predeterminada. En la sección, exploraremos los complementos más útiles para nuestro desarrollo.

Impulsemos nuestras historias de Botones.

Control S

Los controles agregan una función para brindar accesorios personalizados al componente en el propio libro de cuentos. Para nuestro componente Botón, podemos agregar controles para cambiar los diferentes accesorios en el libro de cuentos.

Digamos que tenemos que encontrar el mejor color para el color de fondo del botón. Llevará mucho tiempo si lo probamos para verificar el color de fondo dando uno por uno al componente. En su lugar, podemos agregar un control que nos permita elegir el color diferente en el libro de cuentos. Podemos probar el color de fondo en el propio libro de cuentos.

Veamos cómo agregar controles a nuestras historias de Button.

Primero, tenemos que definir todos los accesorios debajo del título de la siguiente manera.

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

A continuación, separe los accesorios del componente y délos como argumentos de la siguiente manera.

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

Puede ver los controles en la parte inferior de la ventana de vista previa del componente.

Puede ver la pestaña de controles en la parte inferior de la ventana de vista previa del componente. Juega a su alrededor.

Actualice todas las historias como se indicó anteriormente. Todo esto es más como conocer la sintaxis de los complementos del libro de cuentos. En los argTypes, hemos utilizado diferentes tipos de controles. Puede encontrar todos los controles que están presentes en el libro de cuentos. aquí.

Las historias de botones actualizadas se verán de la siguiente manera.

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

Comportamiento

Las acciones son eventos en JavaScript. Podemos hacer clic en un botón que es un evento en JavaScript. Podemos hacer algunas acciones al hacer clic en el botón usando el complemento de acciones.

Con acciones, podemos probar si los eventos están funcionando correctamente o no. No se puede hacer clic en el botón deshabilitado y se debe hacer clic en el botón habilitado. Podemos asegurarlo usando las acciones.

Veamos cómo agregar acción al clic del botón.

Anteriormente le hemos dado una función anónima a los accesorios onClick. Ahora, tenemos que actualizarlo.

  • Importe la acción desde el complemento del libro de cuentos usando la siguiente declaración.
import { action } from "@storybook/addon-actions";
  • Reemplace todos los () => {} con la siguiente declaración.
action("Button is clicked!")

Ahora, ve al libro de cuentos y haz clic en un botón. Verá el mensaje impreso debajo de la pestaña de acciones que está al lado de la pestaña de controles. El mensaje no se imprimirá si hace clic en el botón deshabilitado ya que está deshabilitado.

Podemos usar la acción para diferentes eventos como onChange, onMouseOver, onMouseOut, etc., para asegurarnos de que funcionan correctamente. Intente implementar lo mismo para onChange para un elemento de entrada.

Consulte la documentación de las acciones. aquí.

Fondo

Podemos cambiar el fondo de la ventana de vista previa usando el complemento de fondo. No tenemos que escribir ningún código. Solo cámbialo dentro del libro de cuentos. Puedes ver el gif a continuación.

vista

También podemos probar la capacidad de respuesta de nuestros componentes en el libro de cuentos. Vea el gif a continuación para conocer las opciones de la ventana gráfica.

Documentos

Podemos documentar nuestros componentes en el libro de cuentos usando el complemento docs. Es más útil cuando estamos trabajando en equipo. Ellos leerán el componente y lo entenderán directamente. Ahorra mucho tiempo a los desarrolladores.

En la ventana de vista previa de los componentes de los libros de cuentos, puede ver Documentos en la parte superior derecha de la pestaña Lienzo. Contendrá todos los documentos de todas las historias de un componente. Tenemos que usar Button.stories.mdx si queremos documentar el componente que incluye tanto la reducción como la representación del componente. Simplemente escribimos un código de descuento adicional dentro de él junto con las historias de los componentes.

Estamos escribiendo un documento para nuestras historias. El código incluye Markdown y representación de componentes. Todo es solo aprender la sintaxis. Lo obtendrás a primera vista.

Veamos el código 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>

Más información sobre los componentes de documentación aquí.

Puede obtener más información sobre los complementos aquí.

Conclusión

Espero que hayas disfrutado el tutorial y hayas aprendido sobre el libro de cuentos. Y úselo de manera efectiva en su equipo para que su trabajo sea productivo.

¿Nuevo en Reaccionar? Echa un vistazo a estos recursos de aprendizaje.

Codificación feliz 🙂