Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2441919
Refactor MessageBarService to NotificationService
dvoituron Jun 18, 2026
bb5217e
Update NotificationService method names in documentation to reflect n…
dvoituron Jun 18, 2026
07695ac
Refactor - Part 1
dvoituron Jun 18, 2026
6301a5c
Refactor Toast component structure and enhance slot definitions
dvoituron Jun 19, 2026
b427c4f
Merge branch 'dev-v5' into users/dvoituron/dev-v5/toast-refactor
dvoituron Jun 19, 2026
b1625e7
Refactor Toast System to Notification System
dvoituron Jun 19, 2026
6a8086a
Refactor Toast component to use NotificationService and update styles
dvoituron Jun 20, 2026
28c92a6
Refactor Toast component lifecycle management and status handling
dvoituron Jun 20, 2026
dacedc1
Refactor Toast component to ensure proper status handling and result …
dvoituron Jun 20, 2026
7395a74
Refactor Toast example to support multiple toast intents and improve …
dvoituron Jun 20, 2026
14fe145
Refactor FluentToast component to enhance attribute handling and impr…
dvoituron Jun 20, 2026
9a010f2
Refactor FluentToastProvider to improve CascadingValue usage and enha…
dvoituron Jun 20, 2026
19efa13
Refactor Toast instance management to support dynamic state updates a…
dvoituron Jun 20, 2026
b2f0c8a
Refactor FluentToastDefault example to enhance layout spacing and imp…
dvoituron Jun 20, 2026
ac38b06
Refactor toast components to improve state management, enhance progre…
dvoituron Jun 20, 2026
5d19317
Refactor DismissClickAsync method to use ToastCloseReason for improve…
dvoituron Jun 20, 2026
892a258
Refactor toast examples to use INotificationService, improve button s…
dvoituron Jun 20, 2026
fba1d77
Refactor toast components to support customizable width, enhance layo…
dvoituron Jun 20, 2026
d99d42b
Refactor toast queue synchronization to order queued toasts by index …
dvoituron Jun 20, 2026
b5d45dc
Refactor toast component to replace DismissAction with DismissLabel a…
dvoituron Jun 21, 2026
0bbd94b
Refactor toast component to use DismissAction for enhanced customizat…
dvoituron Jun 21, 2026
9a2de33
Refactor toast component to support quick action buttons, enhancing u…
dvoituron Jun 21, 2026
b092915
Refactor toast documentation to improve clarity and structure, adding…
dvoituron Jun 21, 2026
c9414ab
Refactor toast documentation for clarity and consistency, removing ou…
dvoituron Jun 21, 2026
e731a30
Refactor toast component to update callback naming conventions from C…
dvoituron Jun 21, 2026
2572425
Refactor toast component examples to utilize new notification service…
dvoituron Jun 21, 2026
132cf7a
Refactor toast and notification services to support dynamic component…
dvoituron Jun 21, 2026
935f286
Refactor toast result handling to include instance context and introd…
dvoituron Jun 21, 2026
e877457
Refactor toast examples and documentation to enhance result timing co…
dvoituron Jun 21, 2026
4c34c6f
Remove obsolete toast provider and instance tests, consolidating toas…
dvoituron Jun 21, 2026
442d771
Update toast example to clarify result timing display and improve ini…
dvoituron Jun 21, 2026
91cafac
Update toast result messages for clarity and consistency in completio…
dvoituron Jun 21, 2026
8fb4516
Refactor MessageBar tests to use dependency injection for Notificatio…
dvoituron Jun 21, 2026
08f2edd
Refactor MessageBar tests to use INotificationInstance for improved t…
dvoituron Jun 21, 2026
4a8d7e1
Add NonFocusRestoringTagNames to handle transient elements in dialog …
dvoituron Jun 22, 2026
f84f753
Refactor toast service documentation for clarity and accuracy
dvoituron Jun 22, 2026
4e63d9b
First unit tests
dvoituron Jun 22, 2026
1e4c0ef
Add unit tests
dvoituron Jun 22, 2026
2e38fff
Add unit tests
dvoituron Jun 22, 2026
1497bbc
Add Unit Tests
dvoituron Jun 22, 2026
608fc3d
Add unit tests
dvoituron Jun 22, 2026
bc60c83
Merge branch 'dev-v5' into users/dvoituron/dev-v5/toast-refactor
dvoituron Jun 22, 2026
9460218
Refactor toast lifetime handling to default to 7 seconds and allow in…
dvoituron Jun 23, 2026
6675b3d
Add tests for FluentToastProvider.GetLifetime method to validate life…
dvoituron Jun 23, 2026
27da99d
Enhance Toast documentation with detailed descriptions of toast types…
dvoituron Jun 23, 2026
ceae139
Merge branch 'dev-v5' into users/dvoituron/dev-v5/toast-refactor
dvoituron Jun 24, 2026
6c3268b
Merge branch 'dev-v5' into users/dvoituron/dev-v5/toast-refactor
dvoituron Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@inject IJSRuntime JSRuntime
@inject IToastService ToastService
@inject INotificationService NotificationService

