Serie Storybook: Escribiendo componentes - .stories.jsx vs stories.mdx
Fernando Cutire 🔨
Posted on October 15, 2021
📰 En este artículo aprenderás
- Los archivos que acepta Storybook .stories.jsx y .stories.mdx
- Cómo se visualizan estos archivos en el navegador
- Cuando usar cual y por qué
🗨️ Contenido
Hora de construir
Perfecto, hasta este momento debes de conocer la problemática que resuelve Storybook y como preparar tu entorno en local, así que solo falta construir.
El problema: Construir en storybook
Dentro de la plantilla que construiste en el capítulo anterior te encontrarás con una introducción y otros archivos que simulan componentes, algo que puedes ver en tu navegador si correr npm run start-storybook
.
Esto que observa a la derecha, representan los diferentes tipos de archivos que construiremos en storybook
Storybook: Las historias del libro
Una historia captura el estado renderizado de un componente de la interfaz de usuario. Los desarrolladores escriben varias historias por componente que describen todos los estados "interesantes" que un componente puede soportar.
La CLI creó componentes de ejemplo que demuestran los tipos de componentes que puede crear con Storybook: botón, encabezado y página.
Cada componente de ejemplo tiene un conjunto de historias que muestran los estados que apoya. Puede explorar las historias en la interfaz de usuario y ver el código detrás de ellas en archivos que terminan en .stories.js o .stories.ts. Las historias están escritas en formato Component Story Format (CSF), un estándar basado en módulos ES6, para escribir ejemplos de componentes.
La pequeña documentación es algo personal de cada historia y se refiere en su mayoría a descripción de los controles. Es bueno saber que se pueden construir páginas enteras de documentación pero eso tiene su propio archivo que veremos más adelante
En la captura de pantalla anterior estábamos mostrando el componente botón y nos basaremos en él para explicar los historias.
El botón en realidad lo constituyen tres archivos:
- button.jsx (el componente en jsx)
- button.css (los estilos de el componente)
- button.stories.jsx (la historia de storybook sobre el componente)
Ahora entremos a cada uno de estos archivos y veamos su código.
Button.jsx
Este componente es uno normal de React , como ves importa las librerías React y Proptypes. También importa estilos CSS
import React from 'react';
import PropTypes from 'prop-types';
import './button.css';
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (
<button
type="button"
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
style={backgroundColor && { backgroundColor }}
{...props}
>
{label}
</button>
);
};
Más abajo es cuando se torna interesante, como viste en el componente se le pasan parámetros (props) al componente botón, esto se define mejor en:
Button.propTypes = {
/**
* Is this the principal call to action on the page?
*/
primary: PropTypes.bool,
/**
* What background color to use
*/
backgroundColor: PropTypes.string,
/**
* How large should the button be?
*/
size: PropTypes.oneOf(['small', 'medium', 'large']),
/**
* Button contents
*/
label: PropTypes.string.isRequired,
/**
* Optional click handler
*/
onClick: PropTypes.func,
};
Button.defaultProps = {
backgroundColor: null,
primary: false,
size: 'medium',
onClick: undefined,
};
Dentro de Button.propTypes están incluidos como puedes ver los controles del componente. Dependiendo del control habrá diferentes opciones, por ejemplo size solo acepta tres valores, small, medium o large, pero backgroundColor acepta una cadena.
Habrás notado que arriba de cada control hay una pequeña documentación. Esta se refiere a la descripción que aparece en el punto 3 de Pequeña documentación.
Dentro Button.defaultProps están los valores por defecto del componente, dándole a cada control un valor por defecto a mostrarse.
button.css
.storybook-button {
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 700;
border: 0;
border-radius: 3em;
cursor: pointer;
display: inline-block;
line-height: 1;
}
.storybook-button--primary {
color: white;
background-color: #1ea7fd;
}
.storybook-button--secondary {
color: #333;
background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
}
.storybook-button--small {
font-size: 12px;
padding: 10px 16px;
}
.storybook-button--medium {
font-size: 14px;
padding: 11px 20px;
}
.storybook-button--large {
font-size: 16px;
padding: 12px 24px;
}
Aquí es solo una hoja de estilos para nuestro componente.
Por supuesto, como css, también se puede usar scss o sass
Button.stories.jsx
Es en este archivo donde storybook se comunica con nuestro componente React , Button.jsx
import React from 'react';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
argTypes: {
backgroundColor: { control: 'color' },
},
};
En la primera parte se importan los componentes, se exporta un default , este incluye el título que se mostrará en el storybook, el nombre del componente (en este caso Button) y unos argTypes que en este caso especificar un backgroundColor.
Siguiendo más abajo
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Button',
};
export const Secondary = Template.bind({});
Secondary.args = {
label: 'Button',
};
export const Large = Template.bind({});
Large.args = {
size: 'large',
label: 'Button',
};
export const Small = Template.bind({});
Small.args = {
size: 'small',
label: 'Button',
};
Se crea un componente Template que se le coloca un componente Button y se le pasan argumentos.
Después se ve que se exportan 5 const, Primary, Secondary, Large y Small. Estas corresponden a la sección de cada uno de los tipos de botón. Por eso puedes ver que se le pueden colocar argumentos a cada uno.
Y esto sería lo básico para escribir componentes y mostrarlos en storybook. Ves que puedes colocar controles y asignar componentes de react.
Storybook: documentando el trayecto
Así como hay componentes , también necesitamos una documentación más exhaustiva, un lienzo blanco donde escribir.
Este archivo corresponde a los que tienen terminación .stories.mdx
Como es en el caso de Introduction. Si vamos al archivo, es un documento algo largo donde que nos importa son que puedes importar addons de storybook, que sencillamante son extensiones que dan funcionalidades especiales, para motivos de esta serie, se ve una sencilla como es Meta, pero existen más que se pueden ver la documentación de storybook. Otro detalle importante es que se pueden colocar estilos a la documentación. También, esta documentación se puede escribir en formato markdown y html, dentro del mismo archivo y aún así funciona de maravilla como se muestra en el ejemplo.
# Welcome to Storybook
Storybook helps you build UI components in isolation from your app's business logic, data, and context.
That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.
Browse example stories now by navigating to them in the sidebar.
View their code in the `src/stories` directory to learn how they work.
We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages.
<div className="subheading">Configure</div>
¿ .stories.mdx o .stories.jsx ?
Usar documentación o un componente, la respuesta se da por si sola. Si buscas mostrar los componentes que has hecho en React, es preciso emplear un .stories.jsx y proporcionar controles para que tu equipo pueda observar las diferentes variantes del botón, campo de texto o componente que quieras mostrar.
Por el otro lado , usar .stories.mdx se refiere más que nada a mencionar ciertas guías a tu equipo, guías que no requieren de mostrar el componente necesariamente (aunque también se puede importar y colocar dentro de este tipo de archivos), sino más bien para informar. Por eso es que se creó este tipo de archivo.
🔥 Recapitulando
Repasemos lo que aprendiste
- Existen 2 tipos de archivos principales, que storybook lee
.stories.jsx
(typescript tsx) y.stories.mdx
- Un
.stories.jsx
recibe un componente de react (usualmente .jsx o .tsx si es en typescript) - El componente de react es común, importando estilos y librerías necesarias, pero se le añaden propiedades que terminan siendo controles de storybook
- Para saber si usar .stories.jsx o .stories.mdx, hazte la pregunt ¿Necesito documentación o mostrar un componente con controles? Si es documentación
.stories.mdx
, un componente y permitir al usuario tener controles.stories.jsx
🔚 Fin
Sabes crear componentes .stories.jsx
y documentación .stories.mdx
Puedes dar controles a los componentes para que tu equipo interactúe con ellos y puedes documentar sus propiedades.
Puedes escribir documentación usando .stories.mdx
Puedes distinguir cuando usar.stories.jsx
.stories.mdx
Te invito a que veas mi repositorio de github, con el material.
📺 Continua la serie
Esto no se termina aquí, puedes continuar los siguientes capítulos de la serie Storybook para averiguar como termina.
Serie Storybook: Usando storybook para desarrollo de componentes
Entendiendo el concepto de Storybook, cuando usarlo e introducción para desarrolladores
Serie Storybook: Corriendo storybook en local + Código en github
Desarrollarás un repositorio de Storybook en tu computadora local
Serie Storybook: Escribiendo componentes - .stories.jsx vs stories.mdx
Desarrollarás .stories.jsx y .stories.mdx , aprenderás como se forman y como funciona el núcleo principal en Storybook.
📚 Lecturas Adicionales
Leer es bueno, aquí te dejo algunas fuentes adicionales a este artículo para que puedas complementar y aclarar conocimientos.
React Cookbook: David Griffiths, Dawn Griffiths O Reilly Media Inc
👊🏽 Turno para tí: Comenta y comparte
Si te ha gustado la serie, dale a me gusta, compárteselo a quién veas que lo necesita y comenta si tienes alguna duda
Posted on October 15, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.