In this new post, I explain how to create and use Tabs control for Blazor Web Assembly and Blazor Server. You have the full code of this component on GitHub.
As I explained in my previous post Segment Control For Blazor, the first thing I have to do is to creating 2 new Razor Class Library
in Visual Studio and named them as Tabs
and Tab
.
Definition of Tab
First, we have to define a child of the Tabs container. In one Razor Class Library
, change the name to Tab.razor
.
@if (Parent.ActivePage == this)
{
@ChildContent
}
@code {
[CascadingParameter]
private Tabs Parent { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public string Text { get; set; }
[Parameter]
public string Value { get; set; }
[Parameter]
public bool Enabled { get; set; } = true;
protected override void OnInitialized()
{
if (Parent == null)
throw new ArgumentNullException(nameof(Parent),
"TabPage must exist within a TabControl");
base.OnInitialized();
Parent.AddPage(this);
}
}
So, when I define a new Tab I should pass those parameters:
- Text is the label you want to show to the user
- Value is the real value you want to use
- Enabled allows the user to click on this tab or not
Then, the OnInitialized()
checks if there is a parent and add this tab to the list present in the tabs container. If this tab is the active one, the component shows the content.
Tabs container
So, the Tabs container contains all the tabs to display.
<CascadingValue Value="this">
<div class="tabs">
<div class="tab-container">
<div class="tab-filling tab-filling-left">
@((MarkupString)TextFilling1)
</div>
@foreach (Tab tabPage in Pages)
{
<div class="tab @GetTabCSS(tabPage)" @onclick=@( () => ActivatePage(tabPage) )>
@tabPage.Text
</div>
}
<div class="tab-filling tab-filling-right">
@((MarkupString)TextFilling2)
</div>
</div>
<div class="tab-content">
@ChildContent
</div>
</div>
</CascadingValue>
Now, I have to add the code to the page.
@code {
[Parameter] public string TextFilling1 { get; set; }
[Parameter] public string TextFilling2 { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; }
[Parameter] public EventCallback<Tab> OnTabChanged { get; set; }
public Tab ActivePage { get; set; }
List<Tab> Pages = new List<Tab>();
internal void AddPage(Tab tabPage)
{
Pages.Add(tabPage);
if (Pages.Count == 1)
ActivePage = tabPage;
StateHasChanged();
}
string GetTabCSS(Tab page)
{
if (!page.Enabled)
return "tab-disabled";
return page == ActivePage ? "tab-active" : "";
}
void ActivatePage(Tab page)
{
if (page.Enabled)
{
ActivePage = page;
OnTabChanged.InvokeAsync(page);
}
}
}
So, in the next section I show all the attributes and events we can use.
Anatomy of Tabs
Tabs container attributes
Attribute | Description |
---|---|
TextFilling1 | This text is displayed on the left hand side of the tabs |
TextFilling2 | This text is displayed on the right hand side of the tabs |
Tabs container events
Also, Tabs
has the following events that you can use.
Event | Description |
---|---|
OnTabChanged | When the use click on a new tab, this event is raised. So, you can attach a function to read the new tab object |
Tab attributes
Attribute | Description |
---|---|
Text | The text to display in the tab |
Value | The value associate to a tab (useful if you have to filter your data) |
Enabled | Is this tab enabled? If not the user can’t click on it. By default is True |
How to use it?
First, add the NuGet package in your project. The name of the package is PSC.Blazor.Components.Tabs and the only dependency it has is Microsoft.AspNetCore.Components.Web (>= 5.0.10).
After that, in your wwwroot\index.html
or in the hosts file, you have to add a theme (CSS) for your segment control. Obviously, you can create your own theme. So, use this code:
<link href="_content/PSC.Blazor.Components.Tabs/themes/{theme-name}.css" rel="stylesheet" />
Example
<Tabs TextFilling1="@text1" TextFilling2="@text2" OnTabChanged="OnTabChanged">
<Tab Text="Tab 1" Value="Tab1">
<h2>Content Tab 1</h2>
<p>
This is the content for the Tab 1. It is enabled.
</p>
</Tab>
<Tab Text="Tab 2" Value="Tab2">
<h2>Content Tab 2</h2>
<p>
This is the content for the Tab 2. It is enabled.
</p>
</Tab>
<Tab Text="Tab 3" Value="Tab3">
<h2>Content Tab 3</h2>
<p>
This is the content for the Tab 3. It is enabled.
</p>
</Tab>
<Tab Text="Tab 4" Enabled="@IsEnabled" Value="Tab4">
<h2>Content Tab 4</h2>
<p>
This is the content for the Tab 4. It is disabled if <i>IsEnabled = false</i>
</p>
</Tab>
</Tabs>
@code {
public string text1 = "Text on the left";
public string text2 = "Text on the right";
public bool IsEnabled = false;
public async Task OnTabChanged(Tab tab)
{
text1 = $"Tab value: {tab.Value}";
text2 = $"Tab text: {tab.Text}";
}
}
Themes
Blue
Green
Red
Wrap up
So, now we have a nice and simple Tabs control for Blazor to use in our projects. If you have any comment please add it at the bottom of this post or use the Forum.