Modal
O componente modal fornece uma base sólida para criar diálogos, popovers, lightboxes ou qualquer outra coisa.
O componente renderiza o conteúdo de seu children
sobre um componente backdrop. O Modal
oferece recursos importantes:
- 💄 Gerencia o empilhamento de chamadas quando ter um de cada vez não for suficiente.
- 🔐 Cria um plano de fundo para desabilitar a interação abaixo do modal.
- 🔐 Desativa a rolagem do conteúdo da página enquanto estiver aberto.
- ♿️ Gerencia adequadamente o foco; movendo para o conteúdo modal, e mantendo-o lá até que o modal seja fechado.
- ♿️ Adiciona as funções ARIA apropriadas automaticamente.
- 📦 5 kB gzipped.
Nota sobre a terminologia. O termo "modal" algumas vezes é usado com o sentido de "diálogo", mas isto é um equívoco. Uma janela modal descreve partes de uma UI. Um elemento é considerado modal se ele bloqueia interações com o resto da aplicação.
Se você está criando um diálogo modal, você provavelmente quer usar o componente Dialog em vez de diretamente um Modal. Modal é uma estrutura de baixo-nível que é aproveitada pelos seguintes componentes:
Modal simples
<button type="button" onClick={handleOpen}>
Open Modal
</button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
{body}
</Modal>
Você pode desativar o contorno (muitas vezes azul ou ouro) com a propriedade CSS outline: 0
.
Transições
O estado de aberto/fechado do modal pode ser animado com um componente de transição. Este componente deve respeitar as seguintes condições:
- Seja um filho direto descendente do modal.
- Tenha uma propriedade
in
. Isso corresponde ao estado de aberto/fechado. - Chamar a propriedade de callback
onEnter
quando a transição de entrada iniciar. - Chamar a propriedade de callback
onExited
quando a transição de saída for concluída. Esses dois callbacks permitem que o modal desmonte o conteúdo filho quando fechado e seja totalmente transitado.
O modal possui suporte interno para react-transition-group.
Como alternativa, você pode usar react-spring.
Modal do lado do servidor
React não suporta a API createPortal()
no servidor. Para exibir o modal, você precisa desativar o recurso portal com a propriedade disablePortal
:
Server-side modal
If you disable JavaScript, you will still see me.
<Modal
disablePortal
disableEnforceFocus
disableAutoFocus
open
aria-labelledby="server-modal-title"
aria-describedby="server-modal-description"
className={classes.modal}
container={() => rootRef.current}
>
<div className={classes.paper}>
<h2 id="server-modal-title">Server-side modal</h2>
<p id="server-modal-description">If you disable JavaScript, you will still see me.</p>
</div>
</Modal>
Limitações
Captura do foco
O modal move o foco de volta para o corpo do componente se o foco tentar escapar dele.
No entanto, isso é feito para fins de acessibilidade, e pode criar problemas. No caso de os usuários precisarem interagir com outra parte da página, por exemplo, com uma janela de chatbot, você pode desabilitar o comportamento:
<Modal disableEnforceFocus />
Acessibilidade
(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#dialog_modal)
Certifique-se de adicionar
aria-labelledby="id..."
, referenciando o título modal, aoModal
. Adicionalmente, você pode dar uma descrição do seu modal com a propriedadearia-describedby = "id..."
noModal
.<Modal aria-labelledby="modal-title" aria-describedby="modal-description" > <h2 id="modal-title"> Meu Título </h2> <p id="modal-description"> Minha Descrição </p> </Modal>
O WAI-ARIA authoring practices pode ajudá-lo a definir o foco inicial no elemento mais relevante, com base no seu conteúdo modal.
Esteja ciente que uma "janela modal" sobrepõe a janela primária ou qualquer outra janela modal. As janelas sob um modal são inertes. Ou seja, os usuários não podem interagir com o conteúdo fora de uma janela modal ativa. Isso pode criar comportamentos conflitantes.