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:
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
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
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;
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,
};
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" />;
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
.
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" />
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",
}
Voltando para o Storybook, conseguimos manipular esse Story:
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"
}
}
}
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",
}
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:
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",
}
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",
}
No Storybook:
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.
Top comments (0)