Tabs

Simple Tab

Tab One
Tab Two
Tab Three
Tab Disabled

Content One

<MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-6">
    <MudTabPanel Text="Tab One">
        <MudText>Content One</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Tab Two">
        <MudText>Content Two</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Tab Three">
        <MudText>Content Three</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Tab Disabled" Disabled="true">
        <MudText>Content Disabled</MudText>
    </MudTabPanel>
</MudTabs>
Centered

Use the Centered prop to keep your tabs in the middle.

One
Two
Three
<MudTabs Elevation="4" Rounded="true" Centered="true" Color="@Color.Primary">
    <MudTabPanel Text="One"/>
    <MudTabPanel Text="Two"/>
    <MudTabPanel Text="Three"/>
</MudTabs>
Scrolling Tabs

If the total size of all tabs exceeds the total size of the tabs container, buttons will be added for scrolling.
With the AlwaysShowScrollButtons prop, you can display the scroll buttons at all time.

One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Thirteen
One
Two
Three
<MudTabs Elevation="4" Rounded="true" Color="@Color.Secondary">
    <MudTabPanel Text="One" />
    <MudTabPanel Text="Two" />
    <MudTabPanel Text="Three" />
    <MudTabPanel Text="Four" />
    <MudTabPanel Text="Five" />
    <MudTabPanel Text="Six" />
    <MudTabPanel Text="Seven" />
    <MudTabPanel Text="Eight" />
    <MudTabPanel Text="Nine" />
    <MudTabPanel Text="Ten" />
    <MudTabPanel Text="Eleven" />
    <MudTabPanel Text="Thirteen" />
</MudTabs>

<MudTabs Elevation="4" Rounded="true" AlwaysShowScrollButtons="true" Color="@Color.Info" Class="mt-4">
    <MudTabPanel Text="One" />
    <MudTabPanel Text="Two" />
    <MudTabPanel Text="Three" />
</MudTabs>
Custom Scroll Icons

The icons can be changed with the PrevIcon and NextIcon properties.

One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Thirteen
<MudTabs Elevation="4" Rounded="true" Color="@Color.Success" PrevIcon="@Icons.Material.Filled.SkipPrevious" NextIcon="@Icons.Material.Filled.SkipNext">
    <MudTabPanel Text="One" />
    <MudTabPanel Text="Two" />
    <MudTabPanel Text="Three" />
    <MudTabPanel Text="Four" />
    <MudTabPanel Text="Five" />
    <MudTabPanel Text="Six" />
    <MudTabPanel Text="Seven" />
    <MudTabPanel Text="Eight" />
    <MudTabPanel Text="Nine" />
    <MudTabPanel Text="Ten" />
    <MudTabPanel Text="Eleven" />
    <MudTabPanel Text="Thirteen" />
</MudTabs>
Tabs Position

The position of the tab toolbar can be changed with the Position property.

Item One
Item Two
Item Three

Content One

<MudSelect Variant="Variant.Outlined" Label="Tabs Position" Dense="true" Margin="Margin.Dense" T="@Position" @bind-Value="Position">
    <MudSelectItem T="Position" Value="@Position.Top">Top</MudSelectItem>
    <MudSelectItem T="Position" Value="@Position.Start">Start</MudSelectItem>
    <MudSelectItem T="Position" Value="@Position.Left">Left</MudSelectItem>
    <MudSelectItem T="Position" Value="@Position.Right">Right</MudSelectItem>
    <MudSelectItem T="Position" Value="@Position.End">End</MudSelectItem>
    <MudSelectItem T="Position" Value="@Position.Bottom">Bottom</MudSelectItem>
</MudSelect>

<MudTabs Outlined="true" Position="@Position" Rounded="true" Border="true"
    ApplyEffectsToContainer="true" Class="mt-8" PanelClass="pa-6">
    <MudTabPanel Text="Item One">
        <MudText>Content One</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Item Two">
        <MudText>Content Two</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Item Three">
        <MudText>Content Three</MudText>
    </MudTabPanel>
