diff --git a/src/Components/Web/src/PublicAPI.Unshipped.txt b/src/Components/Web/src/PublicAPI.Unshipped.txt
index 3e6daf94f47d..e0acde65c88d 100644
--- a/src/Components/Web/src/PublicAPI.Unshipped.txt
+++ b/src/Components/Web/src/PublicAPI.Unshipped.txt
@@ -7,6 +7,8 @@ Microsoft.AspNetCore.Components.Web.EnvironmentBoundary.Exclude.get -> string?
Microsoft.AspNetCore.Components.Web.EnvironmentBoundary.Exclude.set -> void
Microsoft.AspNetCore.Components.Web.EnvironmentBoundary.Include.get -> string?
Microsoft.AspNetCore.Components.Web.EnvironmentBoundary.Include.set -> void
+Microsoft.AspNetCore.Components.Routing.NavLink.InactiveClass.get -> string?
+Microsoft.AspNetCore.Components.Routing.NavLink.InactiveClass.set -> void
Microsoft.AspNetCore.Components.Routing.NavLink.RelativeToCurrentUri.get -> bool
Microsoft.AspNetCore.Components.Routing.NavLink.RelativeToCurrentUri.set -> void
*REMOVED*Microsoft.AspNetCore.Components.Forms.RemoteBrowserFileStreamOptions
diff --git a/src/Components/Web/src/Routing/NavLink.cs b/src/Components/Web/src/Routing/NavLink.cs
index ef45761f1099..0d92db203173 100644
--- a/src/Components/Web/src/Routing/NavLink.cs
+++ b/src/Components/Web/src/Routing/NavLink.cs
@@ -29,6 +29,14 @@ public class NavLink : ComponentBase, IDisposable
[Parameter]
public string? ActiveClass { get; set; }
+ ///
+ /// Gets or sets the CSS class name applied to the NavLink when the
+ /// current route does not match the NavLink href. When null
+ /// (the default), no extra class is added in the inactive state.
+ ///
+ [Parameter]
+ public string? InactiveClass { get; set; }
+
///
/// Gets or sets a collection of additional attributes that will be added to the generated
/// a element.
@@ -110,7 +118,8 @@ public void Dispose()
private void UpdateCssClass()
{
- CssClass = _isActive ? CombineWithSpace(_class, ActiveClass ?? DefaultActiveClass) : _class;
+ var stateClass = _isActive ? (ActiveClass ?? DefaultActiveClass) : InactiveClass;
+ CssClass = stateClass is null ? _class : CombineWithSpace(_class, stateClass);
}
private void OnLocationChanged(object? sender, LocationChangedEventArgs args)
diff --git a/src/Components/Web/test/Routing/NavLinkTest.cs b/src/Components/Web/test/Routing/NavLinkTest.cs
index a967274717b3..81e66a35306e 100644
--- a/src/Components/Web/test/Routing/NavLinkTest.cs
+++ b/src/Components/Web/test/Routing/NavLinkTest.cs
@@ -45,6 +45,66 @@ public async Task NavLink_WithRelativeToCurrentUri_PreservesActiveClassLogic()
Assert.Equal("active", classValue);
}
+ [Fact]
+ public async Task NavLink_Active_UsesActiveClassAndIgnoresInactiveClass()
+ {
+ var classValue = await RenderNavLinkAndGetClassAsync(
+ currentUri: "https://example.com/page",
+ href: "https://example.com/page",
+ additionalClass: null,
+ inactiveClass: "text-gray");
+
+ Assert.Equal("active", classValue);
+ }
+
+ [Fact]
+ public async Task NavLink_Inactive_AppliesInactiveClassWhenSet()
+ {
+ var classValue = await RenderNavLinkAndGetClassAsync(
+ currentUri: "https://example.com/other",
+ href: "https://example.com/page",
+ additionalClass: null,
+ inactiveClass: "text-gray");
+
+ Assert.Equal("text-gray", classValue);
+ }
+
+ [Fact]
+ public async Task NavLink_Inactive_OmitsInactiveClassWhenNotSet()
+ {
+ var classValue = await RenderNavLinkAndGetClassAsync(
+ currentUri: "https://example.com/other",
+ href: "https://example.com/page",
+ additionalClass: "bg-dark-gray",
+ inactiveClass: null);
+
+ Assert.Equal("bg-dark-gray", classValue);
+ }
+
+ [Fact]
+ public async Task NavLink_Inactive_CombinesUserClassWithInactiveClass()
+ {
+ var classValue = await RenderNavLinkAndGetClassAsync(
+ currentUri: "https://example.com/other",
+ href: "https://example.com/page",
+ additionalClass: "bg-dark-gray",
+ inactiveClass: "text-gray");
+
+ Assert.Equal("bg-dark-gray text-gray", classValue);
+ }
+
+ [Fact]
+ public async Task NavLink_Active_CombinesUserClassWithActiveClass_WhenInactiveClassAlsoSet()
+ {
+ var classValue = await RenderNavLinkAndGetClassAsync(
+ currentUri: "https://example.com/page",
+ href: "https://example.com/page",
+ additionalClass: "bg-dark-gray",
+ inactiveClass: "text-gray");
+
+ Assert.Equal("bg-dark-gray active", classValue);
+ }
+
private async Task