Search code examples
blazorblazor-server-sideblazor-component

Blazor: Wrap NavLink with List Item


When I use a NavLink in a Blazor server application it gets rendered as <a>. I would like to get a list item wrapping it such as <li><a>.

I also want to leverage as much as possible on the default behavior of NavLink (e.g. track active url).

I tried something simple like

public class ListItemNavLink : NavLink
{
    public string? ListItemCssClass { get; set; }

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.OpenElement(0, "li");
        builder.AddAttribute(1, "class", ListItemCssClass);

        builder.OpenElement(2, "a");

        builder.AddMultipleAttributes(3, AdditionalAttributes);
        builder.AddAttribute(4, "class", CssClass);
        builder.AddContent(5, ChildContent);

        builder.CloseElement();
        builder.CloseElement();
    }
}

However when I try this

<ListItemNavLink ListItemCssClass="sidebar-item" class="sidebar-link" href="x">

I get this.

<li><a listitemcssclass="sidebar-item" href="x" class="sidebar-link">

Which is not exactly what I want. I would like to get something like this (please note the ACTIVE class state applied):

<li class="sitebar-item active">
<a class="sidebar-link">Some Text</a>
</li>

Any hint? Thanks


Solution

  • If I've understood what you expect, try the following as your ListItemNavLink - ListItemNavLink.razor.cs.

    <li class="@this.ListItemCssClass">
        <NavLink @attributes="@this.AdditionalAttributes" Match="@this.Match" ActiveClass="@this.ActiveClass" ></NavLink>
    </li>
    
    @code {
        [Parameter] public string ListItemCssClass { get; set; }
    
        [Parameter] public NavLinkMatch Match { get; set; }
    
        [Parameter] public string ActiveClass { get; set; }
    
        [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object> AdditionalAttributes { get; set; }
    
    }
    

    I've added the normal [Parameters] that you use with NavLink to your component so you can pass them through.

    If you want to see how the RenderTreeBuilder contructs it find the nnn.g.cs file in obj/debug/net5.0/razor