Repository: MudBlazor/MudBlazor (2026-03-31T00:06:59Z)

Issue:
Add property Disabled to MudTabs
### Feature request type

Enhance component

### Component name

MudTabs

### Is your feature request related to a problem?

I want to disable all MudTabPanels of one MudTabs Component, but the parents does not have such a property. Instead I have to set this property on all child MudTabPanels.

### Describe the solution you'd like

Create a new property Disabled on MudTabs that gets cloned to the child MudTabPanels

### Have you seen this feature anywhere else?

_No response_

### Describe alternatives you've considered

Workaround is to set the Disabled property on all children

### Pull Request

- [ ] I would like to do a Pull Request

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct


Discussion:

Patch:
diff --git a/src/MudBlazor/Components/Tabs/MudTabs.razor b/src/MudBlazor/Components/Tabs/MudTabs.razor
index a95418b36401..621dd9dcd62b 100644
--- a/src/MudBlazor/Components/Tabs/MudTabs.razor
+++ b/src/MudBlazor/Components/Tabs/MudTabs.razor
@@ -26,7 +26,7 @@
                     {
                         <MudDropContainer @ref="_dropContainer" T="MudTabPanel" Class="@WrapperClassnames" Style="@WrapperScrollStyle" Items="_panels"
                                           ItemsSelector="@((item,dropzone) => true)" ItemDropped="@ItemUpdated"
-                                          ItemDisabled="@((item) => item.Disabled)" role="tablist">
+                                          ItemDisabled="@((item) => Disabled || item.Disabled)" role="tablist">
                             <ChildContent>
                                 <MudDropZone T="MudTabPanel" Identifier="mud-tabs-dropzone" Class="@DropZoneClassnames" AllowReorder="true" />
                                 @if (!HideSlider && _isSliderPositionDetermined)
diff --git a/src/MudBlazor/Components/Tabs/MudTabs.razor.cs b/src/MudBlazor/Components/Tabs/MudTabs.razor.cs
index 0a15c9f33b48..a93ded12d0c5 100644
--- a/src/MudBlazor/Components/Tabs/MudTabs.razor.cs
+++ b/src/MudBlazor/Components/Tabs/MudTabs.razor.cs
@@ -97,6 +97,16 @@ public partial class MudTabs : MudComponentBase, IAsyncDisposable
         [Category(CategoryTypes.Tabs.Behavior)]
         public bool KeepPanelsAlive { get; set; }
 
+        /// <summary>
+        /// Disables user interaction for all tab panels.
+        /// </summary>
+        /// <remarks>
+        /// Defaults to <c>false</c>.
+        /// </remarks>
+        [Parameter]
+        [Category(CategoryTypes.Tabs.Behavior)]
+        public bool Disabled { get; set; }
+
         /// <summary>
         /// Uses rounded corners on the tab's edges.
         /// </summary>
@@ -648,7 +658,7 @@ internal async Task RemovePanel(MudTabPanel tabPanel)
             _panels.RemoveAt(index);
 
             // no panels left that are visible and not disabled
-            if (!_panels.Any(x => x.Visible && !x.Disabled))
+            if (!_panels.Any(x => x.Visible && !IsPanelDisabled(x)))
             {
                 await _activePanelIndexState.SetValueAsync(-1);
             }
@@ -687,19 +697,19 @@ internal async Task RemovePanel(MudTabPanel tabPanel)
             // Clamp starting point
             startIndex = Math.Clamp(startIndex, 0, _panels.Count - 1);
             // If the provided index is good stop here.
-            if (_panels[startIndex] is { Visible: true, Disabled: false })
+            if (_panels[startIndex].Visible && !IsPanelDisabled(_panels[startIndex]))
                 return startIndex;
 
             // Search to the left
             for (int i = startIndex; i >= 0; i--)
             {
-                if (_panels[i].Visible && !_panels[i].Disabled)
+                if (_panels[i].Visible && !IsPanelDisabled(_panels[i]))
                     return i;
             }
             // Search to the right
             for (int i = startIndex + 1; i < _panels.Count; i++)
             {
-                if (_panels[i].Visible && !_panels[i].Disabled)
+                if (_panels[i].Visible && !IsPanelDisabled(_panels[i]))
                     return i;
             }
             return null;
@@ -753,7 +763,7 @@ public async Task ActivatePanelAsync(MudTabPanel? panel, bool ignoreDisabledStat
             {
                 await _activePanelIndexState.SetValueAsync(-1);
             }
-            else if (panel.Visible && (!panel.Disabled || ignoreDisabledState))
+            else if (panel.Visible && (!IsPanelDisabled(panel) || ignoreDisabledState))
             {
                 var index = _panels.IndexOf(panel);
                 var previewArgs = new TabInteractionEventArgs
@@ -903,7 +913,7 @@ private string GetTabClass(MudTabPanel panel)
         {
             var tabClass = new CssBuilder("mud-tab")
               .AddClass($"mud-tab-active", when: () => panel == ActivePanel)
-              .AddClass($"mud-disabled", panel.Disabled)
+              .AddClass($"mud-disabled", IsPanelDisabled(panel))
               .AddClass($"mud-ripple", Ripple)
               .AddClass(ActiveTabClass, when: () => panel == ActivePanel)
               .AddClass(TabButtonsClass)
@@ -936,7 +946,7 @@ private string GetTabStyle(MudTabPanel panel)
 
         private Color GetPanelIconColor(MudTabPanel panel)
         {
-            if (panel.Disabled)
+            if (IsPanelDisabled(panel))
             {
                 return Color.Inherit;
             }
@@ -949,6 +959,8 @@ private Color GetPanelIconColor(MudTabPanel panel)
             return IconColor;
         }
 
+        private bool IsPanelDisabled(MudTabPanel panel) => Disabled || panel.Disabled;
+
         #endregion
 
         #region Rendering and placement
@@ -1329,7 +1341,7 @@ private async Task HandleKeyInterceptorAsync(KeyboardEventArgs e)
         /// </summary>
         private async Task MoveFocusToPreviousTab(MudTabPanel currentPanel)
         {
-            var enabledPanels = _panels.Where(p => !p.Disabled).ToList();
+            var enabledPanels = _panels.Where(p => !IsPanelDisabled(p)).ToList();
             if (enabledPanels.Count <= 1) return;
 
             var currentIndex = enabledPanels.IndexOf(currentPanel);
@@ -1344,7 +1356,7 @@ private async Task MoveFocusToPreviousTab(MudTabPanel currentPanel)
         /// </summary>
         private async Task MoveFocusToNextTab(MudTabPanel currentPanel)
         {
-            var enabledPanels = _panels.Where(p => !p.Disabled).ToList();
+            var enabledPanels = _panels.Where(p => !IsPanelDisabled(p)).ToList();
             if (enabledPanels.Count <= 1) return;
 
             var currentIndex = enabledPanels.IndexOf(currentPanel);


Test patch:
diff --git a/src/MudBlazor.UnitTests.Viewer/TestComponents/Tabs/TabsDisabledTest.razor b/src/MudBlazor.UnitTests.Viewer/TestComponents/Tabs/TabsDisabledTest.razor
new file mode 100644
index 000000000000..b11d5fb6d1dc
--- /dev/null
+++ b/src/MudBlazor.UnitTests.Viewer/TestComponents/Tabs/TabsDisabledTest.razor
@@ -0,0 +1,9 @@
+﻿<MudTabs Disabled="@Disabled" TabButtonsClass="test-tab-button">
+    <MudTabPanel Text="One">One</MudTabPanel>
+    <MudTabPanel Text="Two">Two</MudTabPanel>
+</MudTabs>
+
+@code {
+    [Parameter]
+    public bool Disabled { get; set; } = true;
+}
diff --git a/src/MudBlazor.UnitTests/Components/TabsTests.cs b/src/MudBlazor.UnitTests/Components/TabsTests.cs
index e9766ed72d82..a021f624274d 100644
--- a/src/MudBlazor.UnitTests/Components/TabsTests.cs
+++ b/src/MudBlazor.UnitTests/Components/TabsTests.cs
@@ -984,6 +984,24 @@ public void ActivatePanels_EvenWhenDisabled()
             }
         }
 
+        [Test]
+        public async Task TabsDisabled_DisablesAllPanelsAndPreventsActivation()
+        {
+            var comp = Context.Render<TabsDisabledTest>();
+
+            IReadOnlyList<IElement> Panels() => comp.FindAll(".test-tab-button");
+
+            Panels().Should().HaveCount(2);
+            Panels()[0].ClassList.Contains("mud-tab-active").Should().BeTrue();
+            Panels()[0].ClassList.Contains("mud-disabled").Should().BeTrue();
+            Panels()[1].ClassList.Contains("mud-disabled").Should().BeTrue();
+
+            await Panels()[1].ClickAsync();
+
+            Panels()[0].ClassList.Contains("mud-tab-active").Should().BeTrue();
+            Panels()[1].ClassList.Contains("mud-tab-active").Should().BeFalse();
+        }
+
         [Test]
         public void SelectedIndex_Binding()
         {