@mshafiqyajid/react-modal
Headless modal hook and styled dialog/drawer for React. Focus trap, scroll lock, Escape to close, four drawer positions, four sizes, smooth enter/exit animations, ARIA-compliant.
Playground #
Props
TSX
import { ModalStyled } from "@mshafiqyajid/react-modal/styled";
import "@mshafiqyajid/react-modal/styles.css";
<ModalStyled
isOpen={open}
onClose={() => setOpen(false)}
title="Example modal"
/>Install #
npm install @mshafiqyajid/react-modal Quick start #
import { ModalStyled } from "@mshafiqyajid/react-modal/styled";
import "@mshafiqyajid/react-modal/styles.css";
const [open, setOpen] = useState(false);
<button onClick={() => setOpen(true)}>Open</button>
<ModalStyled
isOpen={open}
onClose={() => setOpen(false)}
title="Confirm action"
footer={
<>
<button onClick={() => setOpen(false)}>Cancel</button>
<button onClick={() => setOpen(false)}>Confirm</button>
</>
}
>
<p>Are you sure you want to proceed?</p>
</ModalStyled> Drawer variants #
<ModalStyled variant="drawer-right" title="Settings" isOpen={open} onClose={close}>
<p>Drawer content</p>
</ModalStyled>
<ModalStyled variant="drawer-bottom" title="Options" isOpen={open} onClose={close}>
<p>Bottom sheet content</p>
</ModalStyled> Headless #
import { useModal } from "@mshafiqyajid/react-modal";
const { isOpen, open, close, modalProps, overlayProps } = useModal();
<button onClick={open}>Open</button>
{isOpen && (
<div {...overlayProps}>
<div {...modalProps} role="dialog" aria-modal="true">
<button onClick={close}>Close</button>
Content
</div>
</div>
)} API #
| Prop | Type | Default | Description |
|---|---|---|---|
| isOpen | boolean | — | Controls visibility |
| onClose | () => void | — | Called when modal requests close |
| title | ReactNode | — | Header title — omit to hide header entirely |
| footer | ReactNode | — | Footer content — omit to hide footer |
| size | "sm" | "md" | "lg" | "full" | "md" | Dialog width / drawer width |
| variant | "dialog" | "drawer-left" | "drawer-right" | "drawer-bottom" | "dialog" | Layout variant |
| blur | "none" | "sm" | "md" | "lg" | "md" | Backdrop blur intensity |
| padding | "none" | "sm" | "md" | "lg" | "md" | Body padding |
| scrollable | boolean | true | Allow body to scroll when content overflows |
| overlayColor | string | — | Custom backdrop color e.g. "rgba(0,0,0,0.6)" |
| closeOnOverlayClick | boolean | true | Close when clicking the backdrop |
| closeOnEsc | boolean | true | Close on Escape key |
| showCloseButton | boolean | true | Show the × button in the header |