O Storybook 5.3 foi lançado oficialmente há duas semanas e ele trouxe ótimas melhorias. Além de ficar mais fácil de usar e configurar, ele não é mais "só" um explorador de componentes UI. Ele se tornou uma ferramenta incrível para desenvolver um Design System, e eu vou explorar isso com vocês!
Esse artigo é baseado principalmente nos 4 artigos, criados pela equipe do Storybook, sobre esse lançamento. Se quiser ver essas histórias, que são mais curtas e estão separadas, você pode pular direto para Fontes.
Se você não sabe o que é o Storybook, recomendo ler meu artigo anterior, pois também vou usar o projeto dele como base para esse artigo.
Como criar uma biblioteca de componentes com Angular e Storybook
Klaus Kazlauskas ・ Jan 3 '20
Índice dos tópicos principais:
- Atualizando os pacotes
- Configuração declarativa
- Geração automática de documentação
- Iniciando um Design System com MDX
- Storybook focado em Design
Preparação
Na época que esse guia foi preparado, foram usadas as seguintes tecnologias:
tecnologia | versão | instalação |
---|---|---|
Node.js | 11.6.0 | como instalar |
NPM | 6.13.4 | Já vem com o Node.js |
Angular CLI | 8.3.21 | como instalar |
Storybook | 5.3.8 | como instalar |
Todo o código desse projeto está no GitHub. Então, caso você se perca em qualquer parte, pode fazer uma comparação direta:
klauskpm / angular-storybook
Repositório para ensinar a usar Storybook com Angular.
Atualizando os pacotes
Se você instalou os pacotes do Storybook e agora precisa atualizar eles, não se preocupe. Você só precisa rodar o seguinte comando no seu terminal:
# dentro do seu projeto
npx npm-check-updates '/storybook/' -u && npm install
O npm-check-updates
é um pacote que verifica se um pacote precisa atualizar. Nós passamos uma expressão regular para ele achar todos os pacotes que tenham storybook no nome, e a opção -u
para atualizar o nosso package.json
.
O npx
é um comando do Node/npm para executar pacotes sem precisar instalar eles. Ótimo para casos em que não queremos instalar um pacote globalmente porque só vamos usar ele apenas uma vez.
Pode comparar o seu progresso com a tag v2.0 do repositório
Configuração declarativa
O Storybook já tinha uma configuração bem simples, mas tinham alguns pontos que poderiam melhorar, como alguns nomes que não eram claros de acordo com as responsabilidades e a utilização da API do Webpack. Agora que resolveram esses problemas, vamos ver como a ela ficou.
main.js
O main.js
é o arquivo principal de configuração do Storybook e é responsável por tudo que lida com a renderização das nossas histórias. Nesse arquivo vamos declarar, onde devemos buscar as histórias e como identificar elas, quais são os addons da aplicação e as configurações de presets.
Vamos ver como escrevíamos antes e como é hoje.
Antes
.storybook/config.js
import { configure } from '@storybook/angular';
configure([
require.context('../src', true, /\.stories\.[tj]s$/),
require.context('../projects', true, /\.stories\.[tj]s$/)
], module);
.storybook/addons.js
import '@storybook/addon-knobs/register';
import '@storybook/addon-actions/register';
Depois
.storybook/main.js
module.exports = {
stories: [
'../src/**/*.stories.(ts|js)',
'../projects/**/*.stories.(ts|js)'
],
addons: [
'@storybook/addon-knobs',
'@storybook/addon-actions'
]
};
Com isso nós conseguimos matar o config.js
e o addons.js
do nosso projeto e temos uma configuração bem mais simples de entender. Apesar de nesse exemplo nós termos matado o config.js
, nós poderíamos ter outras configurações nele. Essas configurações foram absorvidas pelo preview.js
.
preview.js
O preview.js
cuida do iframe que exibe (preview) a sua história e das configurações globais. É nele que vamos fazer a importação de CSS e polyfill, e configurações de parâmetros e decorators, que era a segunda responsabilidade do config.js
.
No nosso caso só vamos configurar o addon knobs
, que estava sendo configurado dentro do simple-button/index.stories.ts
.
.storybook/preview.js
import { addDecorator } from "@storybook/angular";
import { withKnobs } from "@storybook/addon-knobs";
addDecorator(withKnobs);
manager.js
O manager.js
cuida da parte gráfica que está em volta dos "previews" das histórias e também a parte dos addons. É nele que vamos adicionar configurações como temas, logo e nome da empresa, e configurações de exibição dos addons.
Vamos criar um tema com a base clara e definir que o nome do nosso Storybook é "Angular Storybook":
.storybook/manager.js
import { create } from '@storybook/theming/create';
import { addons } from "@storybook/addons";
addons.setConfig({
theme: create({
base: 'light',
brandTitle: 'Angular Storybook'
})
});
E vamos ter o seguinte resultado:
O layout continua o mesmo, mas, em vez da logo do Storybook, está aparecendo o nome do nosso projeto definido no tema.
Se quiser saber mais sobre a parte de tema, você pode ver a documentação oficial sobre criação de temas.
Separadores de hierarquia
Antes do 5.3, o Storybook aceitava vários tipos de separadores de hierarquia, como |
, \
e .
. mas agora ele força a hierarquia a ser definida sempre com /
. Então, uma história que tinha esse título UI|Buttons & Indicators/Button
ficaria assim UI/Buttons & Indicators/Button
.
Vamos revisitar o nosso simple-button/index.stories.ts
e substituir o título da história respeitando a nova hierarquia:
projects/storybook-ui/src/lib/simple-button/index.stories.ts
import { SimpleButtonComponent } from './simple-button.component';
import { text } from '@storybook/addon-knobs';
import { moduleMetadata } from '@storybook/angular';
import { action } from '@storybook/addon-actions';
export default {
title: 'UI / Button',
decorators: [
moduleMetadata({declarations: [SimpleButtonComponent]})
],
};
export const withDefaultValues = () => ({
component: SimpleButtonComponent
});
export const withText = () => {
return {
template: `
<ui-simple-button
[text]="text"
(click)="click($event)"
></ui-simple-button>
`,
props: {
text: text('Text', 'Ola'),
click: action('Clicou')
}
};
};
Fazendo a atualização em massa
Fazer essa alteração na mão para apenas uma história é simples, mas quando começam a ser várias e com vários níveis, isso se torna trabalhoso. Felizmente, a equipe do Storybook fez um script para atualizar isso de forma automática. Você só precisa rodar o seguinte comando:
# dentro do seu projeto
npx -p @storybook/cli sb migrate upgrade-hierarchy-separators --glob="*.stories.(ts|js)"
Perdemos o root!
Com essa atualização nós perdemos o root/raiz das nossas histórias. O root aparecia como um texto em cima das nossas histórias. No nosso caso, era o UI
, e tinhamos como pasta o Button
. Sem o root, o UI
se torna uma pasta como o Button
.
Para recuperar essa aparência de root, nós precisamos adicionar o seguinte código no .storybook/preview.js
:
.storybook/preview.js
addParameters({
options: {
showRoots: true,
},
});
Migração
Tanto a parte do antigo config.js
quanto os antigos separadores vão ser suportados até a versão 6.0.0 do Storybook. Felizmente, esse artigo já é suficiente para te preparar para essa versão, mas, caso queira consultar uma fonte oficial, a equipe do Storybook também preparou um guia de migração do 5.2 para o 5.3 para facilitar todo esse processo.
Saber mais sobre
Se quiser saber mais detalhes sobre a parte da configuração declarativa, você pode ver o artigo oficial do Storybook:
Declarative Storybook configuration | by Norbert de Langen | Storybook | Medium
Norbert de Langen ・ ・
Medium
Pode comparar o seu progresso com a tag 2.1 do repositório
Geração automática de documentação
O Storybook agora da suporte ao DocsPage para geração automática de documentação, e ao MDX para documentações mais longas e customizadas - vamos falar dele mais tarde.
Configurando o DocsPage
Para usar o DocsPage só preciamos instalar umas dependências, adicionar poucas configurações, e a documentação está pronta. Parece mágica, mas é melhor!
Instale as dependências
Primeiro nós vamos instalar o @storybook/addon-docs
(responsável pela geração das páginas) e o @compodoc/compodoc
(gerador de documentação do de projetos do Angular).
# dentro do seu projeto
npm install --save-dev @storybook/addon-docs @compodoc/compodoc
Mais tarde vou detalhar a importância do compodoc
.
Adicione os scripts de geração
Vamos criar o script docs:storybook
que vai ser responsável por gerar a documentação do nosso projeto, e vamos adicionar esse script antes da execução do storybook
e do build-storybook
.
package.json
{
...,
"scripts": {
"docs:storybook": "compodoc -p .storybook/tsconfig.json -e json -d .",
"storybook": "npm run docs:storybook && start-storybook -p 6006",
"build-storybook": "npm run docs:storybook && build-storybook"
}
}
O comando que configuramos vai gerar um arquivo JSON chamado documentation.json
e vamos passar essas informações para o @storybook/addon-docs
.
⚠️ Na documentação é recomendado usar o
tsconfig.json
do projeto principal em vez do.storybook/tsconfig.json
, mas como estamos usando ocompodoc
para oStorybook
, na MINHA OPINIÃO faz mais sentido usar o doStorybook
. Sinta-se livre para discordar e opinar!
Infelizmente, a documentação não atualiza automaticamente ao mudar o componente. Precisamos regerar o documentation.json
sempre que quisermos as informações mais novas. Felizmente já tem uma issue aberta sobre isso.
Explicando o compodoc
Explicando um pouco o comando que acabamos de configurar, nós passamos as seguintes opções:
-
-p
ou--tsconfig
para definir qual tsconfig vai ser usado -
-e
ou--exportFormat
para definir o formato que vai ser exportado -
-d
ou--output
para definir a pasta em que vai ser exportada a documentação
Se usássemos as opções padrões do compodoc
e gerássemos a documentação com compodoc -p .storybook/tsconfig.json
, seria gerada a pasta documentation
com páginas HTML com uma documentação completa do projeto.
Configure o @storybook/addon-docs
Como todos os outros addons nós precisamos adicionar ele no .storybook/main.js
para ele ser carregado:
.storybook/main.js
module.exports = {
...
addons: [
...,
'@storybook/addon-docs',
]
};
Além disso, precisamos alimentar ele com o documentation.json
gerado pelo compodoc
. Vamos adicionar o seguinte no .storybook/preview.js
:
.storybook/preview.js
import { setCompodocJson } from "@storybook/addon-docs/dist/frameworks/angular";
import docJson from '../documentation';
setCompodocJson(docJson);
E por último, não podemos esquecer de adicionar a propriedade component
na história do nosso componente. É com ela que será identificado o componente e vinculado a tabela de propriedades geradas pelo compodoc
:
projects/storybook-ui/src/lib/simple-button/index.stories.ts
export default {
title: 'UI / Button',
component: SimpleButtonComponent, // Adicionado aqui
decorators: [
moduleMetadata({declarations: [SimpleButtonComponent]})
],
};
Adicione uns enfeites (opcional)
Apenas para ver como a tabela de propriedades é gerada pelo compodoc
, vamos adicionar o seguinte no simple-button/index.stories.ts
:
projects/storybook-ui/src/lib/simple-button/simple-button.component.ts
/**
* ViewChild que está vinculada a nada
*/
@ViewChild('empty', { static: false })
empty: TemplateRef<any>;
/**
* Output fake
*/
@Output()
clicked = new EventEmitter();
/**
* Input que define o texto apresentado no botão
*/
@Input()
text = 'clique aqui';
/**
* Método simples e público
* @return void
*/
public simpleMethod(): void {}
/**
* Método complexo e privado
* @return string
*/
private complexMethod(num1: number, num2: number): string {
return '';
}
E também podemos controlar o tamanho do preview das histórias da documentação adicionando uma configuração no .storybook/preview.js
:
.storybook/preview.js
addParameters({
...,
docs: {
iframeHeight: 60
}
});
Resultado
Agora, quando rodarmos o comando npm run storybook
, devemos ver o seguinte:
🎉 Storybook com documentação gerada 🎉
Saber mais sobre
Se quiser saber mais detalhes sobre geração de documentação, você pode ler o guia oficial para o Angular, ou o artigo oficial do Storybook:
Storybook Docs for new frameworks | by Michael Shilman | Storybook | Medium
Michael Shilman ・ ・
Medium
Pode comparar o seu progresso com a tag v2.2 do repositório
Iniciando um Design System com MDX
MDX é a mistura de Markdown (MD) e JSX (sintaxe do React para escrita de templates). Com o MDX, o Storybook nos da a liberdade de melhorar ou substituir as documentações geradas automaticamente, e muito mais!
Com o MDX podemos escrever histórias apenas com MDX ou misturar as histórias em CSF (Component Story Format) com MDX. Também podemos escrever um MDX de documentação sem histórias, como design tokens e introdução ao design system. Segue abaixo o exemplo de um projeto:
Como escrevemos em MDX
Olhando a imagem acima, podemos ver o #Badge
e o Lets define...
e isso faz parte da sintaxe do Markdown. Enquanto isso o <Badge>
que é um componente feito em React, e o <Meta>
, <Story>
e <Preview>
que fazem parte do addon-docs
, usam a sintaxe do JSX. Isso quer dizer que, quando quisermos adicionar textos e formatações nós vamos usar o MD (Markdown), e quando quisermos adicionar algum layout ou funcionalidade diferente, vamos usar componentes em React com JSX. Segue abaixo o que seria o resultado do MDX apresentado anteriormente:
O resultado dessa combinação é uma sintaxe muito mais simples. Ela é tão simples, e mais afastada da programação, que se torna fácil para que pessoas sem conhecimento da nossa linguagem de programação possam contribuir com a documentação do nosso Design System.
Fonte | Site | GitHub | Componentes de Auxílio
Configurando o MDX
Para fazer o MDX rodar é bem simples. Nós precisamos instalar algumas dependências e fazer nosso sistema encontrar os arquivos MDX.
Instale as dependências
O MDX precisa do DocsPage e do React (JSX). Como já fizemos as instalações pro DocsPage anteiormente, vamos só fazer as instalações necessárias do React.
# dentro do seu projeto
npm install --save-dev react react-is babel-loader
Altere o main.js
O nosso .storybook/main.js
já está configurado para procurar por histórias que tenham as extensões ts
ou js
. Então só precisamos adicionar a extensão mdx
:
module.exports = {
stories: [
'../src/**/*.stories.(ts|js|mdx)',
'../projects/**/*.stories.(ts|js|mdx)'
],
addons: [
'@storybook/addon-docs',
'@storybook/addon-knobs',
'@storybook/addon-actions'
]
};
Criando um arquivo MDX
Por enquanto vamos criar só um arquivo de ilustração. Só precisa copiar e colar que mais tarde vou explicar a sintaxe. Dentro de projects/storybook-ui/src/lib/
vamos criar o arquivo design-system/getting-started.stories.mdx
para introduzir as pessoas ao nosso design system:
projects/storybook-ui/src/lib/design-system/getting-started.stories.mdx
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title='Design System / Introdução' />
# Introdução
Olá pessoa! Seja bem vinda ao meu Design System
Veja o resultado
Agora, quando você rodar o comando npm run storybook
, você deve ver algo como o que está abaixo:
Criando histórias com MDX
Nós configuramos o DocsPage e o MDX, e vimos ambos em ação. Agora, nós precisamos dar o próximo passo e entender como criar histórias em MDX. Para isso, devemos saber quais ferramentas temos.
Blocos do @storybook/addon-docs
O Storybook nos dá vários blocos para montarmos nossas histórias, e os 4 blocos principais são:
-
Meta
para definir título, decorators e parameters (assim como o que definimos noexport default
no CSF) -
Props
para exibir a tabela de propriedades do componente -
Story
para criar a história do componente e exibir ela na documentação -
Preview
para exibir a história do componente em volta de um bloco de exibição
Existem outros blocos além desses, como o ColorPalette
para design tokens, mas esses 4 são os principais e devem aparecer em todas as histórias que fizermos com MDX. Além disso, também podemos criar os nossos próprios blocos usando o React.
Estilos de escrita com MDX
Diferente do React e do Vue, no Storybook o Angular não tem a habilidade de escrever histórias inline. Felizmente, temos outras abordagens:
- histórias puras em MDX
- histórias em CSF com documentação em MDX
- histórias em CSF definindo o MDX arbitrariamente (MDX não podendo definir histórias, só referênciando).
Não irei abordar o último estilo de escrita com MDX (histórias em CSF definindo o MDX arbitrariamente), pois eu não consegui fazer ele funcionar. Continuarei buscando soluções e atualizarei esse artigo caso consiga.
Histórias puras em MDX
Essa abordagem é ótima para documentações, como o getting-started.stories.mdx
, e também para componentes simples. Como eles não precisam de muita configuração, e no máximo tem alguns inputs e outputs simples, não precisamos de um arquivo de lógica. Segue abaixo um exemplo:
index.stories.mdx
import { Meta, Story, Props, Preview } from '@storybook/addon-docs/blocks';
import { moduleMetadata, addDecorator } from '@storybook/angular';
import { SimpleButtonComponent } from '../simple-button.component';
<Meta
title='UI / Button'
component={SimpleButtonComponent}
decorators={[moduleMetadata({ declarations: [SimpleButtonComponent] })]}
/>
# SimpleButton Component
Uma descrição simples em **markdown**.
Exibindo o `SimpleButtonComponent` usando o `Story`.
<Story name='basic' height='60px'>{{
component: SimpleButtonComponent,
props: {},
}}</Story>
## Props
A tabela de propriedades é exibida com usando o `Props`.
<Props of={SimpleButtonComponent} />
## Stories
Fazendo preview da história com `<Preview>`.
<Preview>
<Story name="Basic Preview">{{
component: SimpleButtonComponent,
props: {},
}}</Story>
</Preview>
Histórias em CSF com documentação em MDX
As vezes nós temos componentes mais complexos, ou com dados mais longos, e queremos deixar a parte da documentação mais simples possível. Para esses casos nós vamos ter dois arquivos, um CSF (.ts
ou .js
) e um MDX (.mdx
). No CSF vamos deixar as histórias e lógicas, e no MDX vamos deixar a documentação e aplicaremos as histórias nos devidos lugares. Segue abaixo um exemplo:
stories.ts
import { action } from '@storybook/addon-actions';
import { text } from '@storybook/addon-knobs';
import { SimpleButtonComponent } from '../simple-button.component';
export const withDefaultValues = () => ({
component: SimpleButtonComponent
});
export const withText = () => {
return {
template: `
<ui-simple-button
[text]="text"
(click)="click($event)"
></ui-simple-button>
`,
props: {
text: text('Text', 'Ola'),
click: action('Clicou')
}
};
};
index.stories.mdx
import { Meta, Story, Props, Preview } from '@storybook/addon-docs/blocks';
import { moduleMetadata, addDecorator } from '@storybook/angular';
import { SimpleButtonComponent } from '../simple-button.component';
import * as stories from './stories.ts';
<Meta
title='UI / Button'
component={SimpleButtonComponent}
decorators={[moduleMetadata({ declarations: [SimpleButtonComponent] })]}
/>
# SimpleButton Component
Uma descrição simples em **markdown**.
Exibindo o `SimpleButtonComponent` usando o `CSF` + `MDX`.
<Story name='basic' height='60px'>{stories.withDefaultValues()}</Story>
## Props
A tabela de propriedades é exibida com usando o `Props`.
<Props of={SimpleButtonComponent} />
## Stories
Usando histórias criadas em CSF no MDX
<Preview>
<Story name="With Text">{stories.withText()}</Story>
</Preview>
Vamos atualizar nossa história
Vendo as estratégias acima, podemos afirmar que nosso componente só precisa de um arquivo MDX porque ele é bem simples, mas, apenas por questão de demonstração, vamos usar os dois estilos ao mesmo tempo. Vamos pegar o nosso simple-button/index.stories.ts
e começar a criar nossa nova documentação dele. Vamos seguir os seguintes passos:
- Crie a pasta
stories
dentro deprojects/storybook-ui/src/lib/simple-button
- Renomei o
index.stories.ts
parastories.ts
e mova ele para dentro destories
- Crie o arquivo
index.stories.mdx
dentrostories
Nós renomeamos o arquivo para não haver um possível problema de carregamento das histórias, e movemos os dois arquivos para uma outra pasta apenas por questão de organização.
Agora, vamos aplicar as mudanças no conteúdo dos arquivos:
stories.ts
import { action } from '@storybook/addon-actions';
import { text } from '@storybook/addon-knobs';
import { SimpleButtonComponent } from '../simple-button.component';
export const withDefaultValues = () => ({
component: SimpleButtonComponent
});
export const withText = () => {
return {
template: `
<ui-simple-button
[text]="text"
(click)="click($event)"
></ui-simple-button>
`,
props: {
text: text('Text', 'Ola'),
click: action('Clicou')
}
};
};
index.stories.mdx
import { Meta, Story, Props, Preview } from '@storybook/addon-docs/blocks';
import { moduleMetadata, addDecorator } from '@storybook/angular';
import { SimpleButtonComponent } from '../simple-button.component';
import * as stories from './stories.ts';
<Meta
title='UI / SimpleButton'
component={SimpleButtonComponent}
decorators={[moduleMetadata({ declarations: [SimpleButtonComponent] })]}
/>
# SimpleButton Component
Uma descrição simples em **markdown**.
Exibindo o `SimpleButtonComponent` usando o `Story`.
<Story name='simples' height='60px'>{{
component: SimpleButtonComponent,
props: {},
}}</Story>
## Props
A tabela de propriedades é exibida com usando o `Props`.
<Props of={SimpleButtonComponent} />
## Stories
Usando histórias criadas em CSF no MDX
<Preview>
<Story name="com valores default">{stories.withDefaultValues()}</Story>
</Preview>
<Preview>
<Story name="com texto diferente">{stories.withText()}</Story>
</Preview>
O resultado resultado é esse:
Saber mais sobre
Se quiser saber mais detalhes sobre documentação rica com MDX, você pode ler o artigo oficial do Storybook:
Rich docs with Storybook MDX. Components & documentation in harmony… | by Michael Shilman | Storybook | Medium
Michael Shilman ・ ・
Medium
Além disso, também tem esses links super importantes com documentações e exemplos:
- Documentação do MDX com Angular
- Documentação geral do MDX
- Receitas para criações de histórias
- Lista de blocos em JSX disponíveis
- Lista complementar de blocos em JSX
Antes de ir para a próxima sessão, se você já tem várias histórias criadas no Storybook no estilo do
storiesOf
ouCSF
e quer mudar todas, ou algumas, para outro estilo, você pode dar uma olhada nocodemod
. Ele tem scripts para mudar, em massa, as histórias de estilo e isso pode te poupar muito tempo.Pode comparar o seu progresso com a tag v2.3 do repositório
Storybook focado em Design
Quando lidamos com qualquer organização de um projeto, a parte mais difícil é a comunicação. Seja a falta ou o mau uso dela. Para resolver esse problema, em relação aos aspectos de Design de um sistema, existe o Design System.
Apesar de o Design System ser uma ótima solução, cada equipe tem um conjunto de ferramentas e elas vivem em seus universos isolados. Isso torna o trabalho de manter um Design System algo, um tanto que, trabalhoso.
Por esse motivo, eu fico muito feliz quando vejo o time do Storybook exibindo tantas integrações com essas essas ferramentas.
Figma addon
As mudanças de Design vão aparecer automaticamente no StorybookAbstract addon (para Sketch e Adobe XD)
Abre um painel nas histórias do Storybook, onde você vê os layers e containers do AbstractInVision Design System Manager
O DSM permite ver os componentes do Storybook, no app do DSM, junto dos designs extraídos do SketchZeplin
Linka e mostra uma minidocumentação dos componentes do Storybook direto com o app do ZeplinZeroheight
O addon leva os componentes do Storybook para serem exibidos junto com os designs de outras ferramentas, como Sketch, Figma, ou Adobe XDStory2sketch for Sketch
Converte histórias do Storybook em símbolos do SketchDesign Token
Transforma e exibe design tokens identificados em um painel no Storybook
São integrações para a equipe de Design ver os nossos componentes e usar eles nos próximos designs, ou para nós vermos os designs deles e compararmos cores, tamanhos e fontes. O objetivo é todos terem uma única fonte de verdade sobre os elementos de design e facilitar a manutenção e evolução do Design System
Saber mais sobre
Se quiser saber mais detalhes sobre Storybook para Design, você pode ler o artigo oficial do Storybook:
Storybook for design. How to integrate your favorite design… | by Dominic Nguyen | Storybook | Medium
Dominic Nguyen ・ ・
Medium
Conclusão
Além de facilitar a utilização e configuração, também adicionaram vários modos de criação de documentação (DocsPage e MDX) e várias integrações com as ferramentas de Design. O Storybook tem evoluído muito, e vai continuar evoluindo, para se tornar a ferramenta para criações de Design System.
Eu aprendi muito enquanto fazia esse artigo e espero que ele ajude você também.
Um forte abraço e até a próxima! 😬
Fontes
A base desse artigo foram os 4 artigos sobre o lançamento da nova versão do Storybook. Segue abaixo os links:
- Declarative Storybook configuration
- Storybook Docs for new frameworks
- Rich docs with Storybook MDX
- Storybook for Design
Além desse artigos, também tiveram esses outros links:
Top comments (0)