</MudTabs>
@code {
    public Position Position { get; set; } = Position.Left;

    private void OnSelectedValue(Position value)
    {
        switch (value)
        {
            case Position.Top:
                Position = Position.Top;
                break;
            case Position.Start:
                Position = Position.Start;
                break;
            case Position.Left:
                Position = Position.Left;
                break;
            case Position.Right:
                Position = Position.Right;
                break;
            case Position.End:
                Position = Position.End;
                break;
            case Position.Bottom:
                Position = Position.Bottom;
                break;
        }
    }
}
Icon Tabs

Icons can be used in addition to regular text in the tabs.

Api
Bug Report
<MudTabs Outlined="true">
    <MudTabPanel Text="Api" Icon="@Icons.Material.Filled.Api"/>
    <MudTabPanel Icon="@Icons.Material.Filled.Build"/>
    <MudTabPanel Text="Bug Report" Icon="@Icons.Material.Filled.BugReport"/>
</MudTabs>
Minimum Tab Width

The minimum tab width can be set by specifying a css width against the MinimumTabWidth property.

Api
Api
<MudStack>
    <MudTabs Outlined="true" MinimumTabWidth="20px">
        <MudTabPanel Icon="@Icons.Material.Filled.Build" />
        <MudTabPanel Text="Api" Icon="@Icons.Material.Filled.Api" />
        <MudTabPanel Icon="@Icons.Material.Filled.Settings" />
    </MudTabs>


    <MudTabs Outlined="true" MinimumTabWidth="20px" Position="Position.Left">
        <MudTabPanel Icon="@Icons.Material.Filled.Build" />
        <MudTabPanel Text="Api" Icon="@Icons.Material.Filled.Api" />
        <MudTabPanel Icon="@Icons.Material.Filled.Settings" />
    </MudTabs>
</MudStack>
Badges

Badges can be be applied to both icons and texts in the same way.

live
...
99+
API!
Build1
Bugs0
Timing
APIS
Build...
BugsN
Timing
<MudTabs Elevation="2" Rounded="true" Centered="true">
    <MudTabPanel Icon="@Icons.Material.Filled.Api" BadgeData='"live"' BadgeColor="Color.Info" />
    <MudTabPanel Icon="@Icons.Material.Filled.Build" BadgeData='"..."' />
    <MudTabPanel Icon="@Icons.Material.Filled.BugReport" BadgeData='"99+"' BadgeColor="Color.Error" />
    <MudTabPanel Icon="@Icons.Material.Filled.AccessTime" BadgeData='string.Empty' BadgeDot="true" BadgeColor="Color.Success" />
</MudTabs>

<MudTabs Elevation="2" Rounded="true" Centered="true" Class="my-6" Color="Color.Dark">
    <MudTabPanel Icon="@Icons.Material.Filled.Api" Text="API" BadgeData='"!"' BadgeColor="Color.Error" />
    <MudTabPanel Icon="@Icons.Material.Filled.Build" Text="Build" BadgeData="1" BadgeColor="Color.Success" />
    <MudTabPanel Icon="@Icons.Material.Filled.BugReport" Text="Bugs" BadgeData="0" />
    <MudTabPanel Icon="@Icons.Material.Filled.AccessTime" Text="Timing" BadgeDot="true" BadgeColor="Color.Error" />
</MudTabs>

<MudTabs Elevation="2" Rounded="true" Centered="true">
    <MudTabPanel Text="API" BadgeData='"S"' />
    <MudTabPanel Text="Build" BadgeData='"..."' BadgeColor="Color.Dark" />
    <MudTabPanel Text="Bugs" BadgeData='"N"' />
    <MudTabPanel Text="Timing" BadgeDot="true" BadgeColor="Color.Primary" />
</MudTabs>
Tooltip Tabs
Item One
Item Two
Item Three

Item One

