Como construir um Modal - Angular
Como construir um componente de modal com efeitos de transição utilizando o animations do Angular 2+
No mundo do desenvolvimento, eventualmente encontramos mais de uma forma para chegar no mesmo resultado. A construção de um modal não foge da regra. Neste post vamos mostrar como criar um modal bem simples, de única instância e com o animations
do Angular para dar um efeito visual interessante.
Desenvolvimento da ideia
Pessoalmente gosto de desenvolver a ideia do componente utilizando simplesmente HTML, CSS e JavaScript. Então recorro ao JSFiddle para estudar o cenário.
Dica: no editor do JSFiddle digite html:5
e aperte tab
para o editor criar uma estrutura HTML como a imagem acima mostra. Se quiser saber mais sobre estes atalhos (emmet) acesse este link.
Sem dar muitas voltas, o modal em questão basicamente deve ter sombra, bordas arredondadas e fundo branco. Traduzindo isso para CSS e HTML temos o seguinte código:
.modal {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px #333;
min-width: 320px;
position: fixed;
left: 50%;
padding: 24px;
top: 50%;
transform: translate(-50%, -50%);
}
<div class="modal">
Lorem ipsum dolor sit amet,
consectetur adipisicing elit.
Aliquam, sunt.
</div>
Veja na imagem acima que já temos um resultado inicial mas ainda precisamos evoluir.
Neste texto nosso foco não é o CSS, mas para não passar batido vale comentar que o left: 50%
e o top: 50%
posicionam o <div>
tendo como referencia (origem) a diagonal superior esquerda, ou seja, essa ponta superior esquerda do modal ficará bem no meio da tela conforme a imagem abaixo mostra:
Então adicionamos o translate( -50%, -50%)
para recuar no topo e no lado esquerdo. O recuo equivale a 50% do tamanho do próprio div. Desta forma ele fica centralizado na tela. A imagem abaixo ilustra em azul o cenário sem o translate
e em vermelho com o translate
:
Um outro elemento que normalmente todo modal tem, é um fundo mais escuro que cobre a tela toda por baixo do modal, também conhecido como overlay. Para criarmos este efeito podemos utilizar o seguinte código:
.overlay {
background: #000;
height: 100vh;
left: 0;
opacity: 0.5;
position: fixed;
top: 0;
width: 100vw;
}
<div class="modal">
Lorem ipsum dolor sit amet,
consectetur adipisicing elit.
Aliquam, sunt.
</div>
<div class="overlay"></div>
O resultado ficaria da seguinte forma:
Veja que o overlay ficou em cima do modal. Para corrigir basta adicionar o z-index
no CSS:
.modal {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px #333;
min-width: 320px;
position: fixed;
left: 50%;
padding: 24px;
top: 50%;
transform: translate(-50%, -50%);
z-index: 11;
}
.overlay {
background: #000;
height: 100vh;
left: 0;
opacity: 0.5;
position: fixed;
top: 0;
width: 100vw;
z-index: 10;
}
Resultado final:
Construção do componente no Angular
Agora que montamos uma estrutura HTML + CSS vamos migrar este conteúdo para um componente Angular:
O primeiro passo para testar o modal dentro do app.component.html
é importar o módulo ModalModule
dentro do AppModule
que é quem declara o AppComponent
:
Agora com o ModalModule
importado, podemos testar o modal adicionando algumas linhas de código no app.component.html
:
O #modal
serve para pegarmos a referência do componente. Desta forma conseguimos dentro do próprio template chamar os métodos do modal.
Não precisa ser necessariamente #modal
, poderia ser #abc
ou qualquer outro nome. Veja mais detalhes na documentação oficial: https://angular.io/guide/template-reference-variables
O resultado é o modal em funcionamento:
Inclusão do animations
Agora que já temos um componente de modal, vamos evoluir um pouco para adicionar uma transição visual mais agradável. Vamos adicionar um efeito fade no fundo escuro que fica por trás (overlay) e adicionar uma animação do tipo slide na parte branca do modal.
Para executar esta tarefa vamos recorrer ao animations do Angular. O primeiro passo é importar o BrowserAnimationsModule
. A importação deve ser feita no módulo raiz da sua aplicação. Neste exemplo o módulo root é o AppModule
:
Agora vamos configurar os efeitos no componente modal e na sequência vêm a explicação:
Foram criadas duas trigger
, uma para cada elemento (overlay e o corpo do modal). Cada trigger
acima tem duas possíveis transições:
:enter
-> ocorre quando entramos no*ngIf
, ou seja, o modal será mostrado na tela:leave
-> ocorre quando não entramos no*ngIf
, ou seja, o modal está sendo escondido
Para vincular a trigger
ao elemento HTML utilizamos o prefixo @
seguido do nome da trigger
, conforme está no modal.component.html
acima.
Veja o resultado logo abaixo:
Corrigindo a altura do modal
Na forma que nosso componente está, se adicionarmos muito conteúdo dentro do modal ele vai passar da área visível da tela. Para resolver este problema vamos ajustar a classe .modal
dentro do modal.component.css
:
Adicionamos uma largura mínima de 320px
, uma altura máxima de 90% da altura do viewport e caso o conteúdo exceda esse espaço vertical, uma barra de scroll será apresentada.
Considerações
O modelo do componente de modal proposto neste texto possui um mecanismo bem simples. Caso você necessite controlar várias instâncias ao mesmo tempo será necessário evoluir um pouco mais esta ideia de forma análoga ao que foi mostrado no post Como construir um componente para notificações.
Um outro ponto que poderíamos evoluir, é que o modal só é exibido quando chamamos o método toggle()
, mas poderíamos criar um @Input() exibir
para permitir uma outra forma de controle na exibição do modal: <app-modal [exibir]="true">...
Também não chegamos a adicionar um botão X
para fechar o modal nem falamos sobre acessibilidade. Em um próximo texto abordarei estes assuntos.