ProPro components are coming soon. Stay tuned!

Modal Component

The Modal component provides a dialog window overlay for displaying content that requires user interaction or attention.

Basic Usage

import { Modal, Button } from 'nebula-ui';
import { useState } from 'react';
 
export default function Example() {
  const [open, setOpen] = useState(false);
  
  return (
    <>
      <Button onClick={() => setOpen(true)}>
        Open Modal
      </Button>
      <Modal 
        isOpen={open} 
        onClose={() => setOpen(false)}
        title="Example Modal"
      >
        <p>Modal content goes here</p>
      </Modal>
    </>
  );
}

With Title

Add a title to the modal header:

<Modal 
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  title="Confirm Action"
>
  <p>Are you sure you want to proceed?</p>
</Modal>

Without Title

You can also create a modal without a title:

<Modal 
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  showCloseButton={true}
>
  <p>Modal content without title</p>
</Modal>

Sizes

Modals come in different sizes:

  • sm: Small modal (max-width: 28rem)
  • md: Medium modal (default, max-width: 32rem)
  • lg: Large modal (max-width: 42rem)
  • xl: Extra large modal (max-width: 56rem)
  • full: Full width modal with margins
<Modal size="sm" title="Small Modal">...</Modal>
<Modal size="md" title="Medium Modal">...</Modal>
<Modal size="lg" title="Large Modal">...</Modal>
<Modal size="xl" title="Extra Large Modal">...</Modal>
<Modal size="full" title="Full Width Modal">...</Modal>

Close Behavior

Control how the modal can be closed:

// Close on overlay click (default: true)
<Modal 
  closeOnOverlayClick={true}
  onClose={handleClose}
>
  ...
</Modal>
 
// Close on ESC key (default: true)
<Modal 
  closeOnEsc={true}
  onClose={handleClose}
>
  ...
</Modal>
 
// Hide close button
<Modal 
  showCloseButton={false}
  onClose={handleClose}
>
  ...
</Modal>

Props

PropTypeDefaultDescription
isOpenboolean-Controls modal visibility
onClose() => void-Callback when modal should close
titlestring-Title displayed in header
size'sm' | 'md' | 'lg' | 'xl' | 'full''md'Size of the modal
showCloseButtonbooleantrueShow close button in header
closeOnOverlayClickbooleantrueAllow closing by clicking overlay
closeOnEscbooleantrueAllow closing with ESC key
childrenReactNode-Modal content

Accessibility

The Modal component is fully accessible:

  • Focus trap: Focus is trapped within the modal
  • Keyboard navigation: ESC key closes the modal
  • ARIA attributes: Proper role="dialog" and aria-modal
  • Body scroll lock: Prevents background scrolling when open
  • Focus management: Returns focus to trigger element on close

Examples

Confirmation Dialog

const [showConfirm, setShowConfirm] = useState(false);
 
<Modal 
  isOpen={showConfirm}
  onClose={() => setShowConfirm(false)}
  title="Delete Item"
  size="sm"
>
  <p className="mb-4">Are you sure you want to delete this item?</p>
  <div className="flex gap-2 justify-end">
    <Button variant="ghost" onClick={() => setShowConfirm(false)}>
      Cancel
    </Button>
    <Button variant="destructive" onClick={handleDelete}>
      Delete
    </Button>
  </div>
</Modal>

Form Modal

<Modal 
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  title="Edit Profile"
  size="lg"
>
  <form className="space-y-4">
    <Input label="Name" placeholder="Enter name" />
    <Input label="Email" type="email" placeholder="Enter email" />
    <div className="flex gap-2 justify-end mt-6">
      <Button variant="ghost" onClick={() => setIsOpen(false)}>
        Cancel
      </Button>
      <Button variant="primary" type="submit">
        Save Changes
      </Button>
    </div>
  </form>
</Modal>

Scrollable Content

The modal automatically handles scrollable content:

<Modal title="Long Content" size="md">
  <div className="space-y-4">
    {/* Long content that will scroll */}
    {Array.from({ length: 20 }).map((_, i) => (
      <p key={i}>Content item {i + 1}</p>
    ))}
  </div>
</Modal>

Best Practices

  1. Use appropriate sizes based on content
  2. Always provide a way to close (close button or cancel action)
  3. Lock body scroll (handled automatically)
  4. Return focus to the trigger element on close (handled automatically)
  5. Use for important actions that require user confirmation
  6. Keep content concise - modals work best for focused interactions

Animation

Modals include smooth animations:

  • Fade in overlay
  • Zoom in modal content
  • Smooth transitions for all state changes

These animations are optimized for performance and provide a polished user experience.

Was this page helpful?

Let us know if this documentation helped you.