<MudTabs Elevation="1" Rounded="true" PanelClass="pa-6">
    <MudTabPanel Text="Item One" ToolTip="ToolTip One">
        <MudText>Item One</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Item Two" ToolTip="ToolTip Two">
        <MudText>Item Two</MudText>
    </MudTabPanel>
    <MudTabPanel Text="Item Three" ToolTip="ToolTip Three">
        <MudText>Item Three</MudText>
    </MudTabPanel>
</MudTabs>
Tab Content

Custom tab header content can be provided for special scenarios. Specify only TabContent to customize the tab content, or specify TabWrapperContent to provide a wrapper around the entire tab header.

Item One
Item Two
Item Three

Custom tab content only

<MudTabs Elevation="1" Rounded="true" PanelClass="pa-6">
    <MudTabPanel>
        <ChildContent>
            <MudText>Custom tab content only</MudText>
        </ChildContent>
        <TabContent>
            Item One
        </TabContent>
    </MudTabPanel>
    <MudTabPanel>
        <ChildContent>
            <MudText>Both custom tab and wrapper content</MudText>
        </ChildContent>
        <TabWrapperContent>
            <MudTooltip Text="ToolTip Two">
                @context
            </MudTooltip>
        </TabWrapperContent>
        <TabContent>
            <MudText Typo="Typo.h6">Item Two</MudText>
        </TabContent>
    </MudTabPanel>
    <MudTabPanel Text="Item Three">
        <ChildContent>
            <MudText>Custom wrapper content only</MudText>
        </ChildContent>
        <TabWrapperContent>
            <MudTooltip Text="ToolTip Three">
                @context
            </MudTooltip>
        </TabWrapperContent>
    </MudTabPanel>
</MudTabs>
Set Active Panel
One
Two
Three

Set Active by Index

Set Active by Instance

Set Active by TabPanel ID

<MudTabs Elevation="1" Rounded="true" @ref="tabs">
    <MudTabPanel Text="One" @ref="panel01" ID="@("pn_one")" />
    <MudTabPanel Text="Two" @ref="panel02" ID="@("pn_two")" />
    <MudTabPanel Text="Three" @ref="panel03" ID="@("pn_three")" />
</MudTabs>


<MudText GutterBottom="true" Align="Align.Center" Class="mt-8"><b>Set Active by Index</b></MudText>
<div class="d-flex justify-center">
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick="() => Activate(0)">Index 0</MudButton>
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick="() => Activate(1)" Class="mx-2">Index 1</MudButton>
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick="() => Activate(2)">Index 2</MudButton>
</div>
<MudText GutterBottom="true" Align="Align.Center" Class="mt-4"><b>Set Active by Instance</b></MudText>
<div class="d-flex justify-center">
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick="() => Activate(panel01)">Item One</MudButton>
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick="() => Activate(panel02)" Class="mx-2">Item Two</MudButton>
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick="() => Activate(panel03)">Item Three</MudButton>
</div>
<MudText GutterBottom="true" Align="Align.Center" Class="mt-4"><b>Set Active by TabPanel ID</b></MudText>
<div class="d-flex justify-center">
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick='() => Activate("pn_one")'>Item One</MudButton>
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick='() => Activate("pn_two")' Class="mx-2">Item Two</MudButton>
    <MudButton Variant="@Variant.Filled" Color="Color.Primary" OnClick='() => Activate("pn_three")'>Item Three</MudButton>
</div>
@code {
    MudTabs tabs;
    MudTabPanel panel01;
    MudTabPanel panel02;
    MudTabPanel panel03;

    void Activate(int index)
    {
        tabs.ActivatePanel(index);
    }

    void Activate(MudTabPanel panel)
    {
        tabs.ActivatePanel(panel);
    }

    void Activate(object id)
    {
        tabs.ActivatePanel(id);
    }
}
Binding Selected Panel
Item One
Item Two
Item Three

Active Index: 2

