DEV Community

Cover image for Utilizando o Storybook para componentes
Lucas Lafèré
Lucas Lafèré

Posted on

2

Utilizando o Storybook para componentes

Para que serve o Storybook?

O Storybook é uma ferramenta bastante útil para desenvolvedores de aplicações web baseadas em componentes. Ele permite a criação de componentes de forma isolada, tornando mais fácil testar diferentes estados, cores e propriedades.

Sabe aquele botãozinho que ao clicar, deve ter seu texto mudado, e de acordo com isso, também deve mudar sua cor? Com o Storybook, a tarefa de testar essa funcionalidade se torna muito mais fácil.

Além disso, o Storybook ajuda a criar uma documentação para os componentes, o que facilita o trabalho em equipe.

O Storybook é amplamente utilizado para desenvolvimentos baseados em Component Driven UI. Neste tipo de abordagem, os componentes são criados primeiro e depois as páginas são construídas a partir deles, seguindo uma estratégia "from the bottom-up".

Aqui vai um exemplo do Storybook em funcionamento:

Image description

Instalando o Storybook

Para instalar o Storybook na sua aplicação React, seja com CRA (Create React App) ou Vite, basta executar o seguinte comando no terminal:

npx sb init

Enter fullscreen mode Exit fullscreen mode

Com isso, serão instalados alguns arquivos e pastas novas em seu projeto. A pasta .storybook contém as configurações padrão do Storybook, enquanto a pasta stories é destinada a armazenar os seus stories.

Para inicializar o Storybook após a instalação, execute o seguinte comando:

npm run storybook

Enter fullscreen mode Exit fullscreen mode

Nota: É recomendável que você exclua todos os arquivos na pasta /stories/, pois eles não serão utilizados e podem causar confusão para alguém novo no Storybook.

Criando um Story

Para adicionar um story para um componente em React, crie um arquivo com o nome [nome_do_componente].stories.jsx, por exemplo, Button.stories.jsx para um componente chamado Button.

Exemplo de um componente Button:

import PropTypes from 'prop-types';

function Button({ label, backgroundColor = 'red', size = 'md', handleClick }) {
  let scale = 1;
  if (size === 'sm') scale = 0.75;
  if (size === 'lg') scale = 1.5;

  const style = {
    backgroundColor,
    padding: `${scale * 0.5}rem ${scale * 1}rem`,
    border: 'none',
  };

  return (
    <button onClick={handleClick} style={style}>
      {label}
    </button>
  );
}

