Modal
A dialog surface with a title, a close button, your content and a footer of buttons. Use it as the overlay of ui.layer or ui.dialog_layer. The ready-made dialogs are built on it.
ui.modal · Category: Overlays · Full reference →


ui.modal( ui.muted("notes.py has unsaved changes. Save them before closing?"), title="Save changes?", on_close=on_close, footer=[ui.button("Don't save", on_discard, variant="ghost"), ui.button("Cancel", on_close), ui.button("Save", on_save, variant="solid")], width=440,)When to use
Section titled “When to use”- For dialogs with your own content: a form, settings, an About box.
from pyzed import ui
ui.modal( ui.muted("notes.py has unsaved changes. Save them before closing?"), title="Save changes?", on_close=on_close, footer=[ui.button("Don't save", on_discard, variant="ghost"), ui.button("Cancel", on_close), ui.button("Save", on_save, variant="solid")], width=440,)Variants
Section titled “Variants”Content
Section titled “Content”

Code
ui.modal(ui.muted("Your trial ends in 3 days."), width=320)

title=, on_close=Code
ui.modal(ui.muted("Your trial ends in 3 days."), title="Trial", on_close=on_close, width=320)

footer=Code
ui.modal(ui.muted("Discard the draft?"), title="Draft", on_close=on_close, width=320, footer=[ui.button("Cancel", on_close), ui.button("Discard", on_discard, variant="error")])States and events
Section titled “States and events”max_height= scrolls long content, and Escape sends on_close while the dialog has focus.


description=, icon=, width="sm"Code
ui.modal(ui.input("notes.md", on_input), title="Rename", description="Choose a new name", icon="pencil", on_close=on_close, width="sm", footer=[ui.button("Rename", on_press, variant="solid")])Examples
Section titled “Examples”Over the app
Section titled “Over the app”Wrap the view with ui.dialog_layer to center it over a dimmed backdrop.


ui.dialog_layer(main_view(), ui.modal( pz.column([ui.input("", on_input, placeholder="Project name"), ui.checkbox(True, on_toggle, label="Create a git repository")], spacing=10), title="New project", on_close=on_close, footer=[ui.button("Cancel", on_close), ui.button("Create", on_create, variant="solid")], width=380,), on_dismiss=on_close)Events
Section titled “Events”Modal has 1 event of its own, listed below. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.
| Event | Handler gets | When |
|---|---|---|
on_close |
() |
The close button; also sent by Escape while the dialog has focus. |
Handler gets is what Pyzed passes to your callable: () means nothing. Any handler can also be a message (a value that is not callable), which goes to update().
Handling the events
Section titled “Handling the events”The same events written three ways. Imperative: methods of the app change self. Declarative: the handlers produce messages and one update() decides. Functional: a pure function draws an immutable state and asks for changes with set_state(...). See Imperative, declarative and functional.
class Notes(pz.App): def __init__(self): self.asking = True
def save(self): self.asking = False
def view(self): dialog = ui.modal(ui.muted("Save your changes before closing?"), title="Save changes?", on_close=lambda: setattr(self, "asking", False), # ✕ and Escape footer=[ui.button("Save", self.save, variant="solid")], width=420) return ui.dialog_layer(main_view(), dialog if self.asking else None)class Notes(pz.App): asking = True
def update(self, message): if message in ("save", "close"): self.asking = False
def view(self): dialog = ui.modal(ui.muted("Save your changes?"), title="Save changes?", on_close="close", footer=[ui.button("Save", "save", variant="solid")]) return ui.dialog_layer(main_view(), dialog if self.asking else None)from dataclasses import dataclass
@dataclass(frozen=True)class State: asking: bool = True
def view(state, set_state): close = lambda: set_state(asking=False) dialog = ui.modal(ui.muted("Save your changes?"), title="Save changes?", on_close=close, footer=[ui.button("Save", close, variant="solid")]) return ui.dialog_layer(main_view(), dialog if state.asking else None)Properties and API
Section titled “Properties and API”ui.modal
Section titled “ui.modal”modal( content, *, title=None, on_close=None, width=480, footer=(), description=None, icon=None, max_height=None, theme=None,)A dialog. Use it as the overlay of ui.layer.
| Property | Default | Description |
|---|---|---|
content |
required | Content: a Widget, a string or a number (converted to text). |
title |
None |
Title. |
width |
480 |
Pixels or "sm" (360), "md" (480), "lg" (640) or "xl" (820). |
footer |
() |
Footer buttons, aligned to the right. |
description |
None |
Muted line under the title. |
icon |
None |
Icon before the title. |
max_height |
None |
Scrolls content taller than this, keeping the header and footer in view. |
theme |
None |
Theme to use instead of the current one (pyzed.theme.current()). |
Events: on_close (events).