A modal is an overlay element which blocks interaction with elements outside it.
import {
Button,
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
} from "@opengovsg/oui"<DialogTrigger>
<Button>Open Modal</Button>
<Modal>
<ModalContent>
{(onClose) => (
<>
<ModalHeader>Modal Title</ModalHeader>
<ModalBody>
<p>Your modal content here</p>
</ModalBody>
<ModalFooter>
<Button onPress={onClose}>Close</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</DialogTrigger>OUI exports 5 modal-related components:
When the modal opens:
Use the size prop to change the size of the modal. You will mainly use the desktop, mobile, and full sizes if following Figma.
However, you can also choose from other preset sizes such as xs, sm, md, lg, xl, 2xl, 3xl, 4xl, or 5xl depending on your use case.
By default, the modal can be closed by clicking on the overlay or pressing the Esc key. You can disable this behavior by setting the following properties:
isDismissable property to false to prevent the modal from closing when clicking on the overlay.isKeyboardDismissDisabled property to true to prevent the modal from closing when pressing the Esc key.By default, the modal is centered on screens larger than sm and is at the bottom of the screen on mobile. This placement is called auto, but you can change it by using the placement prop.
Note: The
top-centerandbottom-centerpositions mean that the modal is positioned at the top/bottom of the screen on mobile, and at the center of the screen on desktop.
You can use the scrollBehavior prop to set the scroll behavior of the modal.
The default value is normal.
The Modal component has an overlay prop to show a backdrop behind the modal. The backdrop can be either transparent, opaque or blur. The default value is blur.
You can customize the backdrop by using the overlay slot in classNames.
You can control the modal's open state using the isOpen and onOpenChange props.
Use the animation prop to control the opening and closing animation of the modal.
You can customize the Modal component by passing custom Tailwind CSS classes to the component slots via the classNames prop.
<Modal
classNames={{
base: "bg-white",
overlay: "bg-black/50",
header: "border-b",
body: "py-6",
footer: "border-t",
}}
>
{/* ... */}
</Modal>| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | The content of the modal |
size | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "desktop" | "mobile" | "full" | "desktop" | The size of the modal |
radius | "none" | "sm" | "md" | "lg" | "sm" | The border radius of the modal |
overlay | "transparent" | "opaque" | "blur" | "blur" | The backdrop style |
animation | "none" | "fade" | "zoom" | "zoom" | The animation style for opening and closing |
scrollBehavior | "normal" | "inside" | "outside" | "normal" | The scroll behavior of the modal |
placement | "auto" | "center" | "top" | "top-center" | "bottom" | "bottom-center" | "auto" | The placement of the modal |
isOpen | boolean | - | Whether the modal is open (controlled) |
defaultOpen | boolean | - | Whether the modal is open by default (uncontrolled) |
isDismissable | boolean | true | Whether clicking the overlay closes the modal |
isKeyboardDismissDisabled | boolean | false | Whether pressing Esc closes the modal |
classNames | SlotsToClasses<ModalSlots> | - | Custom CSS classes for component slots |
| Prop | Type | Description |
|---|---|---|
onOpenChange | (isOpen: boolean) => void | Callback when the open state changes |
Use props returned by the useDraggable hook to make the modal draggable.
The
zoomanimation may interfere with the dragging experience (the modal will snap back to the original position on close).It is recommended to set the
animationprop tofadeornonewhen using a draggable modal.
Setting useDraggable#overflow prop to true allows users to drag the modal to a position where it overflows the viewport.
You can use the useMediaQuery hook from usehooks-ts (or other similar libraries) to create a responsive modal that changes its size and placement based on the screen size.