Skip to content

Comments

MudDialogProvider: Add CloseOnNavigation to DialogOptions to optionally close dialogs on navigation#12437

Merged
danielchalmers merged 39 commits intoMudBlazor:devfrom
aaronleev:fix-#10397
Feb 4, 2026
Merged

MudDialogProvider: Add CloseOnNavigation to DialogOptions to optionally close dialogs on navigation#12437
danielchalmers merged 39 commits intoMudBlazor:devfrom
aaronleev:fix-#10397

Conversation

@aaronleev
Copy link
Contributor

@aaronleev aaronleev commented Jan 13, 2026

Added CloseOnNavigation property to DialogOptions and implemented the use case for that property.
This use case also required that the IDialogReference now have access to the DialogOptions that were supplied during its creation.

This change fixes an issue with same page navigation where url changes automatically close all dialogs regardless of the navigation destination being somewhere different or the same page simply updating a parameter.

Checklist:

  • I've read the contribution guidelines
  • My code follows the style of this project
  • I've added or updated relevant unit tests.

@mudbot mudbot bot added the enhancement Adds a new feature or enhances existing functionality (not fixing a defect) in the main library label Jan 13, 2026
@aaronleev aaronleev changed the title MudDialogProvider: Added CloseOnNavigation to DialogOptions to optionally close dialogs on navigation. (#10397) MudDialogProvider: Added CloseOnNavigation to DialogOptions to optionally close dialogs on navigation. (https://github.com/MudBlazor/MudBlazor/issues/10397) Jan 14, 2026
@aaronleev aaronleev changed the title MudDialogProvider: Added CloseOnNavigation to DialogOptions to optionally close dialogs on navigation. (https://github.com/MudBlazor/MudBlazor/issues/10397) MudDialogProvider: Added CloseOnNavigation to DialogOptions to optionally close dialogs on navigation. (10397) Jan 14, 2026
@aaronleev aaronleev changed the title MudDialogProvider: Added CloseOnNavigation to DialogOptions to optionally close dialogs on navigation. (10397) MudDialogProvider: Added CloseOnNavigation to DialogOptions to optionally close dialogs on navigation. (#10397) Jan 14, 2026
@aaronleev
Copy link
Contributor Author

aaronleev commented Feb 4, 2026

@danielchalmers

I have add a solution according to your comment.
Where CloseOnNavigation when null will look at the absolute path of where we were and compare it to where we are, if it has changed we close.

We still want to keep CloseOnNavigation as an option as this doesn't address pages that have multiple @page attributes that will get caught by this "smart close" feature.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 23 to 80
@@ -67,6 +72,12 @@ public interface IDialogReference
/// <param name="inst">The new dialog to use.</param>
void InjectDialog(object inst);

/// <summary>
/// Replaces the dialog options.
/// </summary>
/// <param name="options">The new options to use</param>
void InjectOptions(DialogOptions options);

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDialogReference is a public interface; adding new members (Options, InjectOptions) is a binary breaking change for any external implementation of IDialogReference. If maintaining backwards compatibility is a goal, consider introducing a new derived interface (e.g., IDialogReferenceWithOptions) or providing default interface implementations where possible.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is an acceptable breaking change, otherwise where does it end.

Comment on lines +1668 to +1670
var reference = await service.ShowAsync<DialogOkCancel>();
reference.InjectOptions(null);

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InjectOptions(null) does not compile with the current IDialogReference.InjectOptions(DialogOptions options) signature. Either make InjectOptions accept nullable options, or update these tests to avoid passing null (e.g., verify behavior with CloseOnNavigation = null on a real DialogOptions instance).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

@aaronleev aaronleev Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a test, options are not required on construction of a reference, neither is the RenderFragment or the Dialog instance itself. This is edge case test for a poorly configured IDialogReference.

It will compile it just has a warning on the test case.

(e.g., verify behavior with CloseOnNavigation = null on a real DialogOptions instance). This is verified in other tests in the same file.

Comment on lines +1689 to +1691
var reference = await service.ShowAsync<DialogOkCancel>();
reference.InjectOptions(null);

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InjectOptions(null) does not compile with the current IDialogReference.InjectOptions(DialogOptions options) signature. Either make InjectOptions accept nullable options, or update these tests to avoid passing null (e.g., verify behavior with CloseOnNavigation = null on a real DialogOptions instance).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a test, options are not required on construction of a reference, neither is the RenderFragment or the Dialog instance itself. This is edge case test for a poorly configured IDialogReference.

It will compile it just has a warning on the test case.

(e.g., verify behavior with CloseOnNavigation = null on a real DialogOptions instance). This is verified in other tests in the same file.

/// Replaces the dialog options.
/// </summary>
/// <param name="options">The new options to use</param>
void InjectOptions(DialogOptions options);
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nullability is inconsistent: Options is declared as DialogOptions?, but InjectOptions requires a non-null DialogOptions. Either make Options non-nullable (and ensure it's always set at creation) or allow InjectOptions(DialogOptions? options) so callers/tests can represent "no options" consistently.

Suggested change
void InjectOptions(DialogOptions options);
void InjectOptions(DialogOptions? options);

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

@aaronleev aaronleev Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is consistent with similar functionality in IDialogReference. The options are nullable as they are optional at creation, that doesn't necessarily mean you can later set them to null.

}

/// <inheritdoc />
public void InjectOptions(DialogOptions options)
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DialogReference.InjectOptions cannot set Options back to null because the parameter is non-nullable. This currently conflicts with new unit tests that call InjectOptions(null). Align the signature with the nullable Options property (accept DialogOptions?) or remove the need to ever represent Options == null and adjust tests accordingly.

Suggested change
public void InjectOptions(DialogOptions options)
public void InjectOptions(DialogOptions? options)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in reference to a unit test, it is an object reference so unlike a struct nullability is a suggestion. The call to .InjectOptions(null) is for code converge reasons as DialogOptions can be null on the DialogReference.

Comment on lines +121 to +124
var newUri = $"{uri.GetLeftPart(UriPartial.Path)}?{query}";
await comp.InvokeAsync(() => navigationManager.NavigateTo(newUri));

cont = comp.FindAll("div.mud-dialog-container");
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test expects only 1 dialog to remain after changing only the query string, but the new CloseOnNavigation == null behavior is documented to not close dialogs when only query/fragment changes. After fixing _currentUri initialization, this test will likely fail; update it to assert the intended default behavior (query change keeps dialogs open, path change closes unless CloseOnNavigation == false).

Suggested change
var newUri = $"{uri.GetLeftPart(UriPartial.Path)}?{query}";
await comp.InvokeAsync(() => navigationManager.NavigateTo(newUri));
cont = comp.FindAll("div.mud-dialog-container");
var newUriWithQueryChange = $"{uri.GetLeftPart(UriPartial.Path)}?{query}";
await comp.InvokeAsync(() => navigationManager.NavigateTo(newUriWithQueryChange));
// Changing only the query string should not close dialogs when CloseOnNavigation is null (default)
cont = comp.FindAll("div.mud-dialog-container");
cont.Count.Should().Be(2);
// Changing the path should close dialogs with default CloseOnNavigation, but keep those with CloseOnNavigation = false
var newUriWithPathChange = $"{uri.GetLeftPart(UriPartial.Path)}-other";
await comp.InvokeAsync(() => navigationManager.NavigateTo(newUriWithPathChange));
cont = comp.FindAll("div.mud-dialog-container");

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 122
@@ -91,6 +92,39 @@ public async Task Simple()
result.Canceled.Should().BeFalse();
}

/// <summary>
/// Opening and closing dialogs via navigation.
/// </summary>
[Test]
public async Task CloseOnNavigationTest()
{
var comp = Context.Render<MudDialogProvider>();
comp.Markup.Trim().Should().BeEmpty();
var dialogService = Context.Services.GetRequiredService<IDialogService>();
dialogService.Should().NotBe(null);
var navigationManager = Context.Services.GetRequiredService<NavigationManager>();
navigationManager.Should().NotBe(null);

//create 2 instances and dismiss all except for one with CloseOnNavigation = false
var closeOnNavigationOptions = new DialogOptions
{
CloseOnNavigation = false
};
await comp.InvokeAsync(async () => _ = await dialogService.ShowAsync<DialogOkCancel>("test", options: closeOnNavigationOptions));
await comp.InvokeAsync(async () => _ = await dialogService.ShowAsync<DialogOkCancel>());
var cont = comp.FindAll("div.mud-dialog-container");
cont.Count.Should().Be(2);

var uri = new Uri(navigationManager.Uri);
var query = HttpUtility.ParseQueryString(uri.Query);
query["query"] = Guid.NewGuid().ToString();
var newUri = $"{uri.GetLeftPart(UriPartial.Path)}?{query}";
await comp.InvokeAsync(() => navigationManager.NavigateTo(newUri));
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing using System.Web; / HttpUtility.ParseQueryString adds a new dependency that does not appear to be referenced in the test project and may fail to compile on modern .NET targets. Prefer a framework-native approach (e.g., UriBuilder, simple string concat, or Microsoft.AspNetCore.WebUtilities.QueryHelpers) to construct a URI with updated query parameters.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 76
@@ -7,6 +10,8 @@
<MudButton OnClick="ToggleCloseButtonAsync">Toggle Close Button</MudButton>
<MudButton OnClick="ToggleFullWidthAsync">Toggle Full Width</MudButton>
<MudButton OnClick="ToggleHeaderAsync">Toggle Header</MudButton>
<MudCheckBox TriState="true" T="bool?" Value="MudDialog.Options.CloseOnNavigation" ValueChanged="@(async v => await CloseOnNavigationChangedAsync(v))">Close On Navigation</MudCheckBox>
<MudButton OnClick="ChangeUrl">Change Url</MudButton>
</div>
</DialogContent>
<DialogActions>
@@ -18,6 +23,13 @@
[CascadingParameter]
private IMudDialogInstance MudDialog { get; set; }

[SupplyParameterFromQuery(Name = "example")]
public int? QueryParameterExample { get; set; }

protected override void OnParametersSet() {
QueryParameterExample ??= 0;
}

private void Close() => MudDialog.Close(DialogResult.Ok(true));

private Task ChangeTitleAsync() => MudDialog.SetTitleAsync($"Current time is: {DateTime.Now}");
@@ -51,4 +63,26 @@

return MudDialog.SetOptionsAsync(options);
}

private void ChangeUrl() {
var uri = new Uri(NavigationManager.Uri);

var query = HttpUtility.ParseQueryString(uri.Query);

query["example"] = (QueryParameterExample + 1).ToString();

var newUri = $"{uri.GetLeftPart(UriPartial.Path)}?{query}";

NavigationManager.NavigateTo(newUri);
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@using System.Web / HttpUtility.ParseQueryString introduces a dependency that isn't referenced in the docs project (and is generally avoided in Blazor). Since MudBlazor.Docs already references Microsoft.AspNetCore.WebUtilities, consider using QueryHelpers.AddQueryString (or UriBuilder) to update the query string without relying on System.Web APIs.

Copilot uses AI. Check for mistakes.
@danielchalmers
Copy link
Member

Sorry about Copilot - Thank you for all your work on this!!

@danielchalmers danielchalmers merged commit ff8242d into MudBlazor:dev Feb 4, 2026
16 checks passed
ScarletKuro pushed a commit to ScarletKuro/MudBlazor that referenced this pull request Feb 7, 2026
…ly close dialogs on navigation (MudBlazor#12437)

Co-authored-by: avalerio <avalerio@tnwops.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Chalmers <daniel.chalmers@outlook.com>
@ScarletKuro ScarletKuro mentioned this pull request Feb 11, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Adds a new feature or enhances existing functionality (not fixing a defect) in the main library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants