Skip to main content

Overview

The Modal component displays content in a dialog overlay, perfect for forms, confirmations, and detailed content that requires user focus.

Basic Usage

import { NSModal } from '@newtonschool/grauity';
import { useState } from 'react';

function MyComponent() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
      
      <Modal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        hideOnClickAway={true}
        title="Modal Title"
        description="This is a modal description"
      >
        <p>Modal content goes here</p>
      </NSModal>
    </>
  );
}

Props

isOpen
boolean
required
Controls whether the modal is visible.
onClose
function
Callback function when the modal should be closed.
banner
React.ReactNode
Banner content displayed at the top of the modal.
title
React.ReactNode
Title content for the modal.
description
string
Description text for the modal.
body
React.ReactNode
[DEPRECATED] Use children instead. Body content for the modal.
children
React.ReactNode
Main content for the modal. If body prop is provided, children will be rendered after it.
action
React.ReactNode
Action content (typically buttons) displayed at the bottom.
hideOnClickAway
boolean
required
Whether clicking outside the modal closes it.
blurBackground
boolean
default:false
Apply a blur effect to the background.
showCloseButton
boolean
default:false
Display a close button in the modal header.
width
string
default:"500px"
Width of the modal.
height
string
default:"auto"
Height of the modal.
minWidth
string
Minimum width constraint.
minHeight
string
Minimum height constraint.
maxWidth
string
default:"95vw"
Maximum width constraint.
maxHeight
string
default:"95vh"
Maximum height constraint.
modalPadding
string
default:"20px"
Padding inside the modal.
modalBodyMargin
string
Margin for the modal body section.
mobileBottomFullWidth
boolean
default:false
Make the modal full width at the bottom on mobile devices.
animatePresence
ModalAnimationType
default:"fade"
Animation type for opening/closing.Available choices: false, slide, slide-reverse, fade, emanate
clickEvent
any
Click event object for use with emanate animation.
shouldFocusOnFirstElement
boolean
default:true
Automatically focus the first focusable element.
shouldDisableScroll
boolean
default:true
Disable background scrolling when modal is open.
overflow
string
default:"auto"
Overflow behavior for the modal content.
border
string
Custom border style. Default is 1px solid var(--border-subtle-primary-default, #e1e5ea).
className
string
Additional CSS class name.

With Actions

<Modal
  isOpen={isOpen}
  onClose={onClose}
  hideOnClickAway={true}
  title="Confirm Action"
  description="Are you sure you want to proceed?"
  action={
    <>
      <Button variant="primary" onClick={handleConfirm}>
        Confirm
      </Button>
      <Button variant="tertiary" onClick={onClose}>
        Cancel
      </Button>
    </>
  }
/>

With Banner

<Modal
  isOpen={isOpen}
  onClose={onClose}
  hideOnClickAway={true}
  banner={
    <div style={{ padding: '20px', backgroundColor: '#f0f0f0' }}>
      Banner Content
    </div>
  }
  title="Modal with Banner"
>
  <p>Modal content</p>
</NSModal>

Custom Size

<Modal
  isOpen={isOpen}
  onClose={onClose}
  hideOnClickAway={true}
  width="800px"
  height="600px"
  title="Large Modal"
>
  <p>Content for a larger modal</p>
</NSModal>

Animation Types

// Fade (default)
<NSModal animatePresence="fade" />

// Slide from bottom
<NSModal animatePresence="slide" />

// Slide from top
<NSModal animatePresence="slide-reverse" />

// Emanate from click point
<NSModal 
  animatePresence="emanate" 
  clickEvent={clickEvent}
/>

// No animation
<NSModal animatePresence={false} />

Confirmation Dialog

For simple confirmation dialogs, use the ConfirmationDialog component:
import { ConfirmationDialog } from '@newtonschool/grauity';

<ConfirmationDialog
  isOpen={isOpen}
  title="Delete Item"
  description="Are you sure you want to delete this item?"
  confirmText="Delete"
  cancelText="Cancel"
  onConfirm={handleDelete}
  onCancel={() => setIsOpen(false)}
  confirmButtonVariant="primary"
  confirmButtonColor="error"
/>

Multi-Step Modal

import { MultiStepModal } from '@newtonschool/grauity';

<MultiStepModal
  isOpen={isOpen}
  onClose={onClose}
  modalSteps={[
    {
      title: 'Step 1',
      description: 'First step description',
      body: <div>Step 1 content</div>,
    },
    {
      title: 'Step 2',
      description: 'Second step description',
      body: <div>Step 2 content</div>,
    },
  ]}
  showModalStepsPagination={true}
  hideOnClickAway={false}
  onFinalStep={() => console.log('Completed')}
/>

Build docs developers (and LLMs) love