diff --git a/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml b/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml index 1cf9d13a5..9693cc9fd 100644 --- a/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml +++ b/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml @@ -27,7 +27,7 @@ - + @@ -106,7 +106,7 @@ Text="{Binding Data.Tab3Count}" /> - + @@ -182,7 +182,7 @@ - + @@ -265,6 +265,7 @@ + @@ -337,6 +338,7 @@ + @@ -352,6 +354,47 @@ AutomationProperties.AutomationId="M3_Tab3_Count" Text="{Binding Data.Tab3Count}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -591,6 +634,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -677,6 +761,7 @@ + @@ -747,8 +832,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -757,7 +883,7 @@ - + diff --git a/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml.cs b/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml.cs index c34d65c20..b8812feb0 100644 --- a/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml.cs +++ b/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/TabBarSamplePage.xaml.cs @@ -8,6 +8,7 @@ using Uno.Toolkit.Samples.Content.NestedSamples; using Uno.Toolkit.Samples.Entities; using Uno.Toolkit.Samples.ViewModels; +using Uno.Toolkit.UI; using Windows.Foundation; using Windows.Foundation.Collections; @@ -74,43 +75,46 @@ private void ShowM3MaterialVerticalBarSampleInNestedFrame(object sender, RoutedE public class TabBarViewModel : ViewModelBase { - public int Tab1Count { get => GetProperty(); set => SetProperty(value); } - public int Tab2Count { get => GetProperty(); set => SetProperty(value); } - public int Tab3Count { get => GetProperty(); set => SetProperty(value); } + public int Tab1Count { get => GetProperty(); set => SetProperty(value); } + public int Tab2Count { get => GetProperty(); set => SetProperty(value); } + public int Tab3Count { get => GetProperty(); set => SetProperty(value); } - public int MaterialBottomTab1Count { get => GetProperty(); set => SetProperty(value); } - public int MaterialBottomTab2Count { get => GetProperty(); set => SetProperty(value); } - public int MaterialBottomTab3Count { get => GetProperty(); set => SetProperty(value); } + public int MaterialBottomTab1Count { get => GetProperty(); set => SetProperty(value); } + public int MaterialBottomTab2Count { get => GetProperty(); set => SetProperty(value); } + public int MaterialBottomTab3Count { get => GetProperty(); set => SetProperty(value); } public int MaterialVerticalTab1Count { get => GetProperty(); set => SetProperty(value); } - public int MaterialVerticalTab2Count { get => GetProperty(); set => SetProperty(value); } - public int MaterialVerticalTab3Count { get => GetProperty(); set => SetProperty(value); } + public int MaterialVerticalTab2Count { get => GetProperty(); set => SetProperty(value); } + public int MaterialVerticalTab3Count { get => GetProperty(); set => SetProperty(value); } - public int CupertinoBottomTab1Count { get => GetProperty(); set => SetProperty(value); } - public int CupertinoBottomTab2Count { get => GetProperty(); set => SetProperty(value); } - public int CupertinoBottomTab3Count { get => GetProperty(); set => SetProperty(value); } + public int CupertinoBottomTab1Count { get => GetProperty(); set => SetProperty(value); } + public int CupertinoBottomTab2Count { get => GetProperty(); set => SetProperty(value); } + public int CupertinoBottomTab3Count { get => GetProperty(); set => SetProperty(value); } - public List Items { get => GetProperty>(); set => SetProperty(value); } + public List Items { get => GetProperty>(); set => SetProperty(value); } + public List MenuItems { get => GetProperty>(); set => SetProperty(value); } - public ICommand Tab1CountCommand => new Command(_ => Tab1Count++); - public ICommand Tab2CountCommand => new Command(_ => Tab2Count++); - public ICommand Tab3CountCommand => new Command(_ => Tab3Count++); + public ICommand Tab1CountCommand => new Command(_ => Tab1Count++); + public ICommand Tab2CountCommand => new Command(_ => Tab2Count++); + public ICommand Tab3CountCommand => new Command(_ => Tab3Count++); - public ICommand MaterialBottomTab1CountCommand => new Command(_ => MaterialBottomTab1Count++); - public ICommand MaterialBottomTab2CountCommand => new Command(_ => MaterialBottomTab2Count++); - public ICommand MaterialBottomTab3CountCommand => new Command(_ => MaterialBottomTab3Count++); + public ICommand MaterialBottomTab1CountCommand => new Command(_ => MaterialBottomTab1Count++); + public ICommand MaterialBottomTab2CountCommand => new Command(_ => MaterialBottomTab2Count++); + public ICommand MaterialBottomTab3CountCommand => new Command(_ => MaterialBottomTab3Count++); - public ICommand MaterialVerticalTab1CountCommand => new Command(_ => MaterialVerticalTab1Count++); - public ICommand MaterialVerticalTab2CountCommand => new Command(_ => MaterialVerticalTab2Count++); - public ICommand MaterialVerticalTab3CountCommand => new Command(_ => MaterialVerticalTab3Count++); + public ICommand MaterialVerticalTab1CountCommand => new Command(_ => MaterialVerticalTab1Count++); + public ICommand MaterialVerticalTab2CountCommand => new Command(_ => MaterialVerticalTab2Count++); + public ICommand MaterialVerticalTab3CountCommand => new Command(_ => MaterialVerticalTab3Count++); - public ICommand CupertinoBottomTab1CountCommand => new Command(_ => CupertinoBottomTab1Count++); - public ICommand CupertinoBottomTab2CountCommand => new Command(_ => CupertinoBottomTab2Count++); - public ICommand CupertinoBottomTab3CountCommand => new Command(_ => CupertinoBottomTab3Count++); + public ICommand CupertinoBottomTab1CountCommand => new Command(_ => CupertinoBottomTab1Count++); + public ICommand CupertinoBottomTab2CountCommand => new Command(_ => CupertinoBottomTab2Count++); + public ICommand CupertinoBottomTab3CountCommand => new Command(_ => CupertinoBottomTab3Count++); - public TabBarViewModel() + public TabBarViewModel() { - Items = new List { "Tab 1", "Tab 2", "Tab 3" }; + Items = new List { "Tab 1", "Tab 2", "Tab 3" }; + MenuItems = [new TestRecord("True", true), new TestRecord("False", false), new TestRecord("True", true)]; } } + public record TestRecord(string Name, bool IsSelectable); } diff --git a/src/Uno.Toolkit.RuntimeTests/Tests/TabBarTests.cs b/src/Uno.Toolkit.RuntimeTests/Tests/TabBarTests.cs index 04e22e9f5..92f23bf9c 100644 --- a/src/Uno.Toolkit.RuntimeTests/Tests/TabBarTests.cs +++ b/src/Uno.Toolkit.RuntimeTests/Tests/TabBarTests.cs @@ -259,7 +259,7 @@ public async Task Verify_Padding( await UnitTestUIContentHelperEx.SetContentAndWait(rootGrid); - + var c = GetMinCalculatedDimen(); var expectedDimen = Math.Max(c, minDimen); double actualDimen = orientation switch @@ -311,19 +311,21 @@ public async Task Verify_Indicator_Display_On_Selection() await UnitTestUIContentHelperEx.SetContentAndWait(SUT); - + for (int i = 0; i < NumItems; i++) { SUT.SelectedIndex = i; await UnitTestsUIContentHelper.WaitForIdle(); - var selectedItem = SUT.ContainerFromItem(SUT.SelectedItem) as TabBarItem; + var container = SUT.ContainerFromItem(SUT.SelectedItem); + var selectedItem = SUT.GetInnerContainer(container); // see comment on GetInnerContainer + Assert.IsNotNull(selectedItem); var renderer = await SUT.TakeScreenshot(); var centerPoint = selectedItem!.TransformToVisual(SUT).TransformPoint(new Point(selectedItem.ActualWidth / 2, selectedItem.ActualHeight / 2)); - + await renderer.AssertColorAt(Colors.Red, (int)centerPoint.X, (int)centerPoint.Y); foreach (var nonSelected in SUT.Items.Cast().Where(x => !x.IsSelected)) @@ -380,10 +382,10 @@ public async Task Verify_Indicator_Placement(IndicatorPlacement placement) var abovePresenter = VisualTreeHelperEx .GetFirstDescendant(SUT, x => x.Name == "AboveSelectionIndicatorPresenter"); - + var renderer = await SUT.TakeScreenshot(); var centerPoint = item.TransformToVisual(SUT).TransformPoint(new Point(item.ActualWidth / 2, item.ActualHeight / 2)); - + if (placement == IndicatorPlacement.Above) { @@ -426,6 +428,79 @@ public async Task Verify_SelectedIndex_Not_Set_Unnecessarily() //Assert.IsNull(SUT.GetBindingExpression(TabBar.SelectedIndexProperty)); } + [TestMethod] + public async Task Verify_ItemTemplate_Has_No_Nested_TabBarItem() + { + var source = new[] + { + new TestRecord("True", true), + new TestRecord("False", false), + new TestRecord("True", true) + }; + + var dt = XamlHelper.LoadXaml(""" + + + + """); + + var SUT = new TabBar + { + Style = (Style)Application.Current.Resources["TopTabBarStyle"], + ItemsSource = source, + ItemTemplate = dt, + SelectedIndex = 0 + }; + + await UnitTestUIContentHelperEx.SetContentAndWait(SUT); + + // Ensure the container is a `ContentPresenter` and not a `TabBarItem` + var container = SUT.ContainerFromItem(SUT.SelectedItem); + Assert.IsInstanceOfType(container, typeof(ContentPresenter)); + + // Ensure the inner container is a `TabBarItem` + var selectedItem = SUT.GetInnerContainer(container); // see comment on GetInnerContainer + Assert.IsInstanceOfType(selectedItem, typeof(TabBarItem)); + } + + [TestMethod] + public async Task Verify_ItemTemplate_Disabled_Not_Selectable() + { + var source = new[] + { + new TestRecord("True", true), + new TestRecord("False", false), + new TestRecord("True", true) + }; + + var dt = XamlHelper.LoadXaml(""" + + + + """); + + var SUT = new TabBar + { + Style = (Style)Application.Current.Resources["TopTabBarStyle"], + ItemsSource = source, + ItemTemplate = dt, + }; + + await UnitTestUIContentHelperEx.SetContentAndWait(SUT); + + Assert.IsNull(SUT.SelectedItem); + + // Make sure the first item is selectable + SUT.SelectedIndex = 0; + await UnitTestsUIContentHelper.WaitForIdle(); + Assert.AreSame(SUT.SelectedItem, source[0]); + + SUT.SelectedIndex = 1; + await UnitTestsUIContentHelper.WaitForIdle(); + // Assert the second item is not selected + Assert.AreNotSame(SUT.SelectedItem, source[1]); + } + private class SelectedIndexTestViewModel : INotifyPropertyChanged { private int _p; @@ -441,5 +516,8 @@ public int P public event PropertyChangedEventHandler? PropertyChanged; } + + public record TestRecord(string Name, bool IsSelectable); + } } diff --git a/src/Uno.Toolkit.UI/Behaviors/TabBarSelectorBehaviorState.cs b/src/Uno.Toolkit.UI/Behaviors/TabBarSelectorBehaviorState.cs index e7a9130fe..54fe9c7ed 100644 --- a/src/Uno.Toolkit.UI/Behaviors/TabBarSelectorBehaviorState.cs +++ b/src/Uno.Toolkit.UI/Behaviors/TabBarSelectorBehaviorState.cs @@ -53,7 +53,7 @@ public void Connect() partial void ConnectPartial(); public void Disconnect() - { + { if (Selector != null) { Selector.SelectionChanged -= OnSelectorSelectionChanged; @@ -74,7 +74,7 @@ public void Disconnect() int unselectableCount = 0; for (int i = 0; i < index; i++) { - if (TabBar.ContainerFromIndex(i) is TabBarItem { IsSelectable: false }) + if (TabBar.InnerContainerFromIndex(i) is TabBarItem { IsSelectable: false }) { unselectableCount++; } @@ -88,7 +88,7 @@ public void Disconnect() int skipped = 0; for (int i = 0; i < TabBar.Items.Count; i++) { - if (TabBar.ContainerFromIndex(i) is TabBarItem { IsSelectable: true }) + if (TabBar.InnerContainerFromIndex(i) is TabBarItem { IsSelectable: true }) { if (skipped == index) { @@ -151,8 +151,8 @@ public void UpdateOffset(int position, double progress, double totalOffset) return; } - var selectedTabBarItem = TabBar.ContainerFromIndex(previousIndex.Value) as TabBarItem; - var nextTabBarItem = TabBar.ContainerFromIndex(nextTabIndex.Value) as TabBarItem; + var selectedTabBarItem = TabBar.InnerContainerFromIndex(previousIndex.Value) as TabBarItem; + var nextTabBarItem = TabBar.InnerContainerFromIndex(nextTabIndex.Value) as TabBarItem; var currentX = GetRelativeX(selectedTabBarItem); var nextX = GetRelativeX(nextTabBarItem); @@ -162,7 +162,7 @@ public void UpdateOffset(int position, double progress, double totalOffset) var indicatorPosition = currentX + ((selectedTabBarItem?.ActualWidth ?? 0) / 2) - (selectionIndicator.ActualSize.X / 2); SelectorExtensions.SetSelectionOffset( - TabBar, + TabBar, toRight ? indicatorPosition + (progress * distance) : indicatorPosition - ((1 - progress) * distance) @@ -173,7 +173,7 @@ private void UpdateOffsetToPosition(int position, UIElement selectionIndicator) { if (MapIndexToTabBar(position) is { } index && index >= 0 && index < TabBar.Items.Count) { - var tabItem = TabBar.ContainerFromIndex(index) as TabBarItem; + var tabItem = TabBar.InnerContainerFromIndex(index) as TabBarItem; SelectorExtensions.SetSelectionOffset(TabBar, GetRelativeX(tabItem) + ((tabItem?.ActualWidth ?? 0) / 2) - (selectionIndicator.ActualSize.X / 2)); } } diff --git a/src/Uno.Toolkit.UI/Controls/TabBar/TabBar.cs b/src/Uno.Toolkit.UI/Controls/TabBar/TabBar.cs index 215320638..5ed95ec11 100644 --- a/src/Uno.Toolkit.UI/Controls/TabBar/TabBar.cs +++ b/src/Uno.Toolkit.UI/Controls/TabBar/TabBar.cs @@ -37,6 +37,8 @@ public partial class TabBar : ItemsControl { private const string TabBarGridName = "TabBarGrid"; + internal bool IsUsingOwnContainerAsTemplateRoot { get; private set; } + private bool _isSynchronizingSelection; private object? _previouslySelectedItem; private bool _isLoaded; @@ -57,19 +59,45 @@ protected override void OnApplyTemplate() UpdateIndicatorPlacement(); } - protected override bool IsItemItsOwnContainerOverride(object item) => item is TabBarItem; + protected override bool IsItemItsOwnContainerOverride(object? item) => item is TabBarItem; + + protected override DependencyObject GetContainerForItemOverride() + { + if (IsUsingOwnContainerAsTemplateRoot) + { + return new ContentPresenter(); + } - protected override DependencyObject GetContainerForItemOverride() => new TabBarItem(); + return new TabBarItem(); + } protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { base.PrepareContainerForItemOverride(element, item); + void SetupTabBarItem(TabBarItem item) + { + item.IsSelected = IsSelected(IndexFromContainer(element)); + item.Click += OnTabBarItemClick; + item.IsSelectedChanged += OnTabBarIsSelectedChanged; + } + if (element is TabBarItem container) - { - container.IsSelected = IsSelected(IndexFromContainer(element)); - container.Click += OnTabBarItemClick; - container.IsSelectedChanged += OnTabBarIsSelectedChanged; + { + SetupTabBarItem(container); + } + else if (IsUsingOwnContainerAsTemplateRoot && + element is ContentPresenter outerContainer) + { + var templateRoot = outerContainer.ContentTemplate.LoadContent(); + if (templateRoot is TabBarItem tabBarItem) + { + outerContainer.ContentTemplate = null; + SetupTabBarItem(tabBarItem); + tabBarItem.DataContext = item; + tabBarItem.Style ??= ItemContainerStyle; + outerContainer.Content = tabBarItem; + } } } @@ -82,11 +110,28 @@ protected override void ClearContainerForItemOverride(DependencyObject element, { base.ClearContainerForItemOverride(element, item); + void TearDownTabBarItem(TabBarItem item) + { + item.Click -= OnTabBarItemClick; + item.IsSelectedChanged -= OnTabBarIsSelectedChanged; + if (!IsUsingOwnContainerAsTemplateRoot) + { + item.Style = null; + } + } if (element is TabBarItem container) { - container.Click -= OnTabBarItemClick; - container.IsSelectedChanged -= OnTabBarIsSelectedChanged; - container.Style = null; + TearDownTabBarItem(container); + } + else if (IsUsingOwnContainerAsTemplateRoot && + element is ContentPresenter outerContainer) + { + if (outerContainer.Content is TabBarItem innerContainer) + { + TearDownTabBarItem(innerContainer); + innerContainer.DataContext = null; + } + outerContainer.Content = null; } } @@ -103,9 +148,9 @@ e is IVectorChangedEventArgs iVCE { var item = Items[(int)iVCE.Index]; - if (item is TabBarItem tabBarItem && tabBarItem.IsSelected) + if (GetInnerContainer(item as DependencyObject) is { IsSelected: true } selected) // see comment on GetInnerContainer { - SelectedItem = tabBarItem; + SelectedItem = selected; } } else if (iVCE.CollectionChange == CollectionChange.ItemRemoved) @@ -136,7 +181,7 @@ private void SynchronizeInitialSelection() if (SelectedItem != null) { OnSelectedItemChanged(null); - } + } else if (SelectedIndex >= 0) { OnSelectedIndexChanged(null); @@ -227,6 +272,12 @@ private void OnItemsSourceChanged() SynchronizeInitialSelection(); } + protected override void OnItemTemplateChanged(DataTemplate oldItemTemplate, DataTemplate newItemTemplate) + { + IsUsingOwnContainerAsTemplateRoot = IsItemItsOwnContainerOverride(newItemTemplate?.LoadContent()); + base.OnItemTemplateChanged(oldItemTemplate, newItemTemplate); + } + private void OnSelectedItemChanged(DependencyPropertyChangedEventArgs? args) { if (_isSynchronizingSelection) @@ -256,10 +307,10 @@ private void OnSelectedIndexChanged(DependencyPropertyChangedEventArgs? args) TabBarItem? oldItem = null; if (args?.OldValue is int oldIndex && oldIndex != -1) { - oldItem = this.ContainerFromIndexSafe(oldIndex); + oldItem = this.InnerContainerFromIndexSafe(oldIndex); } - var newItem = this.ContainerFromIndexSafe(SelectedIndex); + var newItem = this.InnerContainerFromIndexSafe(SelectedIndex); if (TryUpdateTabBarItemSelectedState(oldItem, newItem)) { @@ -301,16 +352,20 @@ private void SynchronizeSelection(TabBarItem? item) { _isSynchronizingSelection = true; - foreach (var container in this.GetItemContainers()) + var containers = this.GetItemContainers(); + foreach (var container in containers) { - if (!container.IsSelected) + var tbi = GetInnerContainer(container); // see comment on GetInnerContainer + if (tbi is not { }) continue; + + if (!tbi.IsSelected) { continue; } - if (container != item) + if (tbi != item) { - container.IsSelected = false; + tbi.IsSelected = false; } else { @@ -352,6 +407,40 @@ private void RaiseSelectionChangedEvent(object? prevItem, object? nextItem) SelectionChanged?.Invoke(this, eventArgs); } + // When using an `ItemTemplate` with a `TabBarItem`, the container will be a `ContentPresenter` that wraps the `TabBarItem`. + // In that case, to access the `ContentPresenter` from a `TabBarItem`, you must first call `ContainerFromItem`. + // Afterward, pass the resulting `ContentPresenter` as a parameter to this method. + internal TabBarItem? GetInnerContainer(DependencyObject? container) + { + if (IsUsingOwnContainerAsTemplateRoot && container is ContentPresenter cp) + { + return cp.Content as TabBarItem; + } + + return container as TabBarItem; + } + + internal DependencyObject? InnerContainerFromIndex(int index) + { + var container = ContainerFromIndex(index); + if (IsUsingOwnContainerAsTemplateRoot && container is ContentPresenter cp) + { + container = cp.Content as DependencyObject; + } + + return container; + } + + private TabBarItem? InnerContainerFromIndexSafe(int index) + { + if (index >= 0 && index < Items.Count) + { + return InnerContainerFromIndex(index) as TabBarItem; + } + + return null; + } + private bool IsReady => _isLoaded && HasItems; private bool HasItems => this.GetItems().Any(); diff --git a/src/Uno.Toolkit.UI/Controls/TabBar/TabBarSelectionIndicatorPresenter.cs b/src/Uno.Toolkit.UI/Controls/TabBar/TabBarSelectionIndicatorPresenter.cs index 1dbaffe44..4d5cab44d 100644 --- a/src/Uno.Toolkit.UI/Controls/TabBar/TabBarSelectionIndicatorPresenter.cs +++ b/src/Uno.Toolkit.UI/Controls/TabBar/TabBarSelectionIndicatorPresenter.cs @@ -224,23 +224,24 @@ private void UpdateSelectionIndicatorMaxSize() if (Owner is { } tabBar && GetSelectionIndicator() is { } indicator) { - var tabBarItems = tabBar.GetItemContainers().Where(tbi => tbi.Visibility == Visibility.Visible); - if (tabBarItems.None()) + var tabBarItems = tabBar.GetItemContainers() + .Select(tabBar.GetInnerContainer) // see comment on GetInnerContainer + .OfType(); + var visibleItems = tabBarItems.Count(x => x.Visibility == Visibility.Visible); + if (visibleItems is 0) { return; } var maxSize = new Size(); - var numItems = tabBarItems.Count(); - if (tabBar.Orientation == Orientation.Vertical) { - maxSize.Height = tabBar.ActualHeight / numItems; + maxSize.Height = tabBar.ActualHeight / visibleItems; maxSize.Width = tabBar.ActualWidth; } else { - maxSize.Width = tabBar.ActualWidth / numItems; + maxSize.Width = tabBar.ActualWidth / visibleItems; maxSize.Height = tabBar.ActualHeight; } @@ -297,7 +298,7 @@ private void SynchronizeSelection() return; } - if (tabBar.ContainerFromIndex(tabBar.SelectedIndex) is TabBarItem newSelectedItem) + if (tabBar.InnerContainerFromIndex(tabBar.SelectedIndex) is TabBarItem newSelectedItem) { newSelectedItem.SizeChanged += OnSelectedTabBarItemSizeChanged; _tabBarItemSizeChangedRevoker.Disposable = Disposable.Create(() => newSelectedItem.SizeChanged -= OnSelectedTabBarItemSizeChanged); @@ -331,7 +332,7 @@ private void UpdateSelectionIndicatorPosition(Point? destination = null) if (destination == null && tabBar.SelectedIndex != -1) { - destination = GetRelativePosition(tabBar.ContainerFromIndex(tabBar.SelectedIndex) as TabBarItem); + destination = GetRelativePosition(tabBar.InnerContainerFromIndex(tabBar.SelectedIndex) as TabBarItem); } if (destination == null || diff --git a/src/library/Uno.Toolkit.Material/Styles/Controls/v2/TabBar.xaml b/src/library/Uno.Toolkit.Material/Styles/Controls/v2/TabBar.xaml index 153b734b0..7d2c3ec33 100644 --- a/src/library/Uno.Toolkit.Material/Styles/Controls/v2/TabBar.xaml +++ b/src/library/Uno.Toolkit.Material/Styles/Controls/v2/TabBar.xaml @@ -805,7 +805,6 @@ -