diff --git a/src/Core.Scripts/src/Components/Dialog/FluentDialog.ts b/src/Core.Scripts/src/Components/Dialog/FluentDialog.ts
index 4798f4b6a4..dc5aca34ac 100644
--- a/src/Core.Scripts/src/Components/Dialog/FluentDialog.ts
+++ b/src/Core.Scripts/src/Components/Dialog/FluentDialog.ts
@@ -10,11 +10,41 @@ export namespace Microsoft.FluentUI.Blazor.Components.Dialog {
}
/**
- * Hide the fluent-dialog with the given id
- * @param id The id of the fluent-dialog to hide
- */
+ * Hide the fluent-dialog with the given id
+ * @param id The id of the fluent-dialog to hide
+ */
export function Hide(id: string): void {
const dialog = document.getElementById(id) as any;
dialog?.hide();
+ FocusOnPreviousActiveElement(id);
+ }
+
+ /**
+ * Save the element that was active before the dialog was opened
+ * @param id
+ */
+ export function DialogToggle_PreviousActiveElement(id: string, newState: string): void {
+ const dialog = document.getElementById(id) as any;
+ if (dialog) {
+ if (newState === 'open') {
+ dialog.previousActiveElement = document.activeElement;
+ }
+ else if (newState === 'closed') {
+ FocusOnPreviousActiveElement(id);
+ }
+ }
+ }
+
+ /**
+ * Focus on the element that was active before the dialog was opened
+ * @param id
+ */
+ export function FocusOnPreviousActiveElement(id: string): void {
+ const dialog = document.getElementById(id) as any;
+ if (dialog) {
+ setTimeout(() => {
+ dialog.previousActiveElement?.focus();
+ }, 25);
+ }
}
}
diff --git a/src/Core.Scripts/src/FluentUICustomEvents.ts b/src/Core.Scripts/src/FluentUICustomEvents.ts
index e9700c9e71..c3eb615c93 100644
--- a/src/Core.Scripts/src/FluentUICustomEvents.ts
+++ b/src/Core.Scripts/src/FluentUICustomEvents.ts
@@ -1,3 +1,5 @@
+import { Microsoft as FluentDialogFile } from "./Components/Dialog/FluentDialog";
+
export namespace Microsoft.FluentUI.Blazor.FluentUICustomEvents {
/**
@@ -28,6 +30,7 @@ export namespace Microsoft.FluentUI.Blazor.FluentUICustomEvents {
blazor.registerCustomEventType('dialogbeforetoggle', {
browserEventName: 'beforetoggle',
createEventArgs: (event: any) => {
+ FluentDialogFile.FluentUI.Blazor.Components.Dialog.DialogToggle_PreviousActiveElement(event.target.id, event.detail?.newState ?? event.newState);
return {
id: event.target.id,
type: event.type,
@@ -130,7 +133,7 @@ export namespace Microsoft.FluentUI.Blazor.FluentUICustomEvents {
newState: event.detail?.newState ?? event.newState,
};
}
- });
+ });
}
// [^^^ Add your other custom events before this line ^^^]
diff --git a/src/Core/Components/Dialog/FluentDialog.razor.cs b/src/Core/Components/Dialog/FluentDialog.razor.cs
index 18e5841ac0..1ed1e3c958 100644
--- a/src/Core/Components/Dialog/FluentDialog.razor.cs
+++ b/src/Core/Components/Dialog/FluentDialog.razor.cs
@@ -12,7 +12,7 @@ namespace Microsoft.FluentUI.AspNetCore.Components;
///
/// The dialog component is a window overlaid on either the primary window or another dialog window.
-/// Windows under a modal dialog are inert.
+/// Windows under a modal dialog are inert.
///
public partial class FluentDialog : FluentComponentBase
{
@@ -75,11 +75,7 @@ public FluentDialog(LibraryConfiguration configuration) : base(configuration)
[Parameter]
public EventCallback OnStateChange { get; set; }
- ///
- ///
- ///
- ///
- ///
+ ///
protected override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && LaunchedFromService)
diff --git a/src/Core/Components/Dialog/Services/DialogService.cs b/src/Core/Components/Dialog/Services/DialogService.cs
index 8ed4116302..03c1cb55ae 100644
--- a/src/Core/Components/Dialog/Services/DialogService.cs
+++ b/src/Core/Components/Dialog/Services/DialogService.cs
@@ -4,6 +4,8 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.JSInterop;
namespace Microsoft.FluentUI.AspNetCore.Components;
@@ -13,6 +15,7 @@ namespace Microsoft.FluentUI.AspNetCore.Components;
public partial class DialogService : FluentServiceBase, IDialogService
{
private readonly IServiceProvider _serviceProvider;
+ private readonly IJSRuntime _jsRuntime;
///
/// Initializes a new instance of the class.
@@ -25,6 +28,7 @@ public partial class DialogService : FluentServiceBase, IDialog
public DialogService(IServiceProvider serviceProvider, IFluentLocalizer? localizer)
{
_serviceProvider = serviceProvider;
+ _jsRuntime = serviceProvider.GetRequiredService();
Localizer = localizer ?? FluentLocalizerInternal.Default;
}
@@ -104,11 +108,11 @@ public virtual async Task ShowDialogAsync([DynamicallyAccessedMemb
///
///
///
- internal Task RemoveDialogFromProviderAsync(IDialogInstance? dialog)
+ internal async Task RemoveDialogFromProviderAsync(IDialogInstance? dialog)
{
if (dialog is null)
{
- return Task.CompletedTask;
+ return;
}
// Remove the HTML code from the DialogProvider
@@ -117,6 +121,7 @@ internal Task RemoveDialogFromProviderAsync(IDialogInstance? dialog)
throw new InvalidOperationException($"Failed to remove dialog from DialogProvider: the ID '{dialog.Id}' doesn't exist in the DialogServiceProvider.");
}
- return ServiceProvider.OnUpdatedAsync.Invoke(dialog);
+ await ServiceProvider.OnUpdatedAsync.Invoke(dialog);
+ await _jsRuntime.InvokeVoidAsync("Microsoft.FluentUI.Blazor.Components.Dialog.FocusOnPreviousActiveElement", dialog.Id);
}
}