🚀ReacUI is currently in Beta. We're actively improving it! ❣️

Modal

A dialog component for displaying content that requires user interaction

Installation

The Modal component is part of the ReacUI library. Install the package to use it in your project.

npm install reacui

Import

Import the Modal component into your React component.

import { Modal } from 'reacui';

Basic Modal

A basic modal with a title, content, and action buttons.

import { useState } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Open Modal
      </button>
      
      <Modal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        title="Modal Title"
      >
        <Modal.Body>
          This is the content of the modal. You can put any information 
          or form elements here.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsOpen(false)}>
            Confirm
          </Modal.Button>
          <Modal.Button variant="secondary" onClick={() => setIsOpen(false)}>
            Cancel
          </Modal.Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

Modal Sizes

Modals come in different sizes to fit your content needs.

import { useState } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isSmallOpen, setIsSmallOpen] = useState(false);
  const [isMediumOpen, setIsMediumOpen] = useState(false);
  const [isLargeOpen, setIsLargeOpen] = useState(false);
  
  return (
    <>
      <button onClick={() => setIsSmallOpen(true)}>
        Small Modal
      </button>
      <button onClick={() => setIsMediumOpen(true)}>
        Medium Modal
      </button>
      <button onClick={() => setIsLargeOpen(true)}>
        Large Modal
      </button>
      
      <Modal
        isOpen={isSmallOpen}
        onClose={() => setIsSmallOpen(false)}
        title="Small Modal"
        size="sm"
      >
        <Modal.Body>
          This is a small modal dialog, perfect for simple confirmations or alerts.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsSmallOpen(false)}>
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>

      <Modal
        isOpen={isMediumOpen}
        onClose={() => setIsMediumOpen(false)}
        title="Medium Modal"
        size="md"
      >
        <Modal.Body>
          This is a medium modal dialog.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsMediumOpen(false)}>
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>

      <Modal
        isOpen={isLargeOpen}
        onClose={() => setIsLargeOpen(false)}
        title="Large Modal"
        size="lg"
      >
        <Modal.Body>
          <p>This is a large modal dialog with more content...</p>
          <div className="grid grid-cols-2 gap-4 mt-4">
            <div className="bg-secondary-50 p-4 rounded">
              <h4>Section 1</h4>
              <p>Information can be organized in different sections.</p>
            </div>
            <div className="bg-secondary-50 p-4 rounded">
              <h4>Section 2</h4>
              <p>Provide additional details in a structured layout.</p>
            </div>
          </div>
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsLargeOpen(false)}>
            Save Changes
          </Modal.Button>
          <Modal.Button variant="secondary" onClick={() => setIsLargeOpen(false)}>
            Cancel
          </Modal.Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

Modal Positioning

Control the vertical position of your modals to create different visual effects.

import { useState } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isCenteredOpen, setIsCenteredOpen] = useState(false);
  const [isTopOpen, setIsTopOpen] = useState(false);
  
  return (
    <>
      <button onClick={() => setIsCenteredOpen(true)}>
        Centered Modal
      </button>
      <button onClick={() => setIsTopOpen(true)}>
        Top Modal
      </button>
      
      <Modal
        isOpen={isCenteredOpen}
        onClose={() => setIsCenteredOpen(false)}
        title="Centered Modal"
        position="center"
      >
        <Modal.Body>
          This modal is centered vertically in the viewport, which is the default position.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsCenteredOpen(false)}>
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>

      <Modal
        isOpen={isTopOpen}
        onClose={() => setIsTopOpen(false)}
        title="Top Modal"
        position="top"
      >
        <Modal.Body>
          This modal appears at the top of the viewport instead of being centered.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsTopOpen(false)}>
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

Animations

Add smooth animations to your modals for a better user experience.

import { useState } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isFadeModalOpen, setIsFadeModalOpen] = useState(false);
  const [isSlideModalOpen, setIsSlideModalOpen] = useState(false);
  
  return (
    <>
      <button onClick={() => setIsFadeModalOpen(true)}>
        Fade In Modal
      </button>
      <button onClick={() => setIsSlideModalOpen(true)}>
        Slide Up Modal
      </button>
      
      <Modal
        isOpen={isFadeModalOpen}
        onClose={() => setIsFadeModalOpen(false)}
        title="Fade In Modal"
        animation="fade"
      >
        <Modal.Body>
          This modal smoothly fades in when it appears.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsFadeModalOpen(false)}>
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>

      <Modal
        isOpen={isSlideModalOpen}
        onClose={() => setIsSlideModalOpen(false)}
        title="Slide Up Modal"
        animation="slide-up"
      >
        <Modal.Body>
          This modal slides up from the bottom when it appears.
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button variant="primary" onClick={() => setIsSlideModalOpen(false)}>
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

Forms in Modals

Modals are perfect for containing forms that require user input.

