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 🤟
