Skip to content
MeshLab
All posts

Modal Using Tailwind and Angular

Mesh
Updated Mar 7, 2024, 11:22 PM

Here's how to implement a simple modal in tailwind and angular (v17):

dialog.component.html :

<div
  class="flex items-center justify-center fixed z-[99997] left-0 top-0 w-full h-full overflow-auto overflow-y-hidden bg-black bg-opacity-40"
  (click)="closeDialog($event)"
>
  <div class="bg-base-100 my-[15%] mx-auto p-5 w-[40%] shadow-lg" [ngStyle]="{ minWidth: contentWidth + '%' }">
    <button type="button" class="btn btn-ghost btn-circle" data-bs-dismiss="dialog" (click)="dialogClosed()">
      <i class="fas fa-x"></i>
    </button>
    <div class="card">
      @if (title) {
			<div class="d-flex justify-content-center m-1 border-bottom prose mx-auto">
				<h3>{{ title }}</h3>
			</div>
			<div class="divider"></div>
      }
      <div class="px-10 h-[400px] overflow-y-scroll border border-gray-50 rounded-lg">
        <ng-content></ng-content>
      </div>
    </div>
  </div>
</div>

dialog.component.ts

import { Component, EventEmitter, Input, Output } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-dialog',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './dialog.component.html',
})
export class DialogComponent {
  @Input() title: string | undefined;
  @Input() contentWidth = window.screen.width < 700 ? 90 : 50;
  @Output() closed = new EventEmitter(false);
  @Input() enableClickOutsideClose = true;

  ngOnInit(): void {
    document.body.classList.add('modal-open');
    window.addEventListener('keyup', (e) => {
      if (e.key !== 'Escape') return;

      this.closed.emit(false);
    });
  }

  dialogClosed(): void {
    this.closed.emit(false);
  }

  closeDialog(e: any): void {
    if (this.enableClickOutsideClose && e.target === e.currentTarget) this.closed.emit(false);
  }

  ngOnDestroy(): void {
    document.body.classList.remove('modal-open');
  }
}

and add this in global styles.scss:

body.modal-open {
  overflow-y: hidden;
}

Comments 0

Sign in to join the conversation.

No comments yet. Start the conversation.