<MudTabs Elevation="0" Outlined="true" @bind-ActivePanelIndex="activeIndex">
    <MudTabPanel Text="Item One" ID='"pn_one"'></MudTabPanel>
    <MudTabPanel Text="Item Two" ID='"pn_two"'></MudTabPanel>
    <MudTabPanel Text="Item Three" ID='"pn_three"'></MudTabPanel>
</MudTabs>
<MudText>@($"Active Index: {activeIndex}")</MudText>
@code
 { 
    int activeIndex = 2;
}
Simple Dynamic Tabs

A browser like tab experience, where users can add new tabs and close existing ones. Add and Close needs to be provided as callbacks.
To hide the close icon, set ShowCloseIcon = false

Tab A
Tab B
Tab C
Tab B content

UserTabs index: 1 / DynamicTabs ActivePanelIndex: 1

UserTabs.Count: 3 / DynamicTabs Panels.Count: 0

<MudDynamicTabs @ref="@DynamicTabs" @bind-ActivePanelIndex="@UserIndex"
                AddTab="@AddTabCallback" CloseTab="@CloseTabCallback"
                AddIconToolTip="Click to add a new tab" CloseIconToolTip="Close tab. All data will be lost"
                PanelClass="px-4 py-6" Elevation="4" Rounded ApplyEffectsToContainer>
    @foreach (var tab in UserTabs)
    {
        <MudTabPanel ID="@tab.Id" Text="@tab.Label" ShowCloseIcon="@tab.ShowCloseIcon">@tab.Content</MudTabPanel>
    }
</MudDynamicTabs>
<MudButton OnClick="@RestoreUserTabs">Restore</MudButton>
<MudSwitch T="bool" Color="Color.Primary" Checked="@_showCloseIcon" CheckedChanged="@ToggleShowCloseIcon">@($"Show {_closeToggableTab}'s close icon")</MudSwitch>
<MudText>UserTabs index: @UserIndex / DynamicTabs ActivePanelIndex: @DynamicTabs.ActivePanelIndex</MudText>
<MudText>UserTabs.Count: @UserTabs.Count / DynamicTabs Panels.Count: @DynamicTabs.Panels.Count</MudText>
@code {

    public class TabView
    {
        public string Label { get; set; }
        public string Content { get; set; }
        public Guid Id { get; set; }
        public bool ShowCloseIcon { get; set; } = true;
    }

    public MudDynamicTabs DynamicTabs;
    public List<TabView> UserTabs = new();
    public int UserIndex;
    bool _stateHasChanged;
    bool _showCloseIcon = false;
    string _closeToggableTab = "Tab B";

    void RestoreUserTabs()
    {
        UserTabs.Clear();
        UserTabs.Add(new TabView {Id = Guid.NewGuid(), Label = "Tab A", Content = "Tab A content"});
        UserTabs.Add(new TabView {Id = Guid.NewGuid(), Label = _closeToggableTab, Content = $"{_closeToggableTab} content", ShowCloseIcon = _showCloseIcon });
        UserTabs.Add(new TabView {Id = Guid.NewGuid(), Label = "Tab C", Content = "Tab C content"});
        UserIndex = 1; // Start on 2nd tab: "Tab B"
        _stateHasChanged = true;
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();
        RestoreUserTabs();
    }

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (_stateHasChanged)
        {
            _stateHasChanged = false;
            StateHasChanged();
        }
    }

    private void ToggleShowCloseIcon(bool show)
    {
        var tab = UserTabs?.SingleOrDefault(t => t.Label.Equals(_closeToggableTab));
        if (tab is not null) tab.ShowCloseIcon = show;
        _showCloseIcon = show;
    }

    public void AddTab(Guid id)
    {
        UserTabs.Add(new TabView {Id = id, Label = "dynamic tab", Content = $"Tab ID: {id}"});
        UserIndex = UserTabs.Count - 1; // Automatically switch to the new tab.
        _stateHasChanged = true;
    }

    public void RemoveTab(Guid id)
    {
        var tabView = UserTabs.SingleOrDefault((t) => Equals(t.Id, id));
        if (tabView is not null)
        {
            UserTabs.Remove(tabView);
            _stateHasChanged = true;
        }
    }

    void AddTabCallback() => AddTab(Guid.NewGuid());
    void CloseTabCallback(MudTabPanel panel) => RemoveTab((Guid)panel.ID);
}
Advanced Dynamic Tabs

