Overview
The Modal component displays content in a layer above the main application, blocking interaction with the underlying page until dismissed.
Basic Usage
import { Modal, Button } from '@yourproject/components';
import { useState } from 'react';
function Example() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>
Open Modal
</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
>
<h2>Modal Title</h2>
<p>Modal content goes here.</p>
</Modal>
</>
);
}
Sizes
Modals come in multiple sizes to accommodate different content needs:
<Modal size="sm" isOpen={isOpen} onClose={onClose}>
Small modal for brief messages or simple forms.
</Modal>
<Modal size="md" isOpen={isOpen} onClose={onClose}>
Medium modal for standard dialogs (default).
</Modal>
<Modal size="lg" isOpen={isOpen} onClose={onClose}>
Large modal for detailed content or complex forms.
</Modal>
<Modal size="full" isOpen={isOpen} onClose={onClose}>
Full-screen modal for immersive experiences.
</Modal>
Modal Structure
With Header, Body, and Footer
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from '@yourproject/components';
function Example() {
const [isOpen, setIsOpen] = useState(false);
return (
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
<ModalHeader>
Confirm Action
</ModalHeader>
<ModalBody>
Are you sure you want to proceed? This action cannot be undone.
</ModalBody>
<ModalFooter>
<Button variant="secondary" onClick={() => setIsOpen(false)}>
Cancel
</Button>
<Button variant="primary" onClick={handleConfirm}>
Confirm
</Button>
</ModalFooter>
</Modal>
);
}
Close Behavior
Disable Outside Click
<Modal
isOpen={isOpen}
onClose={onClose}
closeOnOutsideClick={false}
>
This modal won't close when clicking the backdrop.
</Modal>
Disable Escape Key
<Modal
isOpen={isOpen}
onClose={onClose}
closeOnEscape={false}
>
This modal won't close with the Escape key.
</Modal>
<Modal
isOpen={isOpen}
onClose={onClose}
showCloseButton={false}
>
This modal has no close button (must be closed programmatically).
</Modal>
Props
Modal Props
Controls whether the modal is visible
Callback function when modal should close: () => void
Modal size: sm, md, lg, or full
Whether clicking the backdrop closes the modal
Whether pressing Escape closes the modal
Whether to show the X close button in the header
The content to display in the modal
Additional CSS class names to apply
CSS class names for the backdrop overlay
Header content (typically a title)
ModalBody Props
Footer content (typically action buttons)
Alignment of footer content: left, center, or right
TypeScript Interfaces
interface ModalProps {
isOpen: boolean;
onClose: () => void;
size?: 'sm' | 'md' | 'lg' | 'full';
closeOnOutsideClick?: boolean;
closeOnEscape?: boolean;
showCloseButton?: boolean;
children: React.ReactNode;
className?: string;
overlayClassName?: string;
}
interface ModalHeaderProps {
children: React.ReactNode;
className?: string;
}
interface ModalBodyProps {
children: React.ReactNode;
className?: string;
}
interface ModalFooterProps {
children: React.ReactNode;
align?: 'left' | 'center' | 'right';
className?: string;
}
Advanced Examples
Confirmation Modal
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from '@yourproject/components';
import { useState } from 'react';
function DeleteConfirmation() {
const [isOpen, setIsOpen] = useState(false);
const handleDelete = async () => {
await deleteItem();
setIsOpen(false);
};
return (
<>
<Button variant="danger" onClick={() => setIsOpen(true)}>
Delete Item
</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
size="sm"
>
<ModalHeader>
Confirm Deletion
</ModalHeader>
<ModalBody>
Are you sure you want to delete this item? This action cannot be undone.
</ModalBody>
<ModalFooter>
<Button variant="secondary" onClick={() => setIsOpen(false)}>
Cancel
</Button>
<Button variant="danger" onClick={handleDelete}>
Delete
</Button>
</ModalFooter>
</Modal>
</>
);
}
import { Modal, ModalHeader, ModalBody, ModalFooter, Input, Button } from '@yourproject/components';
import { useState } from 'react';
function CreateUserModal() {
const [isOpen, setIsOpen] = useState(false);
const [formData, setFormData] = useState({ name: '', email: '' });
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await createUser(formData);
setIsOpen(false);
};
return (
<>
<Button onClick={() => setIsOpen(true)}>
Create User
</Button>
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
<form onSubmit={handleSubmit}>
<ModalHeader>
Create New User
</ModalHeader>
<ModalBody>
<Input
label="Name"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
required
/>
<Input
label="Email"
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
required
/>
</ModalBody>
<ModalFooter>
<Button variant="secondary" onClick={() => setIsOpen(false)}>
Cancel
</Button>
<Button variant="primary" type="submit">
Create
</Button>
</ModalFooter>
</form>
</Modal>
</>
);
}
Use the closeOnOutsideClick={false} prop for forms to prevent accidental data loss.
Modals automatically trap focus within them and restore focus when closed for better accessibility.
Accessibility
- Implements proper ARIA attributes (
role="dialog", aria-modal)
- Traps focus within the modal while open
- Restores focus to trigger element on close
- Supports Escape key to close (configurable)
- Prevents body scroll when modal is open
- Screen reader compatible with proper announcements