Alert Dialog
An alert dialog interrupting the user with important content and expects an immediate response.
Demo
Features
-
Programmatic API similar to
window.confirm() -
Async/await with
ValueTask<bool>return - Destructive action support with visual indicators
- Customizable title, message, and button text
- Configurable escape and overlay close behavior
- Provider pattern for app-wide availability
- Focus management for destructive dialogs
- Animation support
-
WCAG compliant with
role="alertdialog"
Installation
dotnet add package SummitUISetup
Required Setup
1. Create the AlertDialog component
Create a component that wraps AlertDialogProvider with your desired styling:
@* Components/AlertDialog.razor *@
<AlertDialogProvider Context="alert">
<AlertDialogPortal>
<AlertDialogOverlay class="overlay-styles" />
<AlertDialogContent class="content-styles">
<AlertDialogTitle class="title-styles" />
<AlertDialogDescription class="description-styles" />
<div class="actions">
<AlertDialogCancel class="cancel-button-styles" />
<AlertDialogConfirm class="confirm-button-styles" />
</div>
</AlertDialogContent>
</AlertDialogPortal>
</AlertDialogProvider>2. Add to your layout
Place the component in your layout with an interactive render mode. This makes it available app-wide:
@* In your layout (e.g., MainLayout.razor) *@
@inherits LayoutComponentBase
<AlertDialog @rendermode="InteractiveWebAssembly" />
<main>
@Body
</main>@rendermode directive enables interactivity for the dialog. Without it, the dialog cannot respond to user input.
Anatomy
The AlertDialog is composed of nested components that you structure within the provider:
<AlertDialogProvider Context="alert">
<AlertDialogPortal>
<AlertDialogOverlay />
<AlertDialogContent>
<AlertDialogTitle />
<AlertDialogDescription />
<div class="actions">
<AlertDialogCancel />
<AlertDialogConfirm />
</div>
</AlertDialogContent>
</AlertDialogPortal>
</AlertDialogProvider>Sub-components
AlertDialogProvider
Root provider that manages dialog lifecycle and responds to service events.
AlertDialogContent
Main alert dialog panel with focus trapping and scroll locking.
AlertDialogTitle
Accessible title component with auto-generated ID.
AlertDialogDescription
Accessible message/description component with auto-generated ID.
AlertDialogConfirm
Confirm button that completes the dialog with true.
AlertDialogCancel
Cancel button that completes the dialog with false.
AlertDialogOverlay
Backdrop overlay that can close the dialog when clicked (if configured).
AlertDialogPortal
Fixed-position container for rendering outside of DOM hierarchy.
API Reference
IAlertDialogService
| Property | Type | Default | Description |
|---|---|---|---|
| ConfirmAsync | ValueTask<bool> | - | Shows a confirmation dialog and returns user choice |
| OnShow | event Action<AlertDialogRequest> | - | Event raised when a dialog should be shown (handled by provider) |
AlertDialogOptions
| Property | Type | Default | Description |
|---|---|---|---|
| Title | string? | null | Dialog title |
| ConfirmText | string | "Confirm" | Confirm button text |
| CancelText | string | "Cancel" | Cancel button text |
| IsDestructive | bool | false | Marks the action as destructive (affects focus and styling) |
| AllowEscapeClose | bool | true | Whether escape key closes the dialog |
| AllowOverlayClose | bool | false | Whether clicking the overlay closes the dialog |
AlertDialogProvider
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContentrequired | RenderFragment<AlertDialogContext> | - | Dialog structure template with context access |
AlertDialogContent
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | - | Optional content (replaces title, description, and buttons) |
| As | string | "div" | HTML element type |
| TrapFocus | bool | true | Enable focus trapping |
| PreventScroll | bool | true | Lock body scroll |
| OnEscapeKeyDown | EventCallback<KeyboardEventArgs> | - | Callback on escape key |
| OnOpenAutoFocus | EventCallback | - | Callback when dialog receives auto-focus |
| OnCloseAutoFocus | EventCallback | - | Callback when dialog loses auto-focus |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
AlertDialogTitle
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | - | Optional title content (replaces Options.Title) |
| As | string | "h2" | HTML element type |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
AlertDialogDescription
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | - | Optional description content (replaces Message) |
| As | string | "p" | HTML element type |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
AlertDialogConfirm
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | - | Optional button content (replaces Options.ConfirmText) |
| As | string | "button" | HTML element type |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
AlertDialogCancel
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | - | Optional button content (replaces Options.CancelText) |
| As | string | "button" | HTML element type |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
AlertDialogOverlay
| Property | Type | Default | Description |
|---|---|---|---|
| As | string | "div" | HTML element type |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
AlertDialogPortal
| Property | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | - | Optional portal content (renders DialogOverlay and AlertDialogContent) |
| As | string | "div" | HTML element type |
| AdditionalAttributes | IDictionary<string, object> | - | Additional HTML attributes |
Examples
Simple Confirmation
Basic confirm dialog with custom text.
@inject IAlertDialogService AlertDialogService
<button @onclick="ShowConfirm">
Show Confirmation
</button>
@code {
private async Task ShowConfirm()
{
var confirmed = await AlertDialogService.ConfirmAsync(
"Are you sure you want to proceed?",
new AlertDialogOptions
{
Title = "Confirm Action",
ConfirmText = "Yes, proceed",
CancelText = "No, cancel"
});
if (confirmed)
{
// User confirmed
}
else
{
// User cancelled
}
}
}Destructive Action
Confirmation dialog for destructive actions with visual warning.
@inject IAlertDialogService AlertDialogService
<button class="btn btn-destructive" @onclick="DeleteItem">
Delete Item
</button>
@code {
private async Task DeleteItem()
{
var confirmed = await AlertDialogService.ConfirmAsync(
"This action cannot be undone. This will permanently delete the item and all associated data.",
new AlertDialogOptions
{
Title = "Delete Item",
ConfirmText = "Delete",
CancelText = "Cancel",
IsDestructive = true,
AllowEscapeClose = false,
AllowOverlayClose = false
});
if (confirmed)
{
// Perform delete operation
}
}
}Custom Options
Full customization of dialog appearance and behavior.
@inject IAlertDialogService AlertDialogService
<button @onclick="ShowCustomDialog">
Show Custom Dialog
</button>
@code {
private async Task ShowCustomDialog()
{
var result = await AlertDialogService.ConfirmAsync(
"Please review the terms and conditions before continuing. By clicking accept, you agree to be bound by these terms.",
new AlertDialogOptions
{
Title = "Terms & Conditions",
ConfirmText = "I Accept",
CancelText = "Decline",
IsDestructive = false,
AllowEscapeClose = true,
AllowOverlayClose = false
});
if (result)
{
// User accepted terms
}
else
{
// User declined
}
}
}Programmatic Control
Using the service in component code with full async/await pattern.
@inject IAlertDialogService AlertDialogService
<div class="flex gap-2">
<button @onclick="ShowSimpleConfirm">Simple</button>
<button @onclick="ShowDestructiveConfirm">Destructive</button>
<button @onclick="ShowNoEscapeConfirm">No Escape</button>
</div>
@code {
private async Task ShowSimpleConfirm()
{
// Simple confirmation with defaults
var confirmed = await AlertDialogService.ConfirmAsync("Are you sure?");
if (confirmed)
{
// Proceed with action
}
}
private async Task ShowDestructiveConfirm()
{
// Destructive action with warning
var confirmed = await AlertDialogService.ConfirmAsync(
"Permanently delete this item?",
new AlertDialogOptions
{
Title = "Delete Item",
IsDestructive = true
});
if (confirmed)
{
// Delete the item
}
}
private async Task ShowNoEscapeConfirm()
{
// Dialog that cannot be dismissed with Escape
var confirmed = await AlertDialogService.ConfirmAsync(
"This requires your attention. Please confirm to continue.",
new AlertDialogOptions
{
Title = "Attention Required",
AllowEscapeClose = false,
AllowOverlayClose = false
});
if (confirmed)
{
// User explicitly confirmed
}
}
}Styling
Data Attributes
| Attribute | Values | Description |
|---|---|---|
| data-state | "open" | "closed" | Dialog open state |
| data-destructive | Present when destructive | Indicates the dialog is for destructive action |
CSS Example
/* Overlay styles */
.alert-dialog-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.alert-dialog-overlay[data-state="open"] {
animation: fadeIn 200ms ease-out;
}
/* Content styles */
.alert-dialog-content {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
border-radius: 8px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
padding: 1.5rem;
min-width: 400px;
max-width: 90vw;
z-index: 1001;
}
.alert-dialog-content[data-state="open"] {
animation: scaleIn 200ms ease-out;
}
/* Destructive dialog styling */
.alert-dialog-content[data-destructive] {
border-left: 4px solid #ef4444;
}
/* Actions container */
.alert-dialog-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1.5rem;
}
/* Button styling */
.alert-dialog-cancel {
background: transparent;
border: 1px solid #e0e0e0;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
}
.alert-dialog-cancel:hover {
background: #f5f5f5;
}
.alert-dialog-confirm {
background: #0066cc;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
}
.alert-dialog-confirm:hover {
background: #0052a3;
}
/* Destructive confirm button */
.alert-dialog-content[data-destructive] .alert-dialog-confirm {
background: #ef4444;
}
.alert-dialog-content[data-destructive] .alert-dialog-confirm:hover {
background: #dc2626;
}
/* Animations */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes scaleIn {
from {
opacity: 0;
transform: translate(-50%, -50%) scale(0.95);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}Accessibility
Keyboard Navigation
| Key | Action |
|---|---|
| Escape | Closes the dialog (if AllowEscapeClose is true) |
| Tab | Moves focus to next focusable element |
| Shift + Tab | Moves focus to previous focusable element |
ARIA Attributes
- AlertDialogContent:
Has
role="alertdialog",aria-modal,aria-labelledby, andaria-describedby - AlertDialogTitle:
Auto-generates ID and is referenced by content's
aria-labelledby - AlertDialogDescription:
Auto-generates ID and is referenced by content's
aria-describedby - Destructive dialogs: Focus is automatically set to cancel button first for destructive actions