Modal

Professional modal dialogs for property details, forms, and confirmations with smooth animations.

Modal Variants

Standard Modal

Classic modal with header, body, and footer

Property Details

This luxury penthouse offers breathtaking views of the city skyline.

  • Living Area: 185 m²
  • Bedrooms: 3
  • Bathrooms: 2
  • Terrace: 45 m²

Small Modal

Compact modal for confirmations

Confirm Action

Are you sure you want to delete this property listing?

Large Modal

Spacious modal for detailed content

Property Gallery

Image 1
Image 2
Image 3
Image 4

Real Estate Use Cases

Contact Form Modal

Contact Agent

Implementation Guide

HTML Structure

<!-- Trigger Button -->
<button class="lyd-button primary" onclick="openModal('myModal')">
    Open Modal
</button>

<!-- Modal Structure -->
<div class="lyd-modal-backdrop" id="myModal-backdrop">
    <div class="lyd-modal" id="myModal">
        <div class="lyd-modal-header">
            <h3 class="lyd-modal-title">Modal Title</h3>
            <button class="lyd-modal-close" onclick="closeModal('myModal')">
                <svg>...</svg>
            </button>
        </div>
        <div class="lyd-modal-body">
            <!-- Modal content -->
        </div>
        <div class="lyd-modal-footer">
            <button class="lyd-button secondary">Cancel</button>
            <button class="lyd-button primary">Confirm</button>
        </div>
    </div>
</div>

JavaScript Functions

// Open modal
function openModal(modalId) {
    const backdrop = document.getElementById(modalId + '-backdrop');
    const modal = document.getElementById(modalId);
    
    if (backdrop && modal) {
        backdrop.classList.add('active');
        modal.classList.add('active');
        document.body.style.overflow = 'hidden';
    }
}

// Close modal
function closeModal(modalId) {
    const backdrop = document.getElementById(modalId + '-backdrop');
    const modal = document.getElementById(modalId);
    
    if (backdrop && modal) {
        backdrop.classList.remove('active');
        modal.classList.remove('active');
        document.body.style.overflow = '';
    }
}

// Close on backdrop click
document.querySelectorAll('.lyd-modal-backdrop').forEach(backdrop => {
    backdrop.addEventListener('click', (e) => {
        if (e.target === backdrop) {
            const modalId = backdrop.id.replace('-backdrop', '');
            closeModal(modalId);
        }
    });
});

React/Next.js Component

// components/Modal.tsx
import { ReactNode, useEffect } from 'react';

interface ModalProps {
  isOpen: boolean;
  onClose: () => void;
  title: string;
  children: ReactNode;
  size?: 'small' | 'medium' | 'large';
}

export const Modal = ({ 
  isOpen, 
  onClose, 
  title, 
  children,
  size = 'medium' 
}: ModalProps) => {
  useEffect(() => {
    if (isOpen) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }
    return () => {
      document.body.style.overflow = '';
    };
  }, [isOpen]);
  
  if (!isOpen) return null;
  
  return (
    <div 
      className={`lyd-modal-backdrop ${isOpen ? 'active' : ''}`}
      onClick={onClose}
    >
      <div 
        className={`lyd-modal ${size} ${isOpen ? 'active' : ''}`}
        onClick={(e) => e.stopPropagation()}
      >
        <div className="lyd-modal-header">
          <h3 className="lyd-modal-title">{title}</h3>
          <button className="lyd-modal-close" onClick={onClose}>
            <svg>...</svg>
          </button>
        </div>
        <div className="lyd-modal-body">
          {children}
        </div>
      </div>
    </div>
  );
};

API Reference

Class Description
.lyd-modal-backdrop Dark overlay behind modal
.lyd-modal Main modal container
.lyd-modal-header Modal header with title and close button
.lyd-modal-title Modal title text
.lyd-modal-close Close button in header
.lyd-modal-body Main content area
.lyd-modal-footer Footer with action buttons
.small Small modal size (400px)
.large Large modal size (900px)
.fullscreen Fullscreen modal
.active Shows modal and backdrop

Accessibility & Best Practices

Keyboard Navigation

  • Escape key to close modal
  • Tab to navigate within modal
  • Focus trap inside modal
  • Return focus to trigger on close

Screen Reader Support

  • Use role="dialog" and aria-modal="true"
  • Provide aria-labelledby for title
  • Announce modal opening/closing
  • Hide background content with aria-hidden

Best Practices

  • Prevent body scroll when open
  • Close on backdrop click
  • Smooth open/close animations
  • Responsive sizing on mobile
  • Clear visual hierarchy