logo

Banner do Post

Construindo interfaces declarativas com Chakra UI

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 🤟

Typescript: interfaces Vs Type

Post anterior

Programação assíncrona, Event Loop e NodeJs

Próximo post