Skip to main content

Modal

The Modal component provides a simple imperative API to display dialog windows. Use Modal.show() to create modals programmatically.

Modal.show()

The primary method for displaying modals. It accepts content and modalOptions, and returns a controller for managing the modal.

Modal.show(content, modalOptions);
// or
Modal.show(modalOptions);

Basic Usage

The simplest way to show a modal is to pass a string or ReactNode as content and an optional options object with a title.

import { Button, Modal } from 'react-dialogues';

<Button
onClick={() => {
Modal.show('Hello! This is a basic modal …', {
title: 'Basic Modal',
});
}}
>
Show Basic Modal
</Button>;

Rich Content

You can pass JSX elements as content for more complex layouts. Use the content property in the options object.

import { Button, Modal } from 'react-dialogues';

<Button
onClick={() => {
Modal.show({
title: 'Rich Content',
content: (
<div>
<p>
This modal contains
<strong>rich JSX content </strong>.
</p>
<ul>
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>
</div>
),
});
}}
>
Show Rich Content Modal
</Button>;

Notification Types

Shorthand methods for showing modals with predefined notification styles. Each method automatically applies the corresponding icon and styling. Under the hood, they just call Modal.show() with the type property set.

Use these methods for quick feedback messages with appropriate visual styling.

Available methods:

  • Modal.info()
  • Modal.success()
  • Modal.warning()
  • Modal.error()
import { Button, Footer, Modal } from 'react-dialogues';

<Footer align="left">
<Button
onClick={() => {
Modal.info({ title: 'Info', content: '…' });
}}
>
Info
</Button>
<Button
color="success"
onClick={() => {
Modal.success({ title: 'Success', content: '…' });
}}
>
Success
</Button>
<Button
color="warning"
onClick={() => {
Modal.warning({ title: 'Warning', content: '…' });
}}
>
Warning
</Button>
<Button
color="error"
onClick={() => {
Modal.error({ title: 'Error', content: '…' });
}}
>
Error
</Button>
</Footer>

Custom Buttons

Customize modal buttons using the buttons array. You can use the built-in OkButton and CancelButton components or create your own.

Button options:

  • String values: 'OK', 'Cancel'
  • Components: <OkButton />, <CancelButton />
  • Custom JSX elements

You can find more details about button customization in the Button documentation.

import { Button, Modal } from 'react-dialogues';

<Button
onClick={() => {
Modal.show({
title: 'Confirm Action',
content: 'Are you sure …',
buttons: [
'Cancel',
{ content: 'OK', color: 'success' },
<Button>Help</Button>,
],
});
}}
>
Show Confirm Modal
</Button>;

Size Options

Control the modal width with the size property.

Available sizes:

  • 'normal' - Default size (default)
  • 'large' - Wider modal for more content
  • 'full' - Full-screen modal
import { Button, Modal, Footer } from 'react-dialogues';

const content = (
<div>
<p>This modal demonstrates different size options.</p>
<p>Lorem ipsum …</p>
</div>
);

<Footer align="left">
<Button
onClick={() => {
Modal.show({ title: 'Normal', content });
}}
>
Normal
</Button>
<Button
onClick={() => {
Modal.show({ title: 'Large', content, size: 'large' });
}}
>
Large
</Button>
<Button
onClick={() => {
Modal.show({ title: 'Full', content, size: 'full' });
}}
>
Full
</Button>
</Footer>;

Centered Position

By default, modals appear near the top of the screen. Use centered: true to vertically center the modal.

Options:

  • centered - Boolean, centers modal vertically when true
import { Button, Modal, Footer } from 'react-dialogues';

const content = 'This modal is vertically centered.';

<Footer align="left">
<Button
onClick={() => {
Modal.show({ title: 'Default', content });
}}
>
Default
</Button>
<Button
onClick={() => {
Modal.show({
title: 'Centered Modal',
content,
centered: true,
});
}}
>
Centered
</Button>
</Footer>;

Async/Promise Handling

Modal.show() returns a controller that is also a Promise. Use await to get the user's action when the modal closes.

Return value:

  • [action, result] - Tuple with the action name and result value
  • action is typically 'ok', 'cancel', or 'close'
import { Button, Modal, Toast } from 'react-dialogues';

async function handleClick() {
const [action] = await Modal.show({
title: 'Async Example',
content: 'Click OK or Cancel to see the result.',
buttons: ['Cancel', 'OK'],
});

Toast.show(`You clicked: ${action}`, {
type: action === 'ok' ? 'success' : 'info',
});
}

<Button onClick={handleClick}>Show Async Modal</Button>;

Modal.prompt()

Shows a modal with a text input field. Returns the entered value when the user clicks OK.

Props:

  • label - Label text above the input field
  • placeholder - Placeholder text in the input
  • value - Initial value for the input
