Skip to content
Document DB v7.2: Temporal Support, Telemetry Collection, All Calculations, String Based APIs, & Orleans Storage Providers! Feed The Machine Here

Dialogs

Dialogs is a service-first dialog system that emulates the classic alert, confirm, and prompt primitives. The dialog is always rendered by the library — the native platform alert/prompt is never used — so it looks identical across platforms and supports custom entry/exit animations and full template overrides. Inject IDialogService, await a result, and you’re done.

  • NuGet downloads for Shiny.Maui.Controls
  • NuGet downloads for Shiny.Blazor.Controls
Frameworks
.NET MAUI
Blazor
  • Code-invoked — inject IDialogService and await Dialogs.Alert(...), no per-call markup
  • Three primitivesAlert (acknowledge), Confirm (yes/no → bool), Prompt (text input → PromptResult)
  • Owned & animated — fade, slide (top/bottom/left/right), zoom, and pop animations; never the native dialog
  • Modal & queued — awaiting several calls in a row shows them one at a time
  • Customizable — per-call styling, global defaults, or a full template override
  • Themed — surface, text, outline, and primary colors follow the theme tokens for automatic light/dark

Registered automatically by UseShinyControls(). The overlay auto-attaches to the current page — no XAML or OverlayHost required.

builder.UseMauiApp<App>().UseShinyControls();
Program.cs
builder.Services.AddShinyDialogs();
<!-- MainLayout.razor (once) -->
<DialogHost />

The surface is identical on both hosts. On MAUI inject IDialogService into a ViewModel or service; on Blazor use @inject IDialogService Dialogs.

public class MyViewModel(IDialogService dialogs)
{
// Alert — single button, awaits dismissal
async Task SaveDone()
=> await dialogs.Alert("Heads up", "Your changes have been saved.", "Got it");
// Confirm — returns bool
async Task Delete()
{
var ok = await dialogs.Confirm("Delete item?", "This cannot be undone.", okText: "Delete", cancelText: "Cancel");
if (ok)
await DeleteItemAsync();
}
// Prompt — returns PromptResult
async Task Rename()
{
var result = await dialogs.Prompt("Rename file", "Enter a new name.", placeholder: "report.pdf", okText: "Rename");
if (result.Ok)
await RenameAsync(result.Value);
}
}
MethodReturnsDescription
Alert(title, message, okText = "OK", configure?)TaskSingle dismiss button.
Confirm(title, message, okText = "Yes", cancelText = "No", configure?)Task<bool>true on confirm, false on cancel.
Prompt(title, message, placeholder = null, okText = "OK", cancelText = "Cancel", configure?)Task<PromptResult>Text field plus confirm/cancel buttons.

configure is an optional Action<DialogConfig> for per-call animation and styling.

MemberTypeDescription
OkboolTrue when the user confirmed.
CancelledboolConvenience inverse of Ok.
Valuestring?The entered text. null when cancelled.

Every dialog animates in and out with an owned, cross-platform animation. Set per-call via configure, or set the app-wide default.

DialogAnimation: None, Fade, SlideTop, SlideBottom, SlideLeft, SlideRight, Zoom, Pop (default).

await dialogs.Confirm("Delete?", "This cannot be undone.", configure: c =>
{
c.Animation = DialogAnimation.SlideBottom;
});

The configure delegate exposes DialogConfigAnimation, BackgroundColor, TitleColor, MessageColor, OkButtonColor, OkButtonTextColor, CancelButtonColor, CancelButtonTextColor, CornerRadius, BackdropOpacity, DismissOnBackdrop, and more. Colors are MAUI Color on MAUI and CSS strings on Blazor.

await dialogs.Confirm("Custom", "Brand colors + zoom.", configure: c =>
{
c.Animation = DialogAnimation.Zoom;
c.BackgroundColor = Color.FromArgb("#312E81"); // Blazor: "#312E81"
c.OkButtonColor = Color.FromArgb("#22D3EE");
c.CornerRadius = 24;
});
// MAUI
builder.UseMauiApp<App>().UseShinyControls(c => c.ConfigureDialogs(o =>
{
o.DefaultAnimation = DialogAnimation.Zoom;
o.ConfigureDefaults = cfg => cfg.CornerRadius = 20; // applied to every dialog
}));
// Blazor
builder.Services.AddShinyDialogs(o => o.DefaultAnimation = DialogAnimation.Zoom);

Replace the entire dialog card while the host still supplies the dimmed backdrop and animation. The context (DialogContext) exposes Title, Message, OkText, CancelText, Placeholder, IsPrompt, HasCancel, a two-way PromptValue, and confirm/cancel.

@* Blazor — a RenderFragment<DialogContext> *@
<DialogHost>
<Template Context="ctx">
<div class="my-card">
<h3>@ctx.Title</h3>
<p>@ctx.Message</p>
@if (ctx.IsPrompt)
{
<input @bind="ctx.PromptValue" />
}
<button @onclick="ctx.Cancel">@ctx.CancelText</button>
<button @onclick="ctx.Confirm">@ctx.OkText</button>
</div>
</Template>
</DialogHost>

On MAUI, set DialogOptions.ContentTemplate (a DataTemplate whose BindingContext is the DialogContext, with ConfirmCommand/CancelCommand) via c.ConfigureDialogs(o => o.ContentTemplate = ...). You can also replace the whole service with c.SetCustomDialogs<MyDialogService>().

  • Queued: dialogs are modal and shown one at a time; awaiting several in a row displays them sequentially.
  • Backdrop: tapping the dimmed backdrop cancels (configurable via DismissOnBackdrop). On Blazor, Escape cancels and Enter confirms.
  • Theming: colors come from the theme tokens (Shiny.Color.Surface / --shiny-color-surface, Primary, …) so dialogs match light/dark automatically.
claude plugin marketplace add shinyorg/skills
claude plugin install controls@shiny
copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install controls@shiny
View controls Plugin