Atualmente, existem diversas formas de estilizar páginas no ReactJs, desde utilizar o CSS simples, Sass ou até mesmo styled components. Tudo se resume em criar um arquivo separado do código JSX que irá conter toda a estilização daquele componente ou daquela página. Porém, existe uma outra forma de fazer estilização que é utilizando as interfaces declarativas.
Introdução
Nesse artigo, você irá compreender o que são e como utilizar interfaces declarativas em seus projetos com ReactJs ou NextJs e como que essas bibliotecas auxiliam na hora de aumentar a produtividade em criar layouts responsivos e fáceis de de fazer manutenções. Para isso irei utilizar como exemplo a biblioteca Chakra UI, porém a maioria dos conceitos abordados aqui servem para outras libs.
Interfaces declarativas
Uma das primeiras bibliotecas que começou com esse foco de interfaces declarativas foi o Theme-UI, que cria interfaces baseadas nos princípios constraint-based, onde é possível definir as estilizações de um componente direto pela tag do JSX.
import { ThemeProvider } from 'theme-ui' import { theme } from './theme' export const App = () => ( <ThemeProvider theme={theme}> <h1 sx={{ color: 'primary', fontFamily: 'heading', }}> Hello </h1> </ThemeProvider> )
Claro que isso também já era possível com o CSS simples, mas existem várias funcionalidades que são adicionadas na estilização como: criação de temas, pacotes de componentes, paletas de cores já configurada e etc. A principio, isso parece poluir o código ao misturar estilização com JSX, porém, ao longo desse artigo você irá entender algumas de suas vantagens.
Instalação
Para um projeto utilizando React ou Next o processo de instalação é o mesmo:
Usando NPM:
npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4
Usando YARN:
yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4
Após isso precisaremos configurar um provider, para que o Chakra sobrescreva as configurações padrões do CSS e para que a gente possa passar novas configurações.
import * as React from "react" // 1. import `ChakraProvider` component import { ChakraProvider } from "@chakra-ui/react" function App({ Component }) { // 2. Use at the root of your app return ( <ChakraProvider> <Component /> </ChakraProvider> ) }
No Next é um pouquinho diferente, pois o provider precisa ser colocado no arquivo _app.jsx
import { ChakraProvider } from "@chakra-ui/react" function MyApp({ Component, pageProps }) { return ( <ChakraProvider> <Component {...pageProps} /> </ChakraProvider> ) } export default MyApp
Funcionalidades
- Pacotes de componentes
A maioria das bibliotecas de interface declarativas, já possuem por padrão um vasto pacote de componentes prontos pré estilizados, onde o desenvolvedor precisara fazer poucos ajustes para utilizar o componente.
import { Flex } from 'theme-ui' <Flex> <Box p={2} bg="primary" sx={{ flex: '1 1 auto' }}> Flex </Box> <Box p={2} bg="muted"> Box </Box> </Flex>
No Chakra você pode conferir todos os componentes que eles fornecem por padrão a partir da documentação:
https://chakra-ui.com/docs/getting-started
- Componentização
Como a estilização se torna mais simples utilizando essas bibliotecas, a forma de construir uma interface também fica, desse modo, é possível dividir uma aplicação em componentes cada vez menores e com mais responsabilidades únicas. Portanto, facilitando a manutenção do código.
- Propriedades minificadas
Os nomes das propriedades são minificados evitando a poluição do código e acelerando o processo de escrita, por exemplo, a propriedade "padding" pode ser escrita apenas com a letra "p":
<Box p={2}> </Box>
Porém, caso o desenvolvedor queira, ele também pode escrever o nome por completo das propriedades.
- Cores
A maioria dessas bibliotecas já possuem várias paletas de cores configurada e prontas para serem utilizadas, como é o caso do Chakra que facilita bastante o processo de criar cores globais para uma aplicação.
import {theme} from '@chakra-ui/react' const gray500 = theme.colors.gray[500]
Para verificar as cores disponíveis basta acessar o link ab
E para configurar essas cores basta criar uma pasta e fazer uma função de configuração e depois repassar essa função para o ChakraProvider
Dentro do arquivo theme.ts:
import {extendTheme} from '@chakra-ui/react' export const theme = extendTheme({ colors: { gray: { "900": "#181B23", "800": "#1F2029", "700": "#353646", "600": "#4B4D63", "500": "#616480", "400": "#797D9A", "300": "#9699B0", "200": "#B3B5C6", "100": "#D1D2DC", "50": "#EEEEF2", } }, })
No React ou no Next.
import {AppProps} from 'next/app' import { ChakraProvider } from '@chakra-ui/react' import { theme } from '../styles/theme' function MyApp({ Component, pageProps }: AppProps) { return ( <ChakraProvider theme={theme}> <Component {...pageProps} /> </ChakraProvider> ) } export default MyApp
- Tipografia e espaçamento
Essas bibliotecas de interfaces declarativas também fornecem configurações padrões para tipografias e espaçamentos, que já são aplicados ao criar o ChakraProvider (no caso do Chakra).
- Configuração padrão de tipografia do Chakra:
// example theme object export default { colors: {...}, fonts: { body: "system-ui, sans-serif", heading: "Georgia, serif", mono: "Menlo, monospace", }, fontSizes: { xs: "0.75rem", sm: "0.875rem", md: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem", "4xl": "2.25rem", "5xl": "3rem", "6xl": "3.75rem", "7xl": "4.5rem", "8xl": "6rem", "9xl": "8rem", }, fontWeights: { hairline: 100, thin: 200, light: 300, normal: 400, medium: 500, semibold: 600, bold: 700, extrabold: 800, black: 900, }, lineHeights: { normal: "normal", none: 1, shorter: 1.25, short: 1.375, base: 1.5, tall: 1.625, taller: "2", "3": ".75rem", "4": "1rem", "5": "1.25rem", "6": "1.5rem", "7": "1.75rem", "8": "2rem", "9": "2.25rem", "10": "2.5rem", }, letterSpacings: { tighter: "-0.05em", tight: "-0.025em", normal: "0", wide: "0.025em", wider: "0.05em", widest: "0.1em", }, };
- Configuração padrão de espaçamento do Chakra:
export default { space: { px: "1px", 0.5: "0.125rem", 1: "0.25rem", 1.5: "0.375rem", 2: "0.5rem", 2.5: "0.625rem", 3: "0.75rem", 3.5: "0.875rem", 4: "1rem", 5: "1.25rem", 6: "1.5rem", 7: "1.75rem", 8: "2rem", 9: "2.25rem", 10: "2.5rem", 12: "3rem", 14: "3.5rem", 16: "4rem", 20: "5rem", 24: "6rem", 28: "7rem", 32: "8rem", 36: "9rem", 40: "10rem", 44: "11rem", 48: "12rem", 52: "13rem", 56: "14rem", 60: "15rem", 64: "16rem", 72: "18rem", 80: "20rem", 96: "24rem", }, }
Por padrão, o Chakra inclui uma escala de espaçamento numérico inspirada no Tailwind CSS. Os valores são proporcionais, pelo que 1 unidade de espaçamento é igual a 0,25rem, o que corresponde a 4px por em navegadores comuns.
Responsividade
Uma das funcionalidades mais interessantes do Chakra é a facilidade de construir layouts responsivos, para facilitar isso, por padrão o Chakra possui alguns breakpoints:
import { createBreakpoints } from "@chakra-ui/theme-tools" const breakpoints = createBreakpoints({ sm: "30em", md: "48em", lg: "62em", xl: "80em", "2xl": "96em", })
Cada um representado um tipo de tela diferente (mobile, table, e diferentes tamanhos de desktop). A maioria dos componentes dessa biblioteca podem ser customizados de acordo com a resolução da tela., por exemplo, digamos que em uma aplicação que um desenvolvedor esteja construindo, ele queira que sua logo mude de tamanho de acordo com a tela.
import {Text} from "@chakra-ui/react" export const Logo = () => { return( <Text fontSize="3xl" fontWeight="bold" letterSpacing="tight" > dashgo <Text as="span" color="pink.500" ml="1" fontSize="3xl">.</Text> </Text> ) }
Como podemos ver no código a cima, o tamanho da fonte dessa logo está setada como "3xl", mas caso o desenvolvedor queira que apenas no ambiente mobile a fonte tenha um tamanho diferente, ele teria que fazer da seguinte forma:
fontSize={["2xl", "3xl"]}
Ou seja, no ambiente mobile a fonte terá o tamanho de "2xl" e nos demais terá o tamanho de "3xl", essa forma de customizar a responsividade é conhecida como Sintaxe de Array, também seria possível fazer a mesma alteração utilizando a Sintaxe de Objetos.
fontSize={{ base: "24px", md: "40px", lg: "56px" }}
O Chakra também possui um hook próprio para auxiliar no processo de criar telas responsivas que se chama useBreakpointValue, que é um hook personalizado que devolve um valor de acordo com o breakpoint atual a partir do objeto de valores de resposta fornecidos. Este hook também responde ao redimensionamento da tela e devolve o valor apropriado para o novo tamanho de janela.
import { useBreakpointValue } from "@chakra-ui/react"
Caso o desenvolvedor queira que um botão tenha uma estilização diferente de acordo com o tamanho da tela:
function Example() { const variant = useBreakpointValue({ base: "outline", md: "solid" }) return ( <VStack align="flex-start"> <Text>Resize your window to see the button variant change</Text> <Button colorScheme="teal" variant={variant}> Button </Button> </VStack> ) }
Para saber mais sobre essas funcionalidades, recomendo ler a documentação do Chakra:
Estilizando componentes
Estilizar componentes com Chakra é bastante simples, para isso irei lhe mostrar alguns exemplos práticos. Um componente bastante útil e moldável é o <Flex />, que nada mais é do que uma <Box/> com o display flex, e de uma forma bastante rápida você consegue criar uma box e centralizar tudo que tem dentro dela.
<Flex align="center" justify="center"></Flex>
Outro componente bastante interessante é o <Button /> que pode facilmente ser utilizado com a biblioteca react-icons e ainda podendo escolher que lado o você gostaria e colocar o ícone.
<Button leftIcon={<Icon as={RiPencilLine}/>}> Editar </Button>
Conclusão
Esse breve artigo serviu para lhe mostrar a praticidade que é construir interfaces escaláveis com o Chakra UI, claro que essa biblioteca possui muito mais funcionalidades do que foi mostrado aqui, portanto, aconselho a você, desenvolvedor ou desenvolvedora, a dar uma olhadinha na documentação do Chakra, que é bastante intuitiva e simples de entender. Qualquer dúvida, dicas ou sugestões, não se esqueça de deixar nos comentário aqui em baixo.
Espero que tenha curtido 🤟