import { Button, Modal, Toast } from 'react-dialogues';

async function handleClick() {
const [action, value] = await Modal.prompt({
title: 'Enter your name',
label: 'Name',
placeholder: 'John Doe',
});

if (action === 'ok') {
Toast.info(`User entered: ${value}`);
}
}

<Button onClick={handleClick}>Show Prompt</Button>;

Modal.showCustom()

Displays a modal with a completely custom component. Use this when you need full control over the modal's content and behavior. Under the hood, it's just a shortcut for Modal.show({ component: YourComponent }).

Key points:

  • Your component receives all standard modal props
  • Use useRdController() to access the controller
  • Call controller.setResult() to set the return value
import { Button, Modal, Toast, useRdController } from 'react-dialogues';
import { type ChangeEvent, useEffect, useState } from 'react';

function ColorPicker() {
const controller = useRdController();
const [color, setColor] = useState('#3b82f6');

useEffect(() => {
controller.setResult(color);
}, []);

function handleChange(e: ChangeEvent<HTMLInputElement>) {
setColor(e.target.value);
controller.setResult(e.target.value);
}

return (
<Modal title="Pick a Color" buttons={['Cancel', 'OK']}>
<input type="color" value={color} onChange={handleChange} />
<span> {color}</span>
</Modal>
);
}

async function handleClick() {
const [action, color] = await Modal.showCustom(ColorPicker);
if (action === 'ok') {
Toast.info(`Selected color: ${color}`);
}
}

<Button onClick={handleClick}>Pick Color</Button>;

Modal.destroyAll()

Modal.destroyAll(action?, result?)

Closes all open modals programmatically.

import { Modal } from 'react-dialogues';

// Close all modals
Modal.destroyAll();

// Close all with custom action name
Modal.destroyAll('bulkClose');

Modal.defaults

A static object containing the default values for modal options. You can modify these to change the defaults for all modals in your application.

import { Modal } from 'react-dialogues';

// Modify defaults globally
Modal.defaults.centered = true;
Modal.defaults.size = 'large';
Modal.defaults.maskClosable = false;

// All future modals will use these new defaults
Modal.show({ title: 'Now Centered', content: '…' });

API Reference

PropertyTypeDefaultDescription
buttonsDialogButton[]['OK']Array of buttons
centeredbooleanfalseCenter modal vertically
classNamestring-CSS class for modal
closeOthersbooleanfalseClose other modals when opening
contentReactNode-Modal body content
maskbooleantrueShow background overlay
maskClosablebooleantrueClick overlay to close
onClose(result) => void-Called when modal closes
size'normal' | 'large' | 'full''normal'Modal width
titleReactNode-Modal header title

Inherited from DialogProps

These properties are inherited from the base Dialog component:

PropertyTypeDefaultDescription
actionMode'okClose' | 'simplified' | 'full''simplified' when more the 2 buttons, or 'okClose'Controls how button actions resolve the promise
bodyReactNode-Direct body content (bypasses content wrapper)
classNamesPartial<Record<ModalSlots, string>>-CSS classes for internal slots
closeReactNode-Custom close button element
componentComponentType-Custom component to render instead of Dialog
emptybooleanfalseRender only content without header/footer
firstChildReactNode-Content inserted before all other elements
footerReactNode-Custom footer element (overrides buttons)
headerReactNode-Custom header element (overrides title)
iconReactNode-Custom icon element
lastChildReactNode-Content inserted after all other elements
type'success' | 'info' | 'warning' | 'error'-Notification type styling

Also, you can pass any other properties of HTMLDivElement that are applied to the modal's root element.

ModalSlots

The classNames prop accepts an object mapping slot names to CSS class strings. ModalSlots extends DialogSlots with modal-specific slots.

DialogSlots (inherited):

SlotDescription
bodyThe main content area
footerThe button container at the bottom
headerThe title area at the top
iconThe notification icon element
iconWrapThe container wrapping the icon element

ModalSlots (additional):

SlotDescription
maskThe overlay backdrop behind the modal
wrapThe wrapper element containing the dialog

Usage:

import { Modal } from 'react-dialogues';

Modal.show({
title: 'Styled Modal',
content: 'Custom styled content',
classNames: {
header: 'my-header-class',
body: 'my-body-class',
footer: 'my-footer-class',
mask: 'my-mask-class',
wrap: 'my-wrap-class',
},
});

Return Value

Modal.show() returns an RdController that implements Promise<[action, result]>:

const controller = Modal.show({ title: 'Example', content: 'Hello' });

// Promise methods
const [action, result] = await controller;

// Controller methods
controller.update({ title: 'Updated Title' }); // Update modal props
controller.destroy('cancel'); // Close modal programmatically