<FluentStack HorizontalGap="20px" Wrap="true">
<FluentTextInput Label="Company Url" @bind-Value="@Domain">
Expand Down Expand Up @@ -38,7 +38,7 @@
{
await JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", EmailAddress);

await ToastService.ShowToastAsync(options => {
await NotificationService.ShowToastAsync(options => {
options.Intent = ToastIntent.Success;
options.Title = "Email address copied to clipboard!";
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
@inject IToastService ToastService
@inject INotificationService NotificationService

<FluentButton OnClick="@OpenToastAsync">
Make toast
<FluentButton OnClick="@OpenCustomDismissAsync">
Show Custom Dismiss
</FluentButton>

@code {
int clickCount = 0;

private async Task OpenToastAsync()
async Task OpenCustomDismissAsync()
{
var result = await ToastService.ShowToastAsync(options =>
var result = await NotificationService.ShowToastAsync(options =>
{
options.Intent = ToastIntent.Success;
options.Title = $"Toast title {++clickCount}";
options.Body = "This toast has a custom dismiss action.";
options.IsDismissable = true;
options.DismissAction = "Undo";
options.DismissActionCallback = () =>
options.Title = $"App update available";
options.Lifetime = TimeSpan.FromSeconds(10);
options.Message = "This toast has a custom dismiss action.";
options.DismissAction.Label = "Review";
options.DismissAction.Tooltip = "Click to review the update.";
options.DismissAction.OnClickAsync = async (e) =>
{
Console.WriteLine("Undo action executed.");
return Task.CompletedTask;
Console.WriteLine($"Review action clicked.");
await e.Instance.CloseAsync(ToastCloseReason.Dismissed);
};
options.OnStatusChange = (e) =>
{
Console.WriteLine($"Status changed: {e.Id} - {e.Status}");
};

});
Console.WriteLine($"Toast result: {result}");
}
}

Original file line number Diff line number Diff line change
@@ -1,39 +1,32 @@
@inject IToastService ToastService
@inject INotificationService NotificationService

<FluentButton OnClick="@OpenToastAsync">
Make toast
</FluentButton>
<FluentStack Wrap="true" HorizontalGap="12px">
<FluentButton OnClick="@(async e => await NotificationService.ShowSuccessToastAsync($"Success toast #{counter++}", lifetime: 5))">
Show Success
</FluentButton>
<FluentButton OnClick="@(async e => await NotificationService.ShowWarningToastAsync($"Warning toast #{counter++}", lifetime: 5))">
Show Warning
</FluentButton>
<FluentButton OnClick="@(async e => await NotificationService.ShowErrorToastAsync($"Error toast #{counter++}", lifetime: 5))">
Show Error
</FluentButton>
<FluentButton OnClick="@(async e => await NotificationService.ShowInfoToastAsync($"Info toast #{counter++}", lifetime: 5))">
Show Info
</FluentButton>
<FluentButton OnClick="@(async e => { ProgressResult = await NotificationService.ShowProgressToastAsync($"Progress toast #{counter++}"); })">
Show Progress
</FluentButton>
<FluentButton OnClick="@(async e => { if (ProgressResult is not null) await ProgressResult.Instance.CloseAsync(); })"
Disabled="@(ProgressResult is null)">
Close Progress
</FluentButton>
</FluentStack>

@code {
int clickCount = 0;

private async Task OpenToastAsync()
{
var result = await ToastService.ShowToastAsync(options =>
{
options.Title = $"Toast title {++clickCount}";
options.Body = "Toasts are used to show brief messages to the user.";
options.Subtitle = "subtitle";
options.QuickAction1 = "Action";
options.QuickAction1Callback = () =>
{
Console.WriteLine("Action 1 executed.");
return Task.CompletedTask;
};
options.QuickAction2 = "Action";
options.QuickAction2Callback = () =>
{
Console.WriteLine("Action 2 executed.");
return Task.CompletedTask;
};
options.IsDismissable = true;
options.OnStatusChange = (e) =>
{
Console.WriteLine($"Status changed: {e.Id} - {e.Status}");
};
int counter = 1;

});
Console.WriteLine($"Toast result: {result}");
}
ToastResult? ProgressResult;
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@inject INotificationService NotificationService

<FluentStack Wrap="true" HorizontalGap="12px">
<FluentButton OnClick="@(() => OpenToastAsync(ToastIntent.Info))">
Show Info
</FluentButton>
<FluentButton OnClick="@(() => OpenToastAsync(ToastIntent.Success))">
Show Success
</FluentButton>
<FluentButton OnClick="@(() => OpenToastAsync(ToastIntent.Warning))">
Show Warning
</FluentButton>
<FluentButton OnClick="@(() => OpenToastAsync(ToastIntent.Error))">
Show Error
</FluentButton>
<FluentButton OnClick="@(() => OpenToastAsync(ToastIntent.Progress))">
Show Progress
</FluentButton>
</FluentStack>

@code {

int counter = 1;

async Task OpenToastAsync(ToastIntent intent)
{
var result = await NotificationService.ShowToastAsync(options =>
{
options.Intent = intent;
options.Title = $"{intent} toast #{counter++}";
options.Message = "Toasts are used to show brief messages to the user.";
options.Subtitle = "Sent by Fluent UI Blazor";
options.Lifetime = TimeSpan.FromSeconds(10);
options.AllowDismiss = true;
options.OnStatusChange = (e) =>
{
Console.WriteLine($" . '{e.Instance.Options.Title}' status changed to: {e.Status}");
};
});

Console.WriteLine($"'{result.Instance.Options.Title}' closed with Reason: {result.Reason}");
}
}

Original file line number Diff line number Diff line change
@@ -1,40 +1,31 @@
@inject IToastService ToastService
@inject INotificationService NotificationService

<FluentButton @ref="openToastButton" OnClick="@OpenToastAsync">
Make toast
<FluentButton OnClick="@OpenProgressToastAsync"
Disabled="@InProgress">
Show Toast
</FluentButton>

@code {
FluentButton openToastButton = default!;

private static RenderFragment BuildProgressContent(int value) =>
@<div>
<FluentProgressBar Min="0" Max="100" Value="value" Width="100%" />
@($"{value}% complete")
</div>;
bool InProgress = false;

private async Task OpenToastAsync()
async Task OpenProgressToastAsync()
{
openToastButton.SetDisabled(true);
InProgress = true;

var instance = await ToastService.ShowToastInstanceAsync(options =>
// Show the "CustomizedProgressToast" razor component
var result = await NotificationService.ShowToastAsync<Toast.CustomizedProgressToast>(options =>
{
options.Type = ToastType.DeterminateProgress;
options.Icon = new Icons.Regular.Size20.ArrowDownload();
options.Title = "Downloading file";
options.BodyContent = BuildProgressContent(0);
options.Lifetime = TimeSpan.Zero; // Keep the toast open until closed after the progress is complete
options.Icon = new Icons.Regular.Size24.ArrowDownload();
options.AllowDismiss = false;
options.Width = "400px";
options.Parameters.Add("ProgressValue", 0);
});

for (int i = 0; i <= 100; i += 10)
{
await Task.Delay(500); // Simulate work being done
await instance.UpdateAsync(options =>
{
options.BodyContent = BuildProgressContent(i);
});
}

openToastButton.SetDisabled(false);
// Completed
InProgress = false;
Console.WriteLine($"'Progress toast' closed with Reason: {result.Reason} and Data: {result.Data}");
}
}

Original file line number Diff line number Diff line change
@@ -1,41 +1,54 @@
@inject IToastService ToastService
@inject INotificationService NotificationService

<FluentStack HorizontalGap="16">
<FluentButton @ref="openToastButton" OnClick="@OpenToastAsync">
Make toast
<FluentStack Wrap="true" HorizontalGap="12px">
<FluentButton OnClick="@StartProgressAsync"
Disabled="@InProgress">
Start Progress
</FluentButton>
<FluentButton OnClick="@FinishProcessAsync">
Finish process
<FluentButton OnClick="@FinishProgressAsync"
Disabled="@(ProgressToast is null)">
Finish Progress
</FluentButton>
</FluentStack>

@code {
int clickCount = 0;
FluentButton openToastButton = default!;

private async Task OpenToastAsync()
IToastInstance? ProgressToast;
bool InProgress = false;

// Show a Toast and keep a reference to the instance.
async Task StartProgressAsync()
{
// Disable the button to prevent multiple toasts from being opened.
// In a real app, you would likely want to track the toast ID and only disable if that specific toast is open.
openToastButton.SetDisabled(true);
var result = await ToastService.ShowToastAsync(options =>
InProgress = true;

_ = NotificationService.ShowToastAsync(options =>
{
options.Id = "indeterminate-toast";
options.Timeout = 0;
options.Type = ToastType.IndeterminateProgress;
options.Intent = ToastIntent.Success;
options.Title = $"Toast title {++clickCount}";
options.Body = "No idea when this will be finished...";
options.Id = "my-progress-toast";
options.Intent = ToastIntent.Progress;
options.Title = "Task in progress";
options.Lifetime = TimeSpan.Zero; // Keep the toast open until closed programmatically
options.Message = "No idea when this will be finished...";
options.AllowDismiss = false;
options.OnStatusChange = (e) =>
{
ProgressToast = e.Instance;
};
});
Console.WriteLine($"Toast result: {result}");

// Another way to get the instance of the Toast
// ProgressToast = NotificationService.GetToastInstance("my-progress-toast");
}

private async Task FinishProcessAsync()
// Close the Toast instance.
async Task FinishProgressAsync()
{
// In a real app, you would likely keep track of the toast ID and update that specific toast.
await ToastService.DismissAsync("indeterminate-toast");
// Enable the button again so a new toast can be opened.
openToastButton.SetDisabled(false);
if (ProgressToast is not null)
{
await ProgressToast.CloseAsync();
ProgressToast = null;
}

InProgress = false;
}
}

Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
@inject IToastService ToastService
@inject INotificationService NotificationService

<FluentButton OnClick="@OpenToastAsync">
Make toast
<FluentButton OnClick="@ShowInvertedToastAsync">
Show Inverted
</FluentButton>

@code {
int clickCount = 0;

private async Task OpenToastAsync()
int counter = 1;

async Task ShowInvertedToastAsync()
{
var result = await ToastService.ShowToastAsync(options =>
var result = await NotificationService.ShowToastAsync(options =>
{
options.Intent = ToastIntent.Info;
options.Title = $"Toast title {++clickCount}";
options.Body = "Toasts are used to show brief messages to the user.";
options.Subtitle = "subtitle";
options.QuickAction1 = "Action";
options.QuickAction1Callback = () =>
{
Console.WriteLine("Action 1 executed.");
return Task.CompletedTask;
};
options.IsDismissable = true;
options.DismissAction = "Close";
options.OnStatusChange = (e) =>
{
Console.WriteLine($"Status changed: {e.Id} - {e.Status}");
};
options.Inverted = true;
options.Title = $"Inverted toast #{counter++}";
options.Message = "Toasts are used to show brief messages to the user.";
});
Console.WriteLine($"Toast result: {result}");
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@inject INotificationService NotificationService
@inject IJSRuntime JS

<FluentButton OnClick="@OpenQuickActionToastAsync">
Show Quick Action Toast
</FluentButton>

@code {

async Task OpenQuickActionToastAsync()
{
var result = await NotificationService.ShowToastAsync(options =>
{
options.Intent = ToastIntent.Info;
options.Title = $"Your dashboard changed";
options.Lifetime = TimeSpan.FromSeconds(10);
options.Message = "Update were made to Comtoso Dashboard.";

options.QuickAction1.Label = "Review changes";
options.QuickAction1.Tooltip = "Click to review changes made in Comtoso Dashboard.";
options.QuickAction1.OnClickAsync = async (e) =>
{
Console.WriteLine($"Review action clicked.");
await e.Instance.CloseAsync(ToastCloseReason.Dismissed);
};

options.QuickAction2.Label = "See dashboard";
options.QuickAction2.Tooltip = "Click to see the dashboard.";
options.QuickAction2.OnClickAsync = async (e) =>
{
Console.WriteLine($"See dashboard action clicked.");
await JS.InvokeVoidAsync("open", "https://www.microsoft.com/", "_blank");
await e.Instance.CloseAsync(ToastCloseReason.Dismissed);
};
});
}
}

Loading
Loading