Skip to Content

Modal

Display modal dialogs for important interactions that require user attention.

Build with an agent

Copy component guidance grounded in this release of Citrionus.

Loading component guidance…

Import

import { Modal } from "@raydenui/ui";

Usage

Basic

Preview
const [open, setOpen] = useState(false); <Button onClick={() => setOpen(true)}>Open Modal</Button> <Modal open={open} onClose={() => setOpen(false)} title="Confirm Action" description="Are you sure you want to proceed?" primaryLabel="Confirm" onPrimaryClick={() => { // handle confirm setOpen(false); }} secondaryLabel="Cancel" />

Sizes

Preview
<Modal size="sm" title="Small Modal" open={open} onClose={onClose}> Small modal content (400px width) </Modal> <Modal size="md" title="Medium Modal" open={open} onClose={onClose}> Medium modal content (500px width) </Modal> <Modal size="lg" title="Large Modal" open={open} onClose={onClose}> Large modal content (640px width) </Modal>

With Custom Content

<Modal open={open} onClose={() => setOpen(false)} title="Edit Profile" primaryLabel="Save Changes" secondaryLabel="Cancel" > <div className="space-y-4"> <Input label="Name" placeholder="Enter your name" /> <Input label="Email" placeholder="Enter your email" /> </div> </Modal>
<Modal open={open} onClose={() => setOpen(false)} title="Delete Item" description="This action cannot be undone." footerOrientation="vertical" primaryLabel="Delete" secondaryLabel="Keep Item" />

Primary Only

<Modal open={open} onClose={() => setOpen(false)} title="Welcome!" description="Thanks for signing up." primaryLabel="Get Started" onPrimaryClick={() => setOpen(false)} />

Prevent Close on Overlay

<Modal open={open} onClose={() => setOpen(false)} title="Important Form" closeOnOverlay={false} closeOnEscape={false} showClose={false} > User must complete this form to close. </Modal>

Props

PropTypeDefaultDescription
openboolean—Whether the modal is open (required)
onClose() => void—Called when modal should close (required)
size"sm" | "md" | "lg""sm"Modal width: sm (400px), md (500px), lg (640px)
titlestring—Title text
descriptionstring—Description text below the title
iconReactNode—Leading icon element
showClosebooleantrueShow close button in header
primaryLabelstring"Save"Primary action button label
onPrimaryClick() => void—Primary button callback
secondaryLabelstring—Secondary action button label
onSecondaryClick() => void—Secondary button callback
footerOrientation"horizontal" | "vertical""horizontal"Footer button layout
closeOnOverlaybooleantrueClose on backdrop click
closeOnEscapebooleantrueClose on Escape key
blurbooleantrueShow backdrop blur effect
childrenReactNode—Modal body content
classNamestring—Additional CSS classes

Features

  • Portal rendering: Modal renders to document.body for proper stacking
  • Body scroll lock: Prevents background scrolling when open
  • Keyboard support: Escape key closes modal (configurable)
  • Overlay click: Click outside to close (configurable)
  • Focus management: Proper focus trapping within modal
  • Dark mode support: Automatic dark mode styling

Accessibility

  • Uses a native <dialog> opened with showModal()
  • Title linked via aria-labelledby
  • Description linked via aria-describedby
  • Close button has aria-label="Close modal"
  • The browser contains focus and makes the background inert while the dialog is open
  • Closing returns focus to the trigger when it is still available
Last updated on