Simple Tab
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.
<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.
<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.
<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 bar can be changed with the Position
property.
Content One
<MudSelect Variant="Variant.Outlined" Label="Tabs Position" Dense="true" Margin="Margin.Dense" T="" @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="" 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.
<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.
<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.
<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
<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>
Customization
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. The header of the active tab can be customized using ActiveTabClass
.
Custom tab content only
<MudTabs Elevation="1" Rounded="true" PanelClass="pa-6" ActiveTabClass="border-solid border-2 mud-border-primary"> <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
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
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
UserTabs index: 1 / DynamicTabs ActivePanelIndex: 1
UserTabs.Count: 3 / DynamicTabs Panels.Count: 3
<MudDynamicTabs @ref="" @bind-ActivePanelIndex="" AddTab="" CloseTab="" 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="">Restore</MudButton> <MudSwitch T="bool" Color="Color.Primary" Value="@_showCloseIcon" ValueChanged="">@($"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
Although 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 RenderFragment to the tab (Header) and to each tab panel (TabPanelHeader). The placement can be influenced by setting values to HeaderPosition or TabPanelHeaderPosition
<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(); } } }