AlertDialog
AlertDialog is a modal dialog component that interrupts the user with important content and expects a response. It is built on top of the Dialog component with opinionated defaults and a simplified API.
Differences from Dialog
AlertDialog provides these defaults on top of Dialog:
- Not overlay closable by default (can be changed with
overlay_closable(true)) - No close button by default (can be changed with
close_button(true)) - Footer buttons are center-aligned (Dialog uses right-alignment)
- Simplified API focused on alert and confirmation scenarios
Import
use gpui_kit::component::dialog::{AlertDialog, DialogAction, DialogClose};
use gpui_kit::component::WindowExt;Usage
Setup Application Root View
Like Dialog, you need to set up your application's root view to render the dialog layer. See Dialog documentation for details.
Basic AlertDialog (Declarative API)
Create a fully declarative AlertDialog using trigger and content:
use gpui_kit::component::dialog::{AlertDialog, DialogHeader, DialogTitle, DialogDescription, DialogFooter};
AlertDialog::new(cx)
.trigger(
Button::new("show-alert")
.outline()
.label("Show Alert")
)
.content(|content, _, cx| {
content
.child(
DialogHeader::new()
.child(DialogTitle::new().child("Are you absolutely sure?"))
.child(DialogDescription::new().child(
"This action cannot be undone. \
This will permanently delete your account from our servers."
))
)
.child(
DialogFooter::new()
.child(
Button::new("cancel")
.outline()
.label("Cancel")
.on_click(|_, window, cx| {
window.close_dialog(cx);
})
)
.child(
Button::new("ok")
.primary()
.label("Continue")
.on_click(|_, window, cx| {
window.push_notification("Confirmed", cx);
window.close_dialog(cx);
})
)
)
})Using DialogAction and DialogClose
DialogAction and DialogClose are wrapper components that simplify button click handling by automatically triggering the appropriate actions:
- DialogClose: Wraps a button to trigger the
Cancelaction, invokingon_cancelcallback - DialogAction: Wraps a button to trigger the
Confirmaction, invokingon_okcallback
These components eliminate the need to manually call window.close_dialog(cx):
AlertDialog::new(cx)
.trigger(Button::new("show-alert").outline().label("Show Alert"))
.on_ok(|_, window, cx| {
window.push_notification("You confirmed!", cx);
true // Return true to close dialog
})
.on_cancel(|_, window, cx| {
window.push_notification("You cancelled!", cx);
true
})
.content(|content, _, cx| {
content
.child(
DialogHeader::new()
.child(DialogTitle::new().child("Confirm Action"))
.child(DialogDescription::new().child("Do you want to proceed?"))
)
.child(
DialogFooter::new()
.child(
DialogClose::new().child(
Button::new("cancel").outline().label("Cancel")
)
)
.child(
DialogAction::new().child(
Button::new("ok").primary().label("Confirm")
)
)
)
})Benefits:
- No need to manually close the dialog
- Automatically connects to
on_okandon_cancelcallbacks - Cleaner, more declarative code
- Supports returning
falsefrom callbacks to prevent closing
Basic AlertDialog (Imperative API)
Open a dialog imperatively using WindowExt::open_alert_dialog:
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Delete File")
.description("Are you sure you want to delete this file? This action cannot be undone.")
.show_cancel(true)
.on_ok(|_, window, cx| {
window.push_notification("File deleted", cx);
true // Return true to close dialog
})
})Custom Buttons
Set the button text and variant directly on the dialog:
use gpui_kit::component::button::ButtonVariant;
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Delete Account")
.description("This will permanently delete your account and all associated data.")
.confirm()
.ok_text("Delete")
.ok_variant(ButtonVariant::Danger)
.cancel_text("Keep")
.on_ok(|_, window, cx| {
window.push_notification("Account deleted", cx);
true
})
})button_props takes the same properties as one value, for a configuration you
want to build up or pass around. It overrides only the fields the value sets,
so everything the dialog already carries — the Cancel button confirm asked
for, a callback an earlier on_ok installed — survives, whatever the call
order:
use gpui_kit::component::dialog::DialogButtonProps;
window.open_alert_dialog(cx, move |alert, _, _| {
alert
.title("Delete Account")
.confirm()
.button_props(
DialogButtonProps::default()
.ok_text("Delete")
.ok_variant(ButtonVariant::Danger)
)
})AlertDialog with Icon
Using icon in declarative API:
use gpui_kit::component::{Icon, IconName, ActiveTheme};
AlertDialog::new(cx)
.w(px(320.))
.trigger(Button::new("permission").outline().label("Request Permission"))
.on_ok(|_, window, cx| {
window.push_notification("Permission granted", cx);
true
})
.content(|content, _, cx| {
content
.child(
DialogHeader::new()
.items_center()
.child(
Icon::new(IconName::TriangleAlert)
.size_10()
.text_color(cx.theme().warning)
)
.child(DialogTitle::new().child("Network Permission Required"))
.child(DialogDescription::new().child(
"We need your permission to access the network to provide better services."
))
)
.child(
DialogFooter::new()
.v_flex()
.child(
DialogAction::new().child(
Button::new("allow").w_full().primary().label("Allow")
)
)
.child(
DialogClose::new().child(
Button::new("deny").w_full().outline().label("Don't Allow")
)
)
)
})Using icon in imperative API:
window.open_alert_dialog(cx, |alert, _, cx| {
alert
.title("Warning")
.description("This action requires confirmation.")
.icon(
Icon::new(IconName::AlertTriangle)
.size_8()
.text_color(cx.theme().warning)
)
})Destructive Action Confirmation
AlertDialog::new(cx)
.trigger(
Button::new("delete-account")
.outline()
.danger()
.label("Delete Account")
)
.on_ok(|_, window, cx| {
window.push_notification("Account deletion initiated", cx);
true
})
.content(|content, _, _| {
content
.child(
DialogHeader::new()
.child(DialogTitle::new().child("Delete Account"))
.child(DialogDescription::new().child(
"This will permanently delete your account \
and all associated data. This action cannot be undone."
))
)
.child(
DialogFooter::new()
.child(
DialogClose::new().child(
Button::new("cancel").flex_1().outline().label("Cancel")
)
)
.child(
DialogAction::new().child(
Button::new("delete")
.flex_1()
.outline()
.danger()
.label("Delete Forever")
)
)
)
})Custom Width
AlertDialog::new(cx)
.width(px(500.))
.trigger(Button::new("custom-width").label("Custom Width"))
.content(|content, _, _| {
// ... dialog content
})Controlling Dialog Close Behavior
Allow Overlay Click to Close
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Notice")
.description("Click outside this dialog or press ESC to close it.")
.overlay_closable(true)
})Disable Keyboard ESC to Close
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Important Notice")
.description("Please read this carefully before proceeding.")
.keyboard(false)
})Show Close Button
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Information")
.description("Some information...")
.close_button(true)
})Prevent Dialog from Closing
Return false from on_ok or on_cancel callbacks to prevent the dialog from closing:
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Processing")
.description("A process is running. Click Continue to stop it or Cancel to keep waiting.")
.confirm()
.ok_text("Continue")
.on_ok(|_, window, cx| {
// Return false to prevent closing
window.push_notification("Cannot close: Process still running", cx);
false
})
.on_cancel(|_, window, cx| {
window.push_notification("Waiting...", cx);
false
})
})Dialog Close Callback
Use on_close to execute actions after the dialog closes (called after on_ok or on_cancel):
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Confirm")
.description("Are you sure?")
.on_close(|_, window, cx| {
window.push_notification("Dialog closed", cx);
})
})API Reference
AlertDialog
| Method | Description |
|---|---|
new(cx) |
Create a new AlertDialog |
trigger(element) |
Set trigger element that opens the dialog when clicked |
content(builder) |
Set dialog content using a builder function (declarative API) |
title(title) |
Set dialog title (imperative API) |
description(desc) |
Set dialog description (imperative API) |
icon(icon) |
Set dialog icon (imperative API) |
confirm() |
Show OK and Cancel buttons |
ok_text(text) |
Set OK button text, default "OK" |
ok_variant(variant) |
Set OK button variant, default Primary |
cancel_text(text) |
Set cancel button text, default "Cancel" |
cancel_variant(variant) |
Set cancel button variant |
button_props(props) |
Override the button properties the value sets, keep the rest |
show_cancel(bool) |
Show/hide cancel button, default false |
width(px) |
Set dialog width, default 420px |
overlay_closable(bool) |
Allow clicking overlay to close, default false |
close_button(bool) |
Show/hide close button, default false |
keyboard(bool) |
Support ESC key to close, default true |
on_ok(callback) |
Set OK button callback, return true to close dialog |
on_cancel(callback) |
Set cancel button callback, return true to close dialog |
on_close(callback) |
Set callback after dialog closes |
DialogButtonProps
Every property is unset until a builder sets it, and an unset property keeps whatever the dialog already carries.
| Method | Description |
|---|---|
ok_text(text) |
Set OK button text, default "OK" |
cancel_text(text) |
Set cancel button text, default "Cancel" |
ok_variant(variant) |
Set OK button variant |
cancel_variant(variant) |
Set cancel button variant |
show_cancel(bool) |
Show/hide cancel button |
on_ok(callback) |
Set OK callback |
on_cancel(callback) |
Set cancel callback |
DialogAction
A wrapper component that automatically triggers the Confirm action when its child element is clicked. This invokes the on_ok callback set on the AlertDialog.
Usage:
DialogAction::new().child(
Button::new("ok").primary().label("Confirm")
)Behavior:
- Dispatches
Confirmaction on click - Invokes the
on_okcallback - Dialog closes if callback returns
true - Dialog stays open if callback returns
false
DialogClose
A wrapper component that automatically triggers the Cancel action when its child element is clicked. This invokes the on_cancel callback set on the AlertDialog.
Usage:
DialogClose::new().child(
Button::new("cancel").outline().label("Cancel")
)Behavior:
- Dispatches
Cancelaction on click - Invokes the
on_cancelcallback - Dialog closes if callback returns
true(or if no callback is set) - Dialog stays open if callback returns
false
Examples
Delete Confirmation
Using imperative API:
Button::new("delete")
.danger()
.label("Delete")
.on_click(|_, window, cx| {
window.open_alert_dialog(cx, |alert, _, _| {
alert
.title("Delete File?")
.description("This action cannot be undone.")
.confirm()
.ok_text("Delete")
.ok_variant(ButtonVariant::Danger)
.on_ok(|_, window, cx| {
// Perform delete operation
window.push_notification("File deleted", cx);
true
})
});
})Or using declarative API with DialogAction/DialogClose:
AlertDialog::new(cx)
.trigger(Button::new("delete").danger().label("Delete"))
.on_ok(|_, window, cx| {
window.push_notification("File deleted", cx);
true
})
.content(|content, _, cx| {
content
.child(
DialogHeader::new()
.child(DialogTitle::new().child("Delete File?"))
.child(DialogDescription::new().child("This action cannot be undone."))
)
.child(
DialogFooter::new()
.child(
DialogClose::new().child(
Button::new("cancel").outline().label("Cancel")
)
)
.child(
DialogAction::new().child(
Button::new("delete-confirm").danger().label("Delete")
)
)
)
})Session Timeout
window.open_alert_dialog(cx, |alert, _, _| {
alert
.content(|content, _, _| {
content
.child(
DialogHeader::new()
.items_center()
.child(DialogTitle::new().child("Session Expired"))
.child(DialogDescription::new().child(
"Your session has expired due to inactivity. \
Please log in again to continue."
))
)
.child(
DialogFooter::new()
.child(
Button::new("sign-in")
.label("Sign in")
.primary()
.flex_1()
.on_click(|_, window, cx| {
window.push_notification("Redirecting to login...", cx);
window.close_dialog(cx);
})
)
)
})
})Update Available
AlertDialog::new(cx)
.trigger(Button::new("update").outline().label("Update Available"))
.on_cancel(|_, window, cx| {
window.push_notification("Update postponed", cx);
true
})
.on_ok(|_, window, cx| {
window.push_notification("Starting update...", cx);
true
})
.content(|content, _, _| {
content
.child(
DialogHeader::new()
.child(DialogTitle::new().child("Update Available"))
.child(DialogDescription::new().child(
"A new version (v2.0.0) is available. \
This update includes new features and bug fixes."
))
)
.child(
DialogFooter::new()
.child(
DialogClose::new().child(
Button::new("later").flex_1().outline().label("Later")
)
)
.child(
DialogAction::new().child(
Button::new("update-now").flex_1().primary().label("Update Now")
)
)
)
})Best Practices
- Choose the Right API: Use imperative API (
open_alert_dialog) for simple confirmations; use declarative API (trigger+content) for complex layouts or integration with other components - Use DialogAction and DialogClose: Prefer wrapping buttons with
DialogActionandDialogCloseover manualwindow.close_dialog()calls for cleaner, more declarative code - Clarify Intent: Use appropriate button variants (e.g.,
ButtonVariant::Dangerfor delete operations) to communicate the importance of actions - Provide Clear Descriptions: Ensure users understand the consequences of their actions, especially for destructive operations
- Use Icons Wisely: Icons can enhance attention for warnings and errors, but use them appropriately
- Prevent Closing Carefully: Only prevent dialog closing when user confirmation is truly necessary (e.g., a process is running)
- Maintain Consistency: Keep dialog button order and styles consistent throughout your application
Related Components
- Dialog - More flexible dialog component
- DialogHeader - Dialog header component
- DialogTitle - Dialog title component
- DialogDescription - Dialog description component
- DialogFooter - Dialog footer component
- DialogAction - Wrapper component for confirm/OK buttons
- DialogClose - Wrapper component for cancel/close buttons
Documentation license: original prose and illustrations for which GPUI Kit holds licensing rights are also offered under CC BY 4.0. When copying or adapting, credit GPUI Kit, link the source (https://gpui-kit.com/component/alert-dialog) and https://creativecommons.org/licenses/by/4.0/, and indicate changes. Code examples and software source use Apache-2.0; third-party material retains its terms; existing Apache-2.0 permissions remain.
Bundled from GPUI Kit. Documentation prose: CC BY 4.0; code examples: Apache-2.0. Changes: documentation links localized, asset URLs made absolute, and this attribution added.