Skip to main content
The Dialog component displays a modal overlay that focuses user attention on specific content or actions.

Basic Usage

import reflex_ui as ui

ui.dialog(
    trigger=ui.button("Open Dialog"),
    title="Dialog Title",
    description="Dialog description text",
    content="Main content goes here"
)

Props Reference

trigger
Component
Component that opens the dialog when clicked
title
str | Component
Dialog heading
description
str | Component
Descriptive text below the title
content
str | Component
Main dialog content

Controlled State

class State(rx.State):
    dialog_open: bool = False

ui.dialog(
    trigger=ui.button("Open"),
    title="Controlled Dialog",
    content="Content here",
    open=State.dialog_open,
    on_open_change=State.set_dialog_open
)
open
bool | Var[bool]
Whether dialog is open (controlled)
default_open
bool
default:"False"
Initial open state (uncontrolled)
on_open_change
EventHandler[bool]
Event fired when dialog opens or closes
on_open_change_complete
EventHandler[bool]
Event fired after animation completes
modal
bool | Literal['trap-focus']
default:"True"
  • True: Locks scroll, traps focus, disables outside clicks
  • False: Allows interaction with page
  • 'trap-focus': Only traps focus, allows scroll and outside clicks
disable_pointer_dismissal
bool
default:"False"
Prevents closing by clicking outside the dialog

With Custom Content

ui.dialog(
    trigger=ui.button("Confirm Delete", variant="destructive"),
    title="Are you sure?",
    description="This action cannot be undone.",
    content=rx.el.div(
        ui.button("Cancel", variant="ghost"),
        ui.button("Delete", variant="destructive", on_click=handle_delete),
        class_name="flex gap-2 justify-end"
    )
)

Compositional API

For full control:
ui.dialog.root(
    ui.dialog.trigger(
        render_=ui.button("Open")
    ),
    ui.dialog.portal(
        ui.dialog.backdrop(),
        ui.dialog.popup(
            ui.dialog.title("Title"),
            ui.dialog.description("Description"),
            ui.dialog.close(
                render_=ui.button("Close")
            )
        )
    ),
    on_open_change=handle_change
)

Dialog Components

dialog.root

Container for all dialog parts.
ui.dialog.root(
    # child components
    modal=True
)

dialog.trigger

Button that opens the dialog.
ui.dialog.trigger(
    render_=ui.button("Open")
)

dialog.portal

Portals the dialog to document body.
ui.dialog.portal(
    ui.dialog.backdrop(),
    ui.dialog.popup(...),
    keep_mounted=True
)

dialog.backdrop

Semi-transparent overlay behind dialog.
ui.dialog.backdrop()  # Auto-styled

dialog.popup

Main dialog container with content.
ui.dialog.popup(
    ui.dialog.title("Title"),
    "Content",
    initial_focus="#submit-button"
)
initial_focus
str
CSS selector of element to focus when opened
final_focus
str
CSS selector of element to focus when closed

dialog.title

Heading text (h2 element).
ui.dialog.title("Dialog Title")

dialog.description

Description text (p element).
ui.dialog.description("Additional information")

dialog.close

Button to close the dialog.
ui.dialog.close(
    render_=ui.button("Close", variant="ghost")
)

Styling Classes

Access predefined styles via ui.dialog.class_names:
  • BACKDROP: Dark overlay with opacity transitions
  • POPUP: Centered dialog box with shadow and border
  • TITLE: Large semibold heading
  • DESCRIPTION: Secondary text
  • HEADER: Header section with padding
  • CONTENT: Content area with padding
  • TRIGGER: Trigger element (empty by default)
  • CLOSE: Close button (empty by default)

Animation

The dialog includes smooth enter/exit animations:
  • Backdrop fades in/out
  • Popup scales from 90% to 100%
  • 150ms duration for all transitions

Auto-Close Button

The high-level API includes a close button in the top-right corner:
ui.dialog(
    trigger=ui.button("Open"),
    title="Auto Close",
    content="Has X button automatically"
    # Close button with Cancel01Icon auto-added
)

Portal Container

container
str
CSS selector for custom portal container (default: body)
ui.dialog.portal(
    container="#modal-root",
    # content
)

Accessibility

  • Focus trap when modal=True
  • Escape key closes dialog
  • ARIA labels and roles
  • Keyboard navigation support
  • Screen reader announcements

Implementation Details

From source code at reflex_ui/components/base/dialog.py:196:
  • Built on Base UI Dialog primitives
  • High-level wrapper creates complete structure
  • Auto-includes backdrop and portal
  • Close button with icon auto-added in header
  • Positioned at center with negative margin for offset
  • Width capped at 32rem with max-width for mobile

Build docs developers (and LLMs) love