Dominando Modais: O Padrão Bottom Sheet React Native

No desenvolvimento mobile moderno, a experiência do usuário (UX) é definida pelos detalhes. Se no artigo anterior exploramos as notificações de topo, hoje vamos dominar o Bottom Sheet React Native — aquele modal que desliza suavemente da base para cima. Este é, atualmente, um dos padrões de design mais fortes em apps como Instagram, Uber e Nubank.

📚 Baixar Código Base

1. Por que usar o Bottom Sheet?

Diferente dos alertas centrais que “saltam” e interrompem a visão, o Bottom Sheet é preferido porque mantém os elementos de interação próximos ao polegar do usuário. Isso facilita o uso do aparelho com apenas uma mão, algo essencial para a usabilidade no dia a dia.

2. Anatomia do Código Profissional

Para que o efeito seja fluido e pareça nativo, nossa implementação se baseia em três pilares:

A. O Overlay Inteligente

Usamos uma camada semitransparente para dar foco ao modal. Um detalhe crucial de UX: ao tocar no espaço vazio acima do modal, ele deve fechar.

<TouchableOpacity 
  style={estilos.fecharOverlay} 
  onPress={() => setModalVisivel(false)} 
/>

B. O Indicador de Arraste (Handle)

Um detalhe sutil, mas poderoso, é criar uma pequena barra no topo do modal. Ela sinaliza visualmente ao usuário que aquele painel pode ser “puxado” ou descartado para baixo.

C. Estilização e Sombras

Para o visual de “aba”, aplicamos borderTopLeftRadius e borderTopRightRadius. Somado ao elevation (Android), criamos a profundidade necessária.

3. Implementação Prática (Laboratório)

import React, { useState } from 'react';
import { View, Text, StyleSheet, Modal, TouchableOpacity} from 'react-native';

export default function App() {
  const [modalVisivel, setModalVisivel] = useState(false);

  return (
    <View style={estilos.container}>
      

      <TouchableOpacity 
        style={estilos.botaoPrincipal} 
        onPress={() => setModalVisivel(true)}
        activeOpacity={0.7}
      >
        <Text style={estilos.textoBotaoPrincipal}>Abrir Painel</Text>
      </TouchableOpacity>

      <Modal 
        animationType="slide" 
        visible={modalVisivel} 
        transparent={true}
        onRequestClose={() => setModalVisivel(false)} // Essencial para o botão 'voltar' no Android
      >
        <View style={estilos.overlay}>
          {/* View clicável fora do conteúdo para fechar o modal ao tocar no fundo */}
          <TouchableOpacity 
            style={estilos.fecharOverlay} 
            onPress={() => setModalVisivel(false)} 
          />
          
          <View style={estilos.modalInferior}>
            <View style={estilos.indicador} />
            
            <Text style={estilos.tituloModal}>Bem-vindo</Text>
            <Text style={estilos.textoModal}>Este é um exemplo de modal com informações para o usuário.</Text>
            
            <TouchableOpacity 
              style={estilos.botaoSair} 
              onPress={() => setModalVisivel(false)}
            >
              <Text style={estilos.textoBotaoSair}>Fechar</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </View>
  );
}

const estilos = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5F7FA',
  },
  botaoPrincipal: {
    backgroundColor: '#4F46E5',
    paddingVertical: 15,
    paddingHorizontal: 40,
    borderRadius: 12,
    elevation: 3,
  },
  textoBotaoPrincipal: {
    color: '#FFF',
    fontSize: 16,
    fontWeight: 'bold',
  },
  overlay: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.4)', // Escurece o fundo suavemente
    justifyContent: 'flex-end',
  },
  fecharOverlay: {
    flex: 1,
  },
  modalInferior: {
    backgroundColor: '#FFF',
    paddingHorizontal: 25,
    paddingTop: 12,
    paddingBottom: 40,
    borderTopLeftRadius: 30,
    borderTopRightRadius: 30,
    alignItems: 'center',
    elevation: 20,
    shadowColor: '#000', // Sombra para iOS
    shadowOffset: { width: 0, height: -3 },
    shadowOpacity: 0.1,
    shadowRadius: 10,
  },
  indicador: {
    width: 40,
    height: 5,
    backgroundColor: '#E2E8F0',
    borderRadius: 10,
    marginBottom: 20,
  },
  tituloModal: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#1A202C',
    marginBottom: 8,
  },
  textoModal: {
    fontSize: 16,
    color: '#718096',
    textAlign: 'center',
    marginBottom: 25,
  },
  botaoSair: {
    width: '100%',
    backgroundColor: '#F1F5F9',
    padding: 15,
    borderRadius: 12,
    alignItems: 'center',
  },
  textoBotaoSair: {
    color: '#475569',
    fontSize: 16,
    fontWeight: '600',
  },
});

🧠 Desafio de Autonomia: Dark Mode

Agora que você tem a estrutura, tente aplicar o Pensamento Analítico: como você alteraria as cores do modalInferior e dos textos para criar um “Modo Noturno”? Mudar as cores de fundo para #1A202C e os textos para #FFF é um ótimo começo!


⬅️ Artigo Anterior: Criando Modais Modernos: O Top Alert

➡️ Próximo Passo: Trabalhando com Listas: O poder da FlatList

Compartilhe:

Profissional engajado com as últimas tendências tecnológicas e de gestão, buscando continuamente aprimorar suas competências e compartilhar seu conhecimento.

2 comments

Publicar comentário