import { useState, useRef } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isOpen, setIsOpen] = useState(false);
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const initialFocusRef = useRef(null);
  
  const handleSubmit = (e) => {
    e.preventDefault();
    alert(`Form submitted with Name: ${name}, Email: ${email}`);
    setIsOpen(false);
    setName('');
    setEmail('');
  };
  
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Open Form Modal
      </button>
      
      <Modal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        title="Contact Information"
        initialFocus={initialFocusRef}
      >
        <form onSubmit={handleSubmit}>
          <Modal.Body>
            <div className="space-y-4">
              <div>
                <label htmlFor="name" className="block text-sm font-medium mb-1">
                  Name
                </label>
                <input
                  ref={initialFocusRef}
                  type="text"
                  id="name"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  placeholder="Enter your name"
                  className="block w-full rounded-md border p-2"
                  required
                />
              </div>
              <div>
                <label htmlFor="email" className="block text-sm font-medium mb-1">
                  Email
                </label>
                <input
                  type="email"
                  id="email"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  placeholder="Enter your email"
                  className="block w-full rounded-md border p-2"
                  required
                />
              </div>
            </div>
          </Modal.Body>
          <Modal.Footer>
            <Modal.Button type="submit" variant="primary">
              Submit
            </Modal.Button>
            <Modal.Button variant="secondary" onClick={() => setIsOpen(false)}>
              Cancel
            </Modal.Button>
          </Modal.Footer>
        </form>
      </Modal>
    </>
  );
}

Customization

Customize the modal with different styles and content.

import { useState } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <>
      <button 
        onClick={() => setIsOpen(true)}
        className="px-4 py-2 bg-gradient-to-r from-pink-500 to-purple-600 text-white rounded-full"
      >
        Custom Modal
      </button>
      
      <Modal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        className="rounded-2xl bg-gradient-to-r from-pink-50 to-purple-50 border border-purple-200"
        contentClassName="p-6 text-center"
        closeButton
        overlayClassName="backdrop-blur-sm"
      >
        <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-r from-pink-500 to-purple-600 mb-4">
          <CheckIcon className="h-8 w-8 text-white" />
        </div>
        <h3 className="text-xl font-semibold">Custom Styled Modal</h3>
        <p className="mt-3 text-secondary-600">
          This modal has a custom design with gradient backgrounds, rounded corners, and styled content.
        </p>
        <div className="mt-6 grid grid-cols-2 gap-3">
          <Modal.Button 
            variant="custom" 
            onClick={() => setIsOpen(false)}
            className="py-2.5 bg-gradient-to-r from-pink-500 to-purple-600 text-white rounded-full"
          >
            Confirm
          </Modal.Button>
          <Modal.Button 
            variant="custom" 
            onClick={() => setIsOpen(false)}
            className="py-2.5 bg-white text-secondary-900 border border-secondary-300 rounded-full"
          >
            Cancel
          </Modal.Button>
        </div>
      </Modal>
    </>
  );
}

Accessibility

The Modal component implements best practices for accessibility, including keyboard navigation, focus management, and ARIA attributes.

import { useState, useRef } from 'react';
import { Modal } from 'reacui';

function Example() {
  const [isOpen, setIsOpen] = useState(false);
  const initialFocusRef = useRef(null);
  
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Accessible Modal
      </button>
      
      <Modal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        title="Accessible Modal"
        initialFocus={initialFocusRef}
        closeButton
        aria={{
          labelledby: "modal-title"
        }}
      >
        <Modal.Body>
          <p>This modal implements accessibility best practices:</p>
          <ul className="mt-2 list-disc list-inside space-y-1">
            <li>Proper ARIA attributes</li>
            <li>Focus management</li>
            <li>Keyboard navigation</li>
            <li>Screen reader support</li>
          </ul>
        </Modal.Body>
        <Modal.Footer>
          <Modal.Button 
            ref={initialFocusRef}
            variant="primary" 
            onClick={() => setIsOpen(false)}
          >
            Close
          </Modal.Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

API Reference

The following props are available for the Modal component.

ComponentPropTypeDefaultDescription
ModalisOpenbooleanfalseControls whether the modal is displayed
onClosefunctionrequiredFunction called when the modal should close
childrenReactNoderequiredContent to display inside the modal
titlestring-Optional title for the modal
sizestring'md'Size of the modal: 'sm', 'md', 'lg', 'xl', 'full'
positionstring'center'Vertical position of the modal: 'center', 'top'
animationstring'none'Animation style: 'none', 'fade', 'scale', 'slide-up'
initialFocusRefObject-Ref to the element that should receive focus when the modal opens
closeButtonbooleanfalseWhether to show a close button in the top-right corner
closeOnEscbooleantrueWhether to close the modal when the Escape key is pressed
closeOnOverlayClickbooleantrueWhether to close the modal when clicking the overlay
classNamestring''Additional CSS classes for the modal container
contentClassNamestring''Additional CSS classes for the modal content
overlayClassNamestring''Additional CSS classes for the modal overlay
Modal.BodyclassNamestring''Additional CSS classes for the modal body
Modal.HeaderclassNamestring''Additional CSS classes for the modal header
Modal.FooterclassNamestring''Additional CSS classes for the modal footer
Modal.Buttonvariantstring'primary'Button variant: 'primary', 'secondary', 'danger', 'custom'
onClickfunction-Function called when the button is clicked
classNamestring''Additional CSS classes for the button