Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 39 additions & 10 deletions maui/src/TabView/Control/SfTabBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ internal partial class SfTabBar : SfStackLayout, ITapGestureListener

// Dimension and positioning fields

readonly int _defaultTextPadding = 36;
double _previousTabX = 0d;
double _selectedTabX = 0d;
double _currentIndicatorWidth = 0d;
Expand Down Expand Up @@ -215,6 +214,17 @@ internal partial class SfTabBar : SfStackLayout, ITapGestureListener
typeof(SfTabBar),
propertyChanged: OnHeaderTemplateChanged);

/// <summary>
/// Identifies the <see cref="HeaderItemSpacing"/> bindable property.
/// </summary>
internal static readonly BindableProperty HeaderItemSpacingProperty =
BindableProperty.Create(
nameof(HeaderItemSpacing),
typeof(int),
typeof(SfTabBar),
36,
propertyChanged: OnHeaderItemSpacingChanged);

/// <summary>
/// Identifies the <see cref="HeaderDisplayMode"/> bindable property.
/// </summary>
Expand Down Expand Up @@ -513,6 +523,18 @@ internal DataTemplate? HeaderItemTemplate
set => SetValue(HeaderItemTemplateProperty, value);
}

/// <summary>
/// Gets or sets the value that defines the spacing between header items.
/// </summary>
/// <value>
/// It accepts int values and the default value is 36.
/// </value>
internal int HeaderItemSpacing
{
get => (int)GetValue(HeaderItemSpacingProperty);
set => SetValue(HeaderItemSpacingProperty, value);
}

/// <summary>
/// Gets or sets a value that can be used to customize the corner radius of selection indicator.
/// </summary>
Expand Down Expand Up @@ -1481,6 +1503,11 @@ void UpdateTabPadding()
CalculateTabItemsSourceWidth();
}

void UpdateTabHeaderItemSpacing()
{
CalculateTabItemWidth();
}

void AddTabViewItemFromTemplate(object? item)
{
var view = item as View;
Expand Down Expand Up @@ -2125,8 +2152,8 @@ void CalculateTabItemWidthForCustomMode()
if (item.Header != null)
{
Size desiredSize = item.Header.Measure((float)item.FontSize, item.FontAttributes, item.FontFamily);
double width = desiredSize.Width + _defaultTextPadding;
UpdateTabItemWidth(item, item.IsSelected ? width : _tabHeaderImageSize + _defaultTextPadding);
double width = desiredSize.Width + HeaderItemSpacing;
UpdateTabItemWidth(item, item.IsSelected ? width : _tabHeaderImageSize + HeaderItemSpacing);
}
}
}
Expand Down Expand Up @@ -2163,7 +2190,7 @@ void CalculateTabItemWidthForSizeToContentForItem(SfTabItem item, Size desiredSi
if (item.HeaderContent != null)
{
Size headerContentSize = item.HeaderContent.Measure(double.PositiveInfinity, double.PositiveInfinity);
width = headerContentSize.Width + _defaultTextPadding;
width = headerContentSize.Width + HeaderItemSpacing;
}
else if (item.ImageSource != null && !string.IsNullOrEmpty(item.Header))
{
Expand All @@ -2172,12 +2199,12 @@ void CalculateTabItemWidthForSizeToContentForItem(SfTabItem item, Size desiredSi
else if (item.ImageSource != null)
{
item.HeaderDisplayMode = TabBarDisplayMode.Image;
width = _tabHeaderImageSize + _defaultTextPadding;
width = _tabHeaderImageSize + HeaderItemSpacing;
}
else
{
item.HeaderDisplayMode = TabBarDisplayMode.Text;
width = desiredSize.Width + _defaultTextPadding;
width = desiredSize.Width + HeaderItemSpacing;
}
UpdateTabItemWidth(item, width);
}
Expand All @@ -2189,22 +2216,22 @@ double GetWidthForSizeToContentWithImageAndText(SfTabItem item, Size desiredSize
if (HeaderDisplayMode == TabBarDisplayMode.Image)
{
item.HeaderDisplayMode = TabBarDisplayMode.Image;
return _tabHeaderImageSize + _defaultTextPadding;
return _tabHeaderImageSize + HeaderItemSpacing;
}
else if (HeaderDisplayMode == TabBarDisplayMode.Text)
{
item.HeaderDisplayMode = TabBarDisplayMode.Text;
return desiredSize.Width + _defaultTextPadding;
return desiredSize.Width + HeaderItemSpacing;
}
else
{
if (item.ImagePosition == TabImagePosition.Left || item.ImagePosition == TabImagePosition.Right)
{
return desiredSize.Width + _defaultTextPadding + _tabHeaderImageSize + item.ImageTextSpacing;
return desiredSize.Width + HeaderItemSpacing + _tabHeaderImageSize + item.ImageTextSpacing;
}
else
{
return desiredSize.Width + _defaultTextPadding;
return desiredSize.Width + HeaderItemSpacing;
}
}
}
Expand Down Expand Up @@ -3496,6 +3523,8 @@ protected override void OnBindingContextChanged()

static void OnHeaderTemplateChanged(BindableObject bindable, object oldValue, object newValue) => (bindable as SfTabBar)?.UpdateItemsSource();

static void OnHeaderItemSpacingChanged(BindableObject bindable, object oldValue, object newValue) => (bindable as SfTabBar)?.UpdateTabHeaderItemSpacing();

static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue) => (bindable as SfTabBar)?.UpdateItemsSource();

static void OnSelectedIndexChanged(BindableObject bindable, object oldValue, object newValue) => (bindable as SfTabBar)?.UpdateSelectedIndex((int)newValue, (int)oldValue);
Expand Down
54 changes: 54 additions & 0 deletions maui/src/TabView/Control/SfTabView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,17 @@ public partial class SfTabView : ContentView, IParentThemeElement
null,
propertyChanged: OnHeaderItemTemplateChanged);

