A flexible, accessible modal for React with multiple configuration options and sensible defaults. Easy to use for your daily work.
You can use this Modal kit by just import index.mjs from dist/ folder. You can get the raw .tsx file inside src/ directory.
import React, { useState } from "react";
import {Modal} from "dist/index.mjs";
export default function App() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open Modal</button>
<Modal open={open} close={() => setOpen(false)}>
<p>This is the modal content.</p>
</Modal>
</>
);
}| 🔑 Prop | 🧩 Type | 🎯 Default | 📝 Description |
|---|---|---|---|
| open | boolean |
false |
Controls modal visibility. |
| close | () => void |
Required | Function to close the modal. |
| size | "xs"/"sm"/"md"/"lg"/"xl" |
"xs" |
Modal size. |
| header | boolean |
true |
Show header section. |
| footer | boolean |
true |
Show footer section. |
| headerContent | ReactNode |
"Modal Header" |
Custom header text or element. |
| footerContent | ReactNode |
"Modal Footer" |
Custom footer text or element. |
| showCloseButton | boolean |
true |
Show footer close button. |
| closeButtonAlignment | "left"/"center"/"right" |
"right" |
Align footer close button. |
| closeButtonFullWidth | boolean |
false |
Make footer close button full width. |
| fullScreen | boolean |
false |
Make modal full screen. |
| closeOnBackdropClick | boolean |
true |
Close modal when clicking backdrop. |
| closeOnEsc | boolean |
true |
Close modal on Escape key press. |
| portal | HTMLElement |
document.body |
DOM node to render modal via portal. |
| role | "dialog"/"alertdialog" |
"dialog" |
Accessibility role. |
| className | "string" |
"" |
Custom class for modal container. |
| contentClassName | "string" |
"" |
Custom class for modal body. |
| backdropClassName | "string" |
"" |
Custom class for backdrop. |
| modalStyle | "CSSProperties" |
"" |
Inline styles for modal container. |
| contentStyle | "CSSProperties" |
"" |
Inline styles for modal body. |
| backdropStyle | "CSSProperties" |
"" |
Inline styles for modal backdrop. |
| id | "string" |
"" |
Custom id for modal container. |
| contentId | "string" |
"" |
Custom id for modal body. |
| backdropId | "string" |
"" |
Custom id for backdrop. |
-
The modal uses CSS Modules + SCSS internally.✅
-
You can override styles in 3 ways:
- Custom id names:
<Modal open={open} close={() => setOpen(false)} id="my-modal" contentId="modal-body-id" backdropId="backdrop-id" > Custom styled modal </Modal>
- Custom class names:
<Modal open={open} close={() => setOpen(false)} className="my-modal" contentClassName="my-modal-body" backdropClassName="my-backdrop" > Custom styled modal </Modal>
- Inline styles:
<Modal open={open} close={() => setOpen(false)} modalStyle={{ backgroundColor: "#fff" }} contentStyle={{ padding: "2rem" }} backdropStyle={{ backgroundColor: "rgba(0,0,0,0.8)" }} > Inline styled modal </Modal>
- Custom id names:
- ✅
aria-modal="true"for screen readers. - ✅
aria-labelledbyandaria-describedbylink header and content. - ✅ Keyboard support: Press
Escapeto close. - ✅ Locks body scroll when modal is open.
- ✅ Semantic roles:
dialogoralertdialog.
- ✅ Uses React Portal for isolation.
- ✅ Conditional rendering: mounts only when
openis true. - ✅ Minimal re-renders: effects run only on relevant prop changes.
- ✅ Scoped styles via CSS Modules.
- ✅ Keep modal content lightweight for best performance.
- 🔹 Easy to use: Just pass
openandclose. - 🔹 Highly configurable: Sizes, header/footer, close behavior.
- 🔹 Accessible by default: ARIA roles, ESC key support.
- 🔹 Customizable styles: CSS Modules, class and id overrides, inline styles.
- 🔹 Optimized for performance: Portals, conditional rendering.
<Modal open={open} close={() => setOpen(false)} fullScreen>
<p>This modal takes up the entire screen.</p>
</Modal><Modal
open={open}
close={() => setOpen(false)}
closeOnBackdropClick={false}
closeOnEsc={false}
>
<p>Modal won't close on backdrop click or ESC key.</p>
</Modal><Modal
open={open}
close={() => setOpen(false)}
headerContent={<h3>Custom Header</h3>}
footerContent={<span>Custom Footer</span>}
>
<p>Custom content inside modal.</p>
</Modal><Modal
open={open}
close={() => setOpen(false)}
closeButtonAlignment="center"
>
<p>Footer close button is centered.</p>
</Modal>