Button.propTypes = {
  label: PropTypes.string,
  backgroundColor: PropTypes.string,
  size: PropTypes.oneOf(['sm', 'md', 'lg']),
  handleClick: PropTypes.func,
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

Em seguida, você deve criar um objeto em Button.stories.jsx:

// Em Button.stories.jsx:

import Button from '../components/Button';

export default {
  title: 'My New Button',
// O componente que você deseja renderizar, testar e adicionar um story sobre:
  component: Button, 
};

Enter fullscreen mode Exit fullscreen mode

Agora, você pode criar uma função que retorne o seu componente e dar o nome "Red" ao seu story:

// Em Button.stories.jsx:

import Button from '../components/Button';

export default {
  title: 'My New Button',
  component: Button, 
};

export const Red = () => <Button label="Press Me" backgroundColor="red" />;

Enter fullscreen mode Exit fullscreen mode

Se você estiver usando TypeScript ou o recurso "propTypes" para tipar as suas props, o StoryBook será capaz de ler, inferir e documentar essa tipagem, sabendo, por exemplo, que label: string e backgroundColor: string.

Primeiro componente storybook, um quadrado vermelho com o texto "press me"

Com isso, você já tem o seu primeiro story. Ele ainda não é interativo, mas já existe com documentação e já mostra como seria renderizado em uma página. Agora você pode torná-lo interativo para alternar as props, receber ações e assim por diante.

Tornando nosso Story interativo

Primeiro, precisamos voltar ao nosso arquivo Button.stories.jsx e adicionar a seguinte linha:

//Em Button.stories.jsx:

import Button from '../components/Button';

export default {
  title: 'My new Button',
  component: Button 
}

// nova função aqui:

const Template = args => <Button {...args} />export const Red = () => <Button label="Press me" backgroundColor="red" />

Enter fullscreen mode Exit fullscreen mode

Com isso, estamos criando na variável Template uma função que recebe alguns argumentos (args) - como as props do Componente - e retorna o Button, passando todos os args (props) para o Button.

Agora, para cada novo “estilo” que desejamos testar do nosso componente Button, basta utilizarmos o Template que criamos.

Por exemplo:

//Em Button.stories.jsx:

import Button from '../components/Button';

export default {
  title: 'My new Button',
  component: Button 
}
// mudando o Red para utilizar a Template:

const Template = args => <Button {...args} />
export const Red = Template.bind({}) 
Red.args = { 
  backgroundColor = "red",
  label: "Press me",
  size: "md",
}

Enter fullscreen mode Exit fullscreen mode

Voltando para o Storybook, conseguimos manipular esse Story:

Quadrado verde

Mantendo track de “Actions” dos componentes

Quando criamos uma função chamada onClick como uma prop do nosso componente, o Storybook é capaz de reconhecer, por assinatura, que há algum tipo de evento acontecendo ali, e isso é mostrado na seção Actions da biblioteca.

Mas e quando temos uma função diferente, como handleClick, que utilizamos acima? Para tornar essa função uma Action dentro do Storybook, precisamos usar argTypes dentro do arquivo Button.stories.jsx:

import Button from '../components/Button';

export default {
  title: "'My new Button',"
  component: Button,
  argTypes: {
    handleClick: {
      action: "handleClick"
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Estamos dizendo para o Storybook que essa prop handleClick é uma Action, chamada handleClick. Essa string pode ser o que você quiser, é o nome utilizado dentro do Storybook para essa action.

const Template = args => <Button {...args} />export const Red = Template.bind({})
Red.args = {
  backgroundColor: "red",
  label: "Press me",
  size: "md",
}

Enter fullscreen mode Exit fullscreen mode

Agora no Storybook → Actions, podemos encontrar a função que foi utilizada, com todas as informações de evento dela, como quando utilizamos console.log em um evento:

Log de eventos do handleClick

Criando múltiplos Stories para um mesmo componente

E agora, para finalizar (o básico) da magia do Storybook, podemos criar múltiplos stories para um mesmo componente, utilizando o mesmo Template de antes:

//Em Button.stories.jsx:

import Button from '../components/Button';

export default {
title: "'My new Button',"
component: Button
argTypes: { handleClick: { action: "handleClick"} }
}

const Template = args => <Button {...args} />

export const Red = Template.bind({})
Red.args = {
backgroundColor = "red",
label: "Press me",
size: "md",
}
// criando um botão verde:
export const Green = Template.bind({})
Green.args = {
backgroundColor = "green",
label: "Press me",
size: "md",
}
// criando um botão pequeno:
export const Small = Template.bind({})
Small.args = {
backgroundColor = "red",
label: "Press me",
size: "sm",
}
// criando um botão grande:
export const Large = Template.bind({})
Large.args = {
backgroundColor = "red",
label: "Press me",
size: "lg",
}
// criando um botão com muito texto:
export const LongLabel = Template.bind({})
LongLabel.args = {
backgroundColor = "red",
label: "Press me hptrhpokophpoj gkpdofk pogdfpo kpgodfk pgdkpfo",
size: "md",
}

Enter fullscreen mode Exit fullscreen mode

Ou seja, basta utilizarmos a mesma Template, mudando os argumentos conforme necessidade, baseado no que desejamos testar.

export const NomeDoStory = Template.bind({})
NomeDoStory.args = {
backgroundColor = "red",
label: "Press me",
size: "md",
}

Enter fullscreen mode Exit fullscreen mode

No Storybook:

Imagem com diferentes componentes para testar, criados em nosso código, como mostrado acima


Com isso, você agora já é capaz de criar novos componentes de maneira prática, utilizando os Templates, e testar os diferentes estados que aquele componente precisa ter.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay