How to Use

Modal

Modal displays content in a focused dialog overlay that requires user attention before they can continue interacting with the page. It is typically paired with Backdrop for the overlay effect. Use Modal for confirmations ("Are you sure?"), focused forms (edit dialogs), detail views, or any content that requires full user attention. Modals trap focus inside them and close on Escape or backdrop click.

import {Modal} from "oks-ui"

Confirmation Dialog

The most common modal pattern: a confirmation dialog with a title, message, Cancel and Confirm buttons. Use isOpen/onClose state to control visibility. Render both Backdrop and the modal panel conditionally. The Backdrop sits at z-40 and the modal at z-50. The modal should be centered vertically and horizontally using flexbox. Use max-w-sm for small confirmations, max-w-lg for forms, max-w-2xl for detailed content.

function ConfirmDialog() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div className="space-y-4">
      <Button onClick={() => setIsOpen(true)} color="danger">
        Delete Account
      </Button>
      {isOpen && (
        <>
          <Backdrop isOpen={isOpen} onClose={() => setIsOpen(false)} />
          <div className="fixed inset-0 z-50 flex items-center justify-center">
            <div
              className="mx-4 w-full max-w-sm rounded-xl border p-6 shadow-2xl"
              style={{
                backgroundColor: "var(--color-surface)",
                borderColor: "var(--color-border)",
              }}
            >
              <h2 className="text-lg font-semibold">Confirm Delete</h2>
              <p className="mt-2 text-sm">
                Are you sure you want to delete your account?
                This action cannot be undone.
              </p>
              <div className="mt-6 flex justify-end gap-3">
                <Button variant="soft" onClick={() => setIsOpen(false)}>
                  Cancel
                </Button>
                <Button color="danger"
                  onClick={() => { alert("Deleted"); setIsOpen(false); }}>
                  Delete
                </Button>
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

Focus Management

When a modal opens, focus should move to the first interactive element (usually the Cancel button or the first input). When the modal closes, focus should return to the element that triggered it (the button that set isOpen to true). This is critical for keyboard users and screen readers. The Backdrop handles click-outside-to-close; clicking outside the modal panel triggers onClose. The Escape key also triggers onClose. You can choose to disable backdrop dismiss for forms with unsaved data by not passing onClose to the Backdrop (or by adding a confirmation step).

Accessibility

Modal uses role="dialog" and aria-modal="true" for screen reader announcement. Focus is trapped inside the modal when open — Tab cycles through focusable elements within the panel. Escape closes the modal. The first focusable element receives focus on open. The element that triggered the modal retains a reference so focus can be restored on close. The backdrop has aria-hidden="true". Use aria-labelledby pointing to the modal title and aria-describedby pointing to the description for complete screen reader context. The modal respects prefers-reduced-motion by disabling entrance animations.

Props Reference

All available props for Modal. See the full API reference page for interactive playground examples.

PropTypeDefaultDescription
isOpenbooleanControls visibility (required).
onClose() => voidCalled when modal is dismissed (required).
titleReactNodeModal title rendered in the header.
childrenReactNodeModal body content.
actionsReactNodeFooter action buttons.
size"sm" | "md" | "lg""md"Modal size.
dismissiblebooleantrueShow close button.
closeOnOutsideClickbooleantrueClose on backdrop click.
closeOnEscapebooleantrueClose on Escape key.
blurboolean | 'sm' | 'md' | 'lg' | numberfalseBackdrop blur intensity.
portalbooleantrueRender in portal.

Best Practices

  • Always pair Modal with Backdrop for the overlay — Backdrop provides the darkened background and click-outside-to-close behavior
  • Trap focus inside the modal while it's open — use focus management to prevent users from tabbing to elements behind the modal
  • Use max-w-sm for small confirmation dialogs, max-w-lg for forms, max-w-2xl for detail views or multi-column content
  • Always provide a way to close: Cancel button, X button in the header, Escape key on the keyboard, and clicking the backdrop
  • Restore focus to the trigger element when the modal closes — this is essential for keyboard and screen reader users
  • For forms inside modals, consider disabling backdrop click-to-close when the form has unsaved changes to prevent data loss
  • Avoid stacking modals on top of other modals — if you need to show a secondary dialog, replace the current modal content or use a separate pattern