Criando um menu responsivo com React e Material UI

Quando você possui uma navegação em seu projeto web, ela precisa muitas vezes passar por mudanças e adaptações para se adaptar num browser mobile. Você pode aprender mais sobre como fazer isso em Adaptando um site em dispositivos móveis na prática.

Muitas vezes simples soluções usam apenas CSS e diferentes organizações, e partes essenciais do projeto precisa se transformar em componentes diferentes, como acontece com navegações em menu e outros elementos sensíveis a variação de tela. Quando se fala de adaptação de Menus, há diversas soluções para adaptá-lo, e o menu hamburger é o mais conhecido.

A navegação hamburger é bem comum em sites mobile. Fonte: dribbble.com/shots/2269450-hamburger-menu-2

Ele não é exibido no desktop, onde temos espaço suficiente para vários itens de menu. Quando a visão é mobile, um novo item de menu é criado e os items que antes eram principais, passam a ser submenus deste menu principal. Eu vou mostrar com um exemplo prático como isto é feito usando o Material UI para React.

Para ver o demo em funcionamento, acesse o template para Material UI que eu criei open source.

Por que usar o Material UI?

Material UI é um framework de interface para React, como o Bootstrap, mas baseado na linguagem de design chamada Material Design desenvolvido pelo Google. Ela é uma poderosa ferramenta com componentes já prontos e personalizáveis para você desenvolver interfaces de forma mais eficiente.

Não existe apenas o Material UI. Há muitas outras bibliotecas com interface muito ricas e com componentes “lindos”. Você pode ver uma lista de outros frameworks aqui: github.com/manzinello/beautiful-react-ui-components.

Fiz uma apresentação no Sencha Community Days na Alemanha falando um pouco de bibliotecas de interface e suas vantagens e você pode obter a apresentação (em inglês).

Basicamente, as vantagens do Material-UI, dentre outras, inclui:

  1. Consistência no design e de experiência para qualquer design
  2. Reutilização de código
  3. Personalização e flexibilidade de componentes

Em outro post, falo das vantagens de continuar utilizando o Bootstrap, que também é uma das bibliotecas de front-end mais populares.

Material Sense

O Material Sense foi um template que desenvolvi usando o Material-UI para mostrar sua flexibilidade e como criar templates que pode ser usado como referência para projetos, principalmente projetos de visualização de dados. Ele consta na lista de exemplos de projetos que utilizam o Material UI na página da documentação.

O Material Sense é um projeto open source desenvolvido como um exemplo de uso do Material UI para react. Github: github.com/alexanmtz/material-sense

Menu do topo

Para começar, definimos o menu com o Material UI com o componente AppBar, então um Toolbar para então dentro dele declarar um menu de tabs. Também teremos de forma complementar um tipo de Menu chamado Drawer do Material UI, que é responsável por carregar um menu em uma barra lateral.

O passos para tornar isto isto possível de maneira amigável:

  1. Criamos um menu de tabs dentro de um grid
  2. Temos um outro menu em lista que inicialmente permanece escondido
  3. Criamos seletores que ativam o menu que estava escondido, e esconde o que inicialmente é mostrado para desktop

Criando um menu de tabs usando o Material-UI

Primeiro, vamos começar criando um menu simples em tabs usando os componentes do Material UI. Escolhemos o breakpoint definido como sm (small) em um breakpoint para este menu em tabs para que ele não apareça no Mobile.

Este código contém os estilos usados e regras usando breakpoints com declarações usando JSS (Javascript Style Sheet). É possível fazer de outras formas, a idéia aqui é utilizar media queries para esconder e exibir elementos de acordo com a resolucão de tela.

No código acima, renderizamos o menu vindo de um array de elementos. Com este array podemos renderizar o menu e definir estrutura para ele, como se ele será externo ou se irá navegar para outras páginas com o React Router. Com este menu em um componente separado, podemos também renderizá-lo mais de uma vez, no caso nosso teremos o menu renderizado para mobile e outro para Desktop.

Você pode argumentar com razão sobre ter duplicidade de conteúdo, mas para propósitos de simplificar, vou seguir com esta solução de renderizar dois menus, até por que não serão menus com 50 itens, na verdade longe disto. São menus que devem ocupar o espaço de uma página desktop.

Então temos os seguintes itens do menu vindo de um array de elementos no arquivo Menu.js:

Adicionando o botão do menu hamburger que ativa o Drawer menu para mobile

Aqui, como você pode ver nos estilos, nós escondemos inicialmente o botão de menu hamburger no mobile e criamos um breakpoint para quando for uma tela menor ele exibe o botão, e assim ele pode ativar o Drawer menu e renderizamos o menu novamente, desta vez como parte de uma lista de Itens que irá ser renderizado do lado direito da tela.

Resultado

Um exemplo de um menu adaptado para mobile:
alexanmtz.github.io/material-sense

Um menu hamburger com os subitems abertos em uma navegação mobile

Como o menu de tabs é renderizado no template. Demo: alexanmtz.github.io/material-sense

Código final:

Exemplo no Github: github.com/alexanmtz/material-sense/blob/master/src/components/Topbar.js

Demo: alexanmtz.github.io/material-sense

Quer contribuir com o Open Source, dê uma estrelinha para o Material-Sense e ajude a resolver nossas issues! Você também pode criar novas issues sugerindo melhorias e enviando Pull Request com suas contribuições! Você também pode receber recompensas também pelas issues resolvidas através do Gitpay.

Bem, se você chegou até aqui agora você é capaz de desenvolver o menu do seu projeto adaptado para mobile utilizando Material UI com React. Você pode usar o Create React App como usei no projeto do Material Sense para criar apps front-end e ainda utilizar o Github Pages para fazer deploys diretamente, sendo possível ter um host grátis nas suas mãos.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *