Components/Modal

UI component

Modal

Ink-bordered overlay dialog. Slams in from slightly below on open. Lime header bar, scrollable body, optional footer. Esc key + scrim click to close. Focus trap on open. 3 sizes.

OverlayFocus trapsm / md / lgEsc to closeSlam-in animation
components/ui/Modal.jsx
Live demos — click to open
3 sizes · click scrim or Esc to close
Anatomy
Header · body · footer — static reference
Publish campaign

Your campaign SLAB Studio will go live immediately and start collecting impressions.

You can pause it at any time from the dashboard.

title prop
Lime header bar
children
Scrollable body
footer prop
Paper-2 action bar
Do / Don't
✓ Do

Always provide a clear primary action in the footer and a way to cancel. The modal should confirm a single, focused task.

✕ Don't

Don't nest modals or put navigation inside a modal. Don't use modals for non-blocking information — use Toast or Callout instead.

Props
PropTypeDefaultDescription
openbooleanfalseControlled open state. Modal unmounts when false.
onClose() => voidCalled when Esc is pressed or scrim is clicked.
titlestring | ReactNodenullRendered in lime header bar with close ×. Omit for no header.
footerReactNodenullRendered in paper-2 footer bar. Typically action buttons.
size"sm" | "md" | "lg""md"Max-width: sm=480px, md=600px, lg=800px.
childrenReactNodeModal body — scrollable, max-height 60vh.
Usage
import { Modal } from "components/ui/Modal";

const [open, setOpen] = useState(false);

<Modal
  open={open}
  onClose={() => setOpen(false)}
  title="Publish campaign"
  size="sm"
  footer={
    <>
      <Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
      <Button variant="accent" onClick={publish}>Publish now</Button>
    </>
  }
>
  Are you sure you want to publish this campaign?
</Modal>