Alert-dialog
Component

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

bash
dotnet add package SummitUI

Setup

1. Create the AlertDialog component

Create a component that wraps AlertDialogProvider with your desired styling:

razor
@* 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:

razor
@* In your layout (e.g., MainLayout.razor) *@
@inherits LayoutComponentBase

<AlertDialog @rendermode="InteractiveWebAssembly" />

<main>
    @Body
</main>

Anatomy

The AlertDialog is composed of nested components that you structure within the provider:

razor
<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.

razor
@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.

razor
@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.

razor
@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.

razor
@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

css
/* 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, and aria-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
An unhandled error has occurred. Reload X