Notifications & Dialogs
Toast notifications, status bars, and dialog overlays
Namespace: Beep.Skia.Controls — Inherits: Notification → MaterialControl → SkiaComponent • Dialog → MaterialControl → SkiaComponent
Table of Contents
Overview
The Notification, StatusBar, and Dialog controls provide Material Design 3.0 messaging and overlay feedback entirely rendered with SkiaSharp. Notification (toast/snackbar) displays transient messages at a configurable screen position with automatic dismissal. StatusBar is a persistent bottom strip for status information, progress, and quick actions. Dialog renders a modal overlay with a title, body content, and action buttons, blocking interaction with the canvas beneath until dismissed.
All overlay components are managed by the OverlayManager, which handles z-ordering, focus trapping (for dialogs), and dismiss-on-escape behavior. Notifications and dialogs use enter/exit animations following MD3 motion guidelines.
Auto-Dismiss Timers
Notifications support configurable duration with a progress bar indicating time remaining before dismissal.
Modal Overlay
Dialogs render a semi-transparent scrim over the entire canvas, blocking pointer events to components behind.
Action Buttons
Snackbars and dialogs support inline action buttons for undo, confirm, cancel, and dismiss operations.
Status Icons
Each notification type renders a distinct icon (checkmark, warning triangle, error circle, info circle) using theme-aware colors.
Notification Properties
| Property | Type | Description |
|---|---|---|
Message |
string |
The notification body text. Supports multi-line for longer messages. Rendered using BodyMedium typography. |
Type |
NotificationType |
Enum: Info, Success, Warning, Error. Controls the icon, accent color, and background tint. See Notification Types below. |
Duration |
float |
Display duration in milliseconds. After this time elapses, the notification plays its exit animation and is removed. Default is 4000 (4 seconds). Set to 0 for persistent notifications that require manual dismissal. |
Position |
NotificationPosition |
Enum: Top, Bottom (default), TopLeft, TopRight, BottomLeft, BottomRight, Center. Controls where the notification appears within the canvas/client area. |
IsDismissible |
bool |
When true, a close (X) button is rendered at the trailing edge. Clicking it dismisses the notification immediately. Default is true. |
ShowProgress |
bool |
When true, a thin progress bar is rendered at the bottom of the notification indicating time remaining. Default is false. |
ActionText |
string |
Optional text for an action button (e.g., "Undo", "Retry"). The button is rendered at the trailing edge using LabelLarge typography in Primary color. |
CornerRadius |
float |
Corner rounding of the notification surface. Default is 4f per MD3 snackbar spec. |
Elevation |
int |
Material elevation shadow. Default is 6. |
MinWidth |
float |
Minimum width of the notification. Default is 344f. Notifications auto-size to content up to MaxWidth. |
MaxWidth |
float |
Maximum width before text wraps. Default is 568f. |
StatusBar & StatusBarItem
The StatusBar is a persistent horizontal strip typically rendered at the bottom of the canvas. It contains StatusBarItem children that display text, icons, or progress indicators.
| Property | Type | Description |
|---|---|---|
Items |
List<StatusBarItem> |
Collection of status items displayed left-to-right in the bar. |
BarHeight |
float |
Height of the status bar. Default is 24f. |
ShowGrip |
bool |
When true, a resize grip icon is rendered at the right edge. Default is false. |
StatusBarItem
| Property | Type | Description |
|---|---|---|
Text | string | The status text label. |
Icon | SKPath | Optional icon rendered before the text. |
Width | float | Fixed width of the item cell. Items with Width = 0 auto-size to their content. |
Alignment | StatusAlignment | Enum: Left (default) or Right. Right-aligned items are pushed to the bar's right edge. |
Dialog Support
The Dialog control renders a modal overlay dialog following MD3 dialog specifications. A semi-transparent scrim covers the canvas behind the dialog, and pointer events outside the dialog bounds are intercepted to enforce modality.
| Property | Type | Description |
|---|---|---|
Title |
string |
Dialog headline text. Rendered using HeadlineSmall typography. Set to null to hide. |
Body |
string or SkiaComponent |
The dialog's body content. Can be a simple string (rendered as BodyMedium text) or a SkiaComponent for custom content (forms, lists, etc.). |
Buttons |
List<Button> |
Action buttons rendered in the dialog footer, right-aligned. Typical use: one or two Button instances (e.g., Cancel + Confirm). |
IsOpen |
bool |
Controls dialog visibility. Setting to true registers the scrim and dialog with OverlayManager and plays the enter animation. |
IsModal |
bool |
When true (default), the scrim is rendered and background interaction is blocked. When false, the dialog is non-modal and background clicks pass through. |
ScrimOpacity |
float |
Opacity of the background scrim (0.0–1.0). Default is 0.32f per MD3 spec. |
CornerRadius |
float |
Dialog surface corner rounding. Default is 28f per MD3 dialog spec. |
Elevation |
int |
Material elevation shadow. Default is 8. |
MaxWidth |
float |
Maximum dialog width. Default is 560f. The dialog auto-sizes to content within this constraint. |
MinHeight |
float |
Minimum dialog height. Default is 0 (auto-size). |
| Event | Signature | Description |
|---|---|---|
Opened | EventHandler | Raised after the dialog enter animation completes. |
Closed | EventHandler | Raised after the dialog exit animation completes and the dialog is removed from the overlay layer. |
ActionClicked | EventHandler<string> | Raised when an action button is clicked. The argument is the Tag of the button. |
ActionClicked | EventHandler<string> (Notification) | Raised when the notification's ActionText button is clicked. |
Notification Types
| Type | Icon | Accent Color | Use When |
|---|---|---|---|
NotificationType.Info |
Information circle (i) | Primary from theme |
Neutral status messages, tips, procedural feedback |
NotificationType.Success |
Checkmark circle | #4CAF50 (MD3 green) |
Successful operations: save, export, upload, apply |
NotificationType.Warning |
Warning triangle | #FF9800 (MD3 orange) |
Non-critical issues: unsaved changes, deprecated feature, approaching limits |
NotificationType.Error |
Error circle with X | #F44336 (MD3 red) |
Failed operations: save error, connection lost, validation failure |
The accent color tints the leading icon and the left border of the notification surface. The background is always InverseSurface with InverseOnSurface text for high contrast.
Code Example
Showing a Success Notification
var notification = new Notification
{
Message = "Project saved successfully.",
Type = NotificationType.Success,
Duration = 3000,
Position = NotificationPosition.Bottom,
ShowProgress = true
};
notification.ActionClicked += (s, action) =>
Console.WriteLine($"Action: {action}");
notification.Initialize();
notification.Show();
drawingManager.RequestRedraw();
Snackbar with Undo Action
var snackbar = new Notification
{
Message = "Item deleted.",
Type = NotificationType.Info,
Duration = 5000,
Position = NotificationPosition.Bottom,
ActionText = "Undo",
ShowProgress = true
};
snackbar.Initialize();
snackbar.ActionClicked += (s, action) =>
{
if (action == "Undo")
{
RestoreDeletedItem();
}
};
snackbar.Show();
StatusBar with Multiple Items
var statusBar = new StatusBar
{
X = 0, Y = 0,
Width = 800,
BarHeight = 28,
Items = new List<StatusBarItem>
{
new() { Text = "Ready", Icon = null, Width = 120 },
new() { Text = "", Width = 0 },
new() { Text = "Ln 24, Col 12", Alignment = StatusAlignment.Right, Width = 140 },
new() { Text = "UTF-8", Alignment = StatusAlignment.Right, Width = 80 },
new() { Text = "100%", Alignment = StatusAlignment.Right, Width = 60 }
}
};
statusBar.Initialize();
drawingManager.AddComponent(statusBar);
drawingManager.RequestRedraw();
Modal Confirmation Dialog
var cancelButton = new Button
{
Text = "Cancel",
ButtonStyle = ButtonStyle.Text,
Width = 80, Height = 40,
Tag = "cancel"
};
var confirmButton = new Button
{
Text = "Delete",
ButtonStyle = ButtonStyle.Filled,
Width = 80, Height = 40,
Tag = "confirm"
};
cancelButton.Initialize();
confirmButton.Initialize();
var dialog = new Dialog
{
Title = "Delete Project?",
Body = "This action cannot be undone. All associated files and configurations will be permanently removed.",
Buttons = new List<Button> { cancelButton, confirmButton },
IsModal = true,
MaxWidth = 480
};
dialog.Initialize();
dialog.ActionClicked += (s, tag) =>
{
if (tag == "confirm")
{
DeleteProject();
ShowNotification("Project deleted.", NotificationType.Success);
}
dialog.Close();
};
dialog.Open();
drawingManager.RequestRedraw();
Error Notification (Top-Right, Persistent)
var errorNotification = new Notification
{
Message = "Failed to connect to database.\nCheck your connection settings and try again.",
Type = NotificationType.Error,
Duration = 0,
Position = NotificationPosition.TopRight,
IsDismissible = true,
ActionText = "Retry"
};
errorNotification.Initialize();
errorNotification.ActionClicked += (s, action) =>
{
if (action == "Retry") RetryConnection();
};
errorNotification.Show();
Notification Manager (Helper Pattern)
public static class NotificationManager
{
public static void ShowInfo(string message, string actionText = null,
Action action = null)
{
Show(message, NotificationType.Info, actionText, action);
}
public static void ShowSuccess(string message)
{
Show(message, NotificationType.Success);
}
public static void ShowError(string message, string actionText = null,
Action action = null)
{
Show(message, NotificationType.Error, actionText, action, duration: 0);
}
private static void Show(string message, NotificationType type,
string actionText = null, Action action = null, float duration = 4000)
{
var notification = new Notification
{
Message = message,
Type = type,
Duration = duration,
Position = NotificationPosition.Bottom,
ActionText = actionText
};
notification.Initialize();
if (actionText != null && action != null)
notification.ActionClicked += (s, a) => action();
notification.Show();
}
}