How to make menu item color change after click in Blazor app with Tailwind CSS

Viewed 4634

I've started building Blazor server app with Tailwind CSS. I created horizontal menu nav bar with new styles. But one thing I missed. In default Blazor template when I click on menu item, it changes background color, till click to other menu element or changing route component page - then that page menu element changes color, other elements return to default background. I know it is not doing by default bootstrap CSS or site.css. And in code I can't find it. Is it done in <script src="_framework/blazor.server.js"></script> in _Host.cshtml?

I've tried a few solutions as this two NavLinks:

        ...
        <ul class="@($"{menuVisibleClass} flex flex-col bg-gray-400 px-4 py-2 md:flex md:flex-row md:bg-transparent")">
            <NavLink @onclick="ToggleActive" class="@($"nav-item {activeClass}" )"  href="/">Home</NavLink>
            <NavLink class="@($"nav-item focus:bg-purple-400")" tabindex="-1" href="/fetchdata">Counter</NavLink>      
        </ul>
    </div>
    
    @code
    {
        ...
        private bool _active = false;
        string activeClass = "";
    
        private void ToggleActive()
        {
            _active = !_active;
            activeClass = _active ? " bg-purple-400" : "";
        }
        ...
    }

But of course it is not it. I think it should be something like this in JavaScript (w3schools link):

       <div id="myDIV">
          <button class="btn">1</button>
          <button class="btn active">2</button>
          <button class="btn">3</button>
        </div>
        
        <script>
        var header = document.getElementById("myDIV");
        var btns = header.getElementsByClassName("btn");
        for (var i = 0; i < btns.length; i++) {
          btns[i].addEventListener("click", function() {
          var current = document.getElementsByClassName("active");
          current[0].className = current[0].className.replace(" active", "");
          this.className += " active";
          });
        }
        </script>

Is there something simmilar to achieve that? Should I pass manually id from onclick event of every NAvLink or maybe other solution would be proper?

edit: I found info (link) that with Bootstrap NavLink toggles an active CSS class based on whether its href matches the current URL. But with active class generated by Tailwind CSS I can't do it.

@tailwind base;
@tailwind components;

.nav-item {
    @apply bg-gray-100 m-1 font-bold text-gray-700 px-4 py-2 rounded-sm shadow-lg;
}
.nav-item:hover {
    @apply bg-purple-300;
}
.nav-item:focus {
    @apply outline-none;
}

.nav-item:active {
    @apply bg-purple-500;
}
2 Answers

In blazor the template does this with the NavLink component. The NavLink component places a class on the anchor object when it is being rendered based on weather the current navigation location starts with or is equal to the href.

In your case if the route is active you simply want to put and active class on the element.

<div id="myDIV">
          <button class="btn @GetActive("path1")">1</button>
          <button class="btn @GetActive("path2")">2</button>
          <button class="btn @GetActive("path3")">3</button>
</div>

@code {

    [Inject]
    NavigationManager NavigationManager { get; set; }

    protected override void OnInitialized() => NavigationManager.LocationChanged += (s, e) => StateHasChanged();

    bool IsActive(string href, NavLinkMatch navLinkMatch = NavLinkMatch.Prefix)
    {
        var relativePath = NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLower();
        return navLinkMatch == NavLinkMatch.All ? relativePath == href.ToLower() : relativePath.StartsWith(href.ToLower());
    }

    string GetActive(string href, NavLinkMatch navLinkMatch = NavLinkMatch.Prefix) => IsActive(href, navLinkMatch) ? "active" : "";
}

Blazor "translate a navLink to a simple link", so can define some like

a.active{@apply bg-purple-500}

Or your

.nav-item.active{@apply bg-purple-500}

Or use ActiveClass and use

.customActiveClass{@apply bg-purple-500}

But I can not imagine how use pseudoclass :active of tailwinds

Related