Allthough MudDynamicTabs allows a basic browser like tab experience, the way the style can be influenced is limited

The Property Header and TabPanelHeader allows you to add any RenderFragement to the tab (Header) and to each tab panel (TabPanelHeader). The placement can be influenced by setting values to HeaderPosition or TabPanelHeaderPosition

Tab A
Tab B
Tab C
First tab content
<MudTabs @bind-ActivePanelIndex="_index" Border="true" Outlined="true" PanelClass="px-4 py-6" ApplyEffectsToContainer="true">
	<ChildContent>
		@foreach (var item in _tabs)
		{
			 <MudTabPanel Text="@item.Name" Tag="@item.Id">@item.Content</MudTabPanel>
		}
	</ChildContent>
	<Header>
		<MudButtonGroup>
			<MudTooltip Text="Prepend a tab">
				<MudIconButton Icon="@Icons.Material.Filled.ChevronLeft" OnClick="@( () => AddTabCallback(false) )" />
			</MudTooltip>
			<MudTooltip Text="Append a tab">
				<MudIconButton Icon="@Icons.Material.Filled.ChevronRight" OnClick="@( () => AddTabCallback(true) )"  />
			</MudTooltip>
		</MudButtonGroup>
	</Header>
	<TabPanelHeader>
		@if(context.Text.StartsWith("Tab") == false)
		{
			<MudTooltip Text="only dynamic tabs can be closed">
				<MudIconButton Class="ml-2 pa-1" Color="Color.Error" Icon="@Icons.Material.Filled.Remove" OnClick="(_) => RemoveTab(context)" />
			</MudTooltip>
		}
  </TabPanelHeader>
</MudTabs>
@code {

	private class TabView
	{
		public String Name { get; set; }
		public String Content { get; set; }
		public Guid Id { get; set; }
	}

	private List<TabView> _tabs = new();
	private int _index = 0;
	private int? _nextIndex = null;

	private void RemoveTab(MudTabPanel tabPanel)
	{
		var tab = _tabs.FirstOrDefault(x => x.Id == (Guid)tabPanel.Tag);
		if(tab != null)
		{
			_tabs.Remove(tab);
		}
	}

	protected override void OnInitialized()
	{
		base.OnInitialized();

		_tabs.Add(new TabView { Content = "First tab content", Name = "Tab A", Id = Guid.NewGuid() });
		_tabs.Add(new TabView { Content = "Second tab content", Name = "Tab B", Id = Guid.NewGuid() });
		_tabs.Add(new TabView { Content = "Third tab content", Name = "Tab C", Id = Guid.NewGuid() });
	}

	private void AddTabCallback(Boolean append)
	{
		var tabView = new TabView { Name = "Dynamic content", Content = "A new tab", Id = Guid.NewGuid() };
		
		//the tab becomes available after it is rendered. Hence, we can't set the index here
		if(append == true)
		{
			_tabs.Add(tabView);
			_nextIndex = _tabs.Count - 1;
		}
		else
		{
			_tabs.Insert(0, tabView);
			_nextIndex = 0;
		}
	}

	protected override void OnAfterRender(bool firstRender)
	{
		if(_nextIndex.HasValue == true)
		{
			_index = _nextIndex.Value;
			_nextIndex = null;
			StateHasChanged();
		}
	}
}

Copyright © 2020-2024 MudBlazor.

Powered by .NET 8.0.3

An unhandled error has occurred. Reload 🗙