Neste tutorial, vamos mergulhar nos principais recursos do extrato de vanilla e demonstrar como criar folhas de estilo de tempo de execução zero construindo um aplicativo de exemplo com React e webpack.

O que é vanilla-extract?

O vanilla-extract tem tudo a ver com folhas de estilo de tempo de execução zero no TypeScript (ou JavaScript). Se você já usou Sass ou Less no passado, já sabe como eles podem ser poderosos para temas como organização e pré-processamento dos estilos do seu aplicativo.

Assim como esses pré-processadores CSS, vanilla-extract gera todos os estilos durante sua construção. Entre seus benefícios, você encontrará nomes de classes com escopo local, variáveis ​​CSS, regras CSS, suporte para temas simultâneos (sem globais), expressões de utilitário calc e muito mais.

Configurando extrato vanilla

Para demonstrar como usar vanilla-extract, criei um scaffolded projeto simples com React e webpack já adicionados. Você pode cloná-lo/bifurcá-lo localmente e usá-lo como ponto de partida para as próximas coisas que tentaremos no vanilla-extract.

Quando terminar, certifique-se de executar o comando npm install para baixe todos os pacotes do Node necessários.

Em seguida, execute o próximo comando para adicionar as dependências principais para vanilla-extract ( integração do webpack ):

npm install @ vanilla-extract/css @ vanilla-extract/babel-plugin @ vanilla-extract/webpack-plugin

Quando o comando é terminado, você verá as dependências recém-adicionadas em seu arquivo package.json:

“dependencies”: {“@ vanilla-extract/babel-plugin”:”^ 1.0.1″,”@ vanilla-extract/css”:”^ 1.2.1″,”@ vanilla-extract/webpack-plugin”:”^ 1.1.0″,…}

Quanto às configurações vanilla-extract webpack/Babel, você também precisa atualizar o arquivo webpack.config.js com as três mudanças a seguir:

const {VanillaExtractPlugin}=require (“@ vanilla-extract/plugin do webpack”);

A primeira alteração acima deve ser adicionada ao início do arquivo, na seção de importações. Esta linha representa o plug-in webpack para lidar com operações relacionadas ao extrato vanilla.

Ele será usado junto com a seção de plug-ins no arquivo com uma instanciação simples da seguinte maneira:

plug-ins: [ new HtmlWebpackPlugin (), new MiniCssExtractPlugin (), new VanillaExtractPlugin (),],

Finalmente, você precisa adicionar o plug-in vanilla-extract Babel à regra de teste “js | ts | tsx” para o carregador do carregador babel, como mostrado abaixo:

{test:/\.(js|ts|tsx)$/,… use: [{loader:”babel-loader”, options: {… plugins: [“@ vanilla-extract/babel-plugin”],},},],},

Um dos avisos nos documentos oficiais do vanilla-extract referem-se à necessidade de manipulação de CSS pelas configurações do webpack. Não se preocupe com isso; já estamos lidando com arquivos CSS nas configurações de projeto padrão do scaffold.

Se você deseja verificar se tudo está configurado corretamente, basta executar o comando npm run start e verificar os resultados em seu navegador.

Criando um tema estilizado

extrato vanilla funciona como um pré-processador, mas, em vez do Less ou Sass usual, você obtém TypeScript.

Vamos ver extrato vanilla em ação criando um tema estilizado muito simples para ajudar a construir a seguinte página:

Vamos começar com os estilos. Para escrevê-los, primeiro crie um novo arquivo na pasta src denominado styles.css.ts. Este tipo de arquivo é avaliado no momento da compilação e, como você verá ao adicionar o seguinte código a ele, é TypeScript:

import {createTheme, style} from”@ vanilla-extract/css”; export const [themeClass, vars]=createTheme ({color: {primary:”# 764abc”, secondary:”white”,}, font: {menu:”1.5em”,},}); exportar const menuStyle=style ({backgroundColor: vars.color.primary, fontSize: vars.font.menu, display:”block”, width:”100%”, color:”white”, padding: 20,}); export const menuItemsStyle=style ({float:”right”,}); exportar const menuItemStyle=style ({backgroundColor: vars.color.primary, color: vars.color.secondary, margin: 10,”: hover”: {cursor:”ponteiro”, cor:”laranja”,},}); export const sectionStyle=style ({display:”inline-block”, width:”100%”, textAlign:”center”, marginTop:”20%”,});

Os estilos são sempre referidos pela função de estilo, que recebe o objeto com todas as propriedades CSS necessárias para aquele objeto de estilo específico. Eles devem sempre ser exportados, pois serão pré-processados ​​por vanilla-extract antes de serem injetados na saída final.

A função createTheme é um recurso muito útil que você pode usar da biblioteca sempre que precisar de mais genéricos, gerenciamento de estilo centralizado. Pode ser necessário alternar temas, por exemplo, então este é um cenário perfeito de como os temas podem ajudar.

Cada estilo está usando variáveis ​​temáticas, mas elas também podem ser acessadas de arquivos externos do TypeScript porque também os estamos exportando.

Veja como é fácil adicionar um efeito de foco a um estilo. Sinta-se à vontade para incrementar o tema como desejar.

Agora é hora de usar nossos estilos. Para isso, crie outro arquivo na pasta src denominado App.tsx (o principal componente do aplicativo React) e adicione o seguinte conteúdo a ele:

import {themeClass, menuStyle, menuItemsStyle, menuItemStyle, sectionStyle,} from”./styles.css”; export const App=()=> (

Conteúdo do corpo aqui!

);

Mais uma vez, sinta-se à vontade para dividi-lo em mais componentes, se desejar. Vamos mantê-lo centralizado, no entanto, por uma questão de simplicidade.

É interessante notar que os estilos que estão sendo importados são adicionados como classes CSS, em vez de estilo embutido. Isso acontece porque todo o processo é feito estaticamente, o que não seria possível se você colocasse coisas embutidas.

No entanto, o vanilla-extract oferece suporte a API dinâmica para temas de tempo de execução dinâmico, caso você esteja curioso.

Você também pode usar a função globalStyle do pacote css para determinar se seu aplicativo deve seguir um estilo global para elementos gerais, como o corpo da página. Para fazer isso, crie outro arquivo chamado global.css.ts e coloque o seguinte conteúdo nele:

import {globalStyle} from”@ vanilla-extract/css”; globalStyle (“body, body *”, {all:”unset”, boxSizing:”border-box”, fontFamily:”Segoe UI”, color:”black”, padding: 0, margin: 0,});

O exemplo ainda não pode ser testado até que você tenha reunido tudo no arquivo index.tsx, da seguinte maneira:

import {render} from”react-dom”; importar {App} de”./App”; import”./global.css”; const root=document.createElement (“div”); document.body.appendChild (root); render (, root);

Para testá-lo, basta executar novamente o npm run startcommand e atualizar seu navegador. Você deve ver a mesma página mostrada na imagem acima.

Mas como esse mapeamento de estilo para classes acaba sendo representado no navegador?

Se você usar seu navegador para inspecionar os elementos HTML/CSS na página, você pode ver que o primeiro div no qual injetamos a classe themeClass tem as seguintes propriedades:

Seu uso posterior pode ser encontrado após a inspeção do o resto dos elementos, como em um dos menuItemStyle:

Usando Sprinkles com extrato de baunilha

Neste ponto, você deve entender o que é vanilla-extract é sobre como você pode usá-lo para criar seus estilos e temas estáticos.

No entanto, os estilos ainda são um pouco confusos e repetitivos. Vamos corrigir isso introduzindo Sprinkles , o tempo de execução zero framework CSS atômico para extração vanilla.

O Sprinkles fornece um conjunto de classes utilitárias que podem ser personalizadas e compostas em estilos reutilizáveis ​​junto com os átomos. Se você usou Styled System ou Tailwind CSS antes, então você se sentirá familiarizado com sua abordagem.

Iniciar adicionando a dependência do pacote ao seu projeto:

npm install @ vanilla-extract/sprinkles

A seguir, centralizaremos as muitas variáveis ​​que nosso aplicativo está usando até agora. Isso facilitará a reutilização, especialmente para os valores de base mais genéricos.

Crie outro arquivo chamado vars.css.ts na pasta src e coloque o seguinte conteúdo nele:

import {createGlobalTheme} from”@ vanilla-extract/css”; export const vars=createGlobalTheme (“: root”, {space: {none:”0″, small:”4px”, medium:”8px”, large:”16px”,”1/2″:”50%”,”1/5″:”20%”,}, cor: {branco:”#fff”, preto:”# 000″, laranja:”# FFA500″, principal:”# 764abc”,}, fontFamily: {body:’-apple-system,”Segoe UI”, Verdana, Arial’,}, fontSize: {small:”1em”, medium:”1.4em”, large:”1.8em”,}, gridRepeat: {“4x”:”repetir (4, 1fr)”,},});

A função createGlobalTheme ajuda a estabelecer as variáveis ​​CSS, eliminando a necessidade de fazer isso manualmente (como fazíamos na versão anterior do aplicativo).

Aqui, você pode adicionar qualquer vars que achar podem ser reutilizados em todos os estilos do aplicativo, sejam eles colocados em seus arquivos CSS ou diretamente nos componentes React.

Neste exemplo, estamos definindo valores globais básicos para o tamanho da fonte e família, cores e espaços gerais (para preenchimento, margem, etc.).

Lembre-se de que os nomes que você atribui a eles dependem de você; não há um sistema de sintaxe rígido aqui, então certifique-se de dar nomes significativos que explicam o que cada valor faz.

Agora é hora de criar os átomos personalizados a serem colocados em um novo arquivo chamado sprinkles.css.ts. Cole o seguinte conteúdo:

import {createAtomicStyles, createAtomsFn} from”@ vanilla-extract/sprinkles”; import {vars} de”./vars.css”; const responsiveStyles=createAtomicStyles ({conditions: {mobile: {}, tablet: {“@media”:”screen and (min-width: 768px)”}, desktop: {“@media”:”screen and (min-width: 1024px)”},}, defaultCondition:”mobile”, properties: {display: [“none”,”flex”,”block”,”inline”,”grid”], flexDirection: [“row”,”column”], gridTemplateColumns: vars.gridRepeat, justifyContent: [“stretch”,”flex-start”,”center”,”flex-end”,”space-around”,”space-between”,], textAlign: [“center”,”left”,”right”], alignItems: [“stretch”,”flex-start”,”center”,”flex-end”], paddingTop: vars.space, paddingBottom: vars.space, paddingLeft: vars.space, paddingRight: vars.space, marginTop: vars.space, marginRight: vars.space, marginLeft: vars.space, marginBottom: vars.space, fontFamily: vars.fontFamily, fontSize: vars.fontSize,//etc. }, abreviações: {padding: [“paddingTop”,”pad dingBottom”,”paddingLeft”,”paddingRight”], paddingX: [“paddingLeft”,”paddingRight”], paddingY: [“paddingTop”,”paddingBottom”], placeItems: [“justifyContent”,”alignItems”],}, }); const colorStyles=createAtomicStyles ({condições: {lightMode: {}, darkMode: {“@media”:”(preferers-color-scheme: dark)”},}, defaultCondition:”lightMode”, propriedades: {color: vars. cor, plano de fundo: vars.color,//etc.},}); exportar átomos const=createAtomsFn (responsiveStyles, colorStyles);

Reserve um tempo para examinar todo o conteúdo deste arquivo-eu prometo, valerá a pena. A função createAtomicStyles ajuda a configurar o conjunto de propriedades predefinidas em torno de:

condições-se o estilo deve ser aplicado a propriedades de dispositivos móveis, desktop ou somente tablet-a lista de adereços de estilo React conhecidos e seus respectivos valores (ou tuplas extraídas do arquivo vars criado anteriormente) atalhos-como o nome sugere, isso ajudará a criar atalhos para várias propriedades que têm valores semelhantes a serem aplicados de uma vez

Observe que a função final, createAtomsFn, recebe dois estilos atômicos , o segundo relacionado aos modos de claro/escuro temáticos (muitos aplicativos lidam com isso atualmente). Para simplificar, vamos manter esta parte curta e aplicar apenas o modo leve como padrão.

Agora que não há mais tema no arquivo style.css.ts, precisamos atualizá-lo para lidar com o polvilha recém-criada. Abaixo está o novo código a ser usado no arquivo:

import {composeStyles, style} from”@ vanilla-extract/css”; importar {átomos} de”./sprinkles.css”; export const menu=composeStyles (atoms ({display:”flex”, justifyContent:”space-between”, padding:”large”,//Atoms condicionais: flexDirection: {mobile:”column”, desktop:”row”,} , fontSize: {desktop:”large”, mobile:”medium”}, background: {lightMode:”primary”,},})); export const menuItems=composeStyles (atoms ({display: {desktop:”flex”, mobile:”grid”,}, gridTemplateColumns: {mobile:”4x”,}, paddingX: {desktop:”small”, mobile:”nenhum”,}, paddingY: {mobile:”medium”,}, flexDirection: {mobile:”column”, desktop:”row”,},})); export const menuItem=composeStyles (atoms ({display:”flex”, alignItems:”center”, paddingX:”medium”, color:”white”, flexDirection: {mobile:”column”, desktop:”row”,}, }), estilo ({“: hover”: {cursor:”ponteiro”, cor:”laranja”,},}));

Vamos repassar. A função composeStyles pode ser usada sempre que você precisar juntar vários estilos em um único.

Para os primeiros estilos criados no arquivo de código, temos apenas um único átomo sendo adicionado. No entanto, conforme você navega para baixo, o último estilo relacionado ao menu do item também adiciona algumas propriedades extras por meio da função de estilo.

Isso é útil sempre que você precisa adicionar propriedades CSS personalizadas que não pertencem ao átomos do tema atual. Se você acha que é um caso muito específico e que a propriedade não deveria pertencer ao tema, usar a função de estilo é útil.

Dê uma olhada nos átomos condicionais para coisas como flexDirection, fontSize e muito mais. Como configuramos as condições para desktop vs. celular no arquivo Sprinkles, agora, toda vez que você precisar configurar estilos diferentes dependendo do tamanho do dispositivo, você pode defini-lo por meio das propriedades do desktop e do celular, respectivamente.

Por exemplo, para nossa disposição menuItems, a disposição móvel dos elementos deve usar uma exibição de grade CSS em vez de flex para que possamos mostrá-la, como na figura abaixo:

O mesmo se aplica ao tamanho da fonte, que é menor em dispositivos móveis.

Você deve estar se perguntando o que aconteceu com o estilo de seção que tínhamos antes no arquivo style.css.ts. Bem, nós o movemos para o arquivo App.tsx, apenas para demonstrar como Sprinkles lida com átomos embutidos.

Vamos ver como o conteúdo do arquivo é agora:

import * as styles from”./styles.css”; importar {átomos} de”./sprinkles.css”; export const App=()=> (

Conteúdo do corpo aqui!

);

A primeira alteração que fizemos neste arquivo são as importações. Agora, em vez de importar cada um (uma lista que pode rapidamente ficar muito grande), estamos importando todos para a constante de estilos. Em seguida, você pode chamar diretamente cada um nos nomes das classes.

Preste atenção ao novo componente da seção. Sim, não há problema em personalizar seus átomos diretamente nos componentes e o Sprinkles cuidará disso para você.

Observe que estamos repetindo o uso de desktop/celular-desta vez para os valores margin-top porque eles mudam quando visualizados em dispositivos de diferentes tamanhos.

Por último, há uma pequena mudança no arquivo global.css.ts devido ao novo repositório centralizado para os vars do aplicativo. Este é seu conteúdo atualizado:

import {globalStyle} from”@ vanilla-extract/css”; import {vars} de”./vars.css”; globalStyle (“body, body *”, {all:”unset”, boxSizing:”border-box”, fontFamily: vars.fontFamily.body, color: vars.color.black, padding: 0, margin: 0,}) ;

É hora de testar novamente! Você verá que a apresentação quase não mudou, que é o objetivo. No entanto, conseguimos melhorar o código significativamente em termos de capacidade de reutilização e organização.

Conclusão

Há muito mais coisas a explorar sobre extração vanilla, no entanto, estou confiante de que estabeleceu uma base sólida de conhecimento para ajudá-lo a começar a usá-lo.

Você pode ler mais sobre API dinâmica para temas de tempo de execução dinâmico, bem como sua excelente funções utilitárias para coisas como expressões de cálculo.

Você pode encontrar a versão final do nosso projeto de exemplo em GitHub .

Você já experimentou o vanilla-extract? Em caso afirmativo, o que você acha até agora?