/// <summary>
/// Identifies the <see cref="HeaderItemSpacing"/> bindable property.
/// </summary>
public static readonly BindableProperty HeaderItemSpacingProperty =
BindableProperty.Create(
nameof(HeaderItemSpacing),
typeof(int),
typeof(SfTabView),
36,
propertyChanged: OnHeaderItemSpacingChanged);

/// <summary>
/// Identifies the <see cref="ContentItemTemplate"/> bindable property.
/// </summary>
Expand Down Expand Up @@ -1033,6 +1044,33 @@ public DataTemplate? HeaderItemTemplate
get => (DataTemplate?)GetValue(HeaderItemTemplateProperty);
set => SetValue(HeaderItemTemplateProperty, value);
}

/// <summary>
/// Gets or sets the value that defines the spacing between header items.
/// </summary>
/// <value>
/// It accepts int values and the default value is 36.
/// </value>
/// <example>
/// Here is an example of how to set the <see cref="HeaderItemSpacing"/> property.
///
/// # [XAML](#tab/tabid-1)
/// <code><![CDATA[
/// <tabView:SfTabView HeaderItemSpacing="32" />
/// ]]></code>
///
/// # [C#](#tab/tabid-2)
/// <code><![CDATA[
/// SfTabView tabView = new SfTabView();
/// tabView.HeaderItemSpacing = 32;
/// Content = tabView;
/// ]]></code>
/// </example>
public int HeaderItemSpacing
{
get => (int)GetValue(HeaderItemSpacingProperty);
set => SetValue(HeaderItemSpacingProperty, value);
}

/// <summary>
/// Gets or sets the template that is used to display the content.
Expand Down Expand Up @@ -1961,6 +1999,11 @@ internal void RaiseCenterButtonTappedEvent(EventArgs args)
/// </summary>
static void OnHeaderItemTemplateChanged(BindableObject bindable, object oldValue, object newValue) => (bindable as SfTabView)?.UpdateHeaderItemTemplate();

/// <summary>
/// Handles changes to the <see cref="HeaderItemSpacing"/> property.
/// </summary>
static void OnHeaderItemSpacingChanged(BindableObject bindable, object oldValue, object newValue) => (bindable as SfTabView)?.UpdateHeaderSpacing();

/// <summary>
/// Handles changes to the <see cref="ContentItemTemplate"/> property.
/// </summary>
Expand Down Expand Up @@ -2096,6 +2139,17 @@ void UpdateHeaderItemTemplate()
}
}

/// <summary>
/// Updates the header item spacing of the tab bar.
/// </summary>
void UpdateHeaderSpacing()
{
if (_tabHeaderContainer != null)
{
_tabHeaderContainer.HeaderItemSpacing = HeaderItemSpacing;
}
}

/// <summary>
/// Updates the content item template if both ItemsSource and ContentItemTemplate are set.
/// </summary>
Expand Down