diff --git a/package/lib/src/controls/tabs.dart b/package/lib/src/controls/tabs.dart index b123025e9..030f4580a 100644 --- a/package/lib/src/controls/tabs.dart +++ b/package/lib/src/controls/tabs.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:flet/src/utils/alignment.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; @@ -136,9 +137,14 @@ class _TabsControlState extends State var indicatorTabSize = widget.control.attrBool("indicatorTabSize"); + var isScrollable = widget.control.attrBool("scrollable", true)!; + var tabAlignment = parseTabAlignment(widget.control, "tabAlignment", + isScrollable ? TabAlignment.start : TabAlignment.fill); + var tabBar = TabBar( + tabAlignment: tabAlignment, controller: _tabController, - isScrollable: widget.control.attrBool("scrollable", true)!, + isScrollable: isScrollable, dividerColor: HexColor.fromString(Theme.of(context), widget.control.attrString("dividerColor", "")!) ?? TabBarTheme.of(context).dividerColor, diff --git a/package/lib/src/utils/alignment.dart b/package/lib/src/utils/alignment.dart index 07efbbba8..457ce084e 100644 --- a/package/lib/src/utils/alignment.dart +++ b/package/lib/src/utils/alignment.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import '../models/control.dart'; import 'numbers.dart'; @@ -23,6 +23,15 @@ CrossAxisAlignment parseCrossAxisAlignment( orElse: () => defValue); } +TabAlignment parseTabAlignment( + Control control, String propName, TabAlignment defValue) { + return TabAlignment.values.firstWhere( + (e) => + e.name.toLowerCase() == + control.attrString(propName, "")!.toLowerCase(), + orElse: () => defValue); +} + WrapAlignment parseWrapAlignment( Control control, String propName, WrapAlignment defValue) { return WrapAlignment.values.firstWhere( diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index 7f03f73d2..c8c76fd31 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -214,6 +214,7 @@ PaddingValue, PageDesignLanguage, ScrollMode, + TabAlignment, TextAlign, ThemeMode, ) diff --git a/sdk/python/packages/flet-core/src/flet_core/tabs.py b/sdk/python/packages/flet-core/src/flet_core/tabs.py index ade61ffc1..5149a88b3 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tabs.py +++ b/sdk/python/packages/flet-core/src/flet_core/tabs.py @@ -14,6 +14,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + TabAlignment, ) @@ -162,6 +163,7 @@ def __init__( tabs: Optional[List[Tab]] = None, selected_index: Optional[int] = None, scrollable: Optional[bool] = None, + tab_alignment: Optional[TabAlignment] = None, animation_duration: Optional[int] = None, divider_color: Optional[str] = None, indicator_color: Optional[str] = None, @@ -206,6 +208,7 @@ def __init__( self.tabs = tabs self.selected_index = selected_index self.scrollable = scrollable + self.tab_alignment = tab_alignment self.animation_duration = animation_duration self.divider_color = divider_color self.label_color = label_color @@ -267,6 +270,16 @@ def scrollable(self) -> Optional[bool]: def scrollable(self, value: Optional[bool]): self._set_attr("scrollable", value) + # tab_alignment + @property + def tab_alignment(self) -> Optional[TabAlignment]: + return self.__tab_alignment + + @tab_alignment.setter + def tab_alignment(self, value: Optional[TabAlignment]): + self.__tab_alignment = value + self._set_attr("tabAlignment", value.value if value is not None else None) + # animation_duration @property def animation_duration(self) -> Optional[int]: diff --git a/sdk/python/packages/flet-core/src/flet_core/types.py b/sdk/python/packages/flet-core/src/flet_core/types.py index 4defef634..6364a0761 100644 --- a/sdk/python/packages/flet-core/src/flet_core/types.py +++ b/sdk/python/packages/flet-core/src/flet_core/types.py @@ -139,6 +139,14 @@ class CrossAxisAlignment(Enum): BASELINE = "baseline" +class TabAlignment(Enum): + NONE = None + START = "start" + START_OFFSET = "startOffset" + FILL = "fill" + CENTER = "center" + + LabelPositionString = Literal[None, "right", "left"]