Skip to content

Commit

Permalink
feat: Add TabView.reservedStripWidth
Browse files Browse the repository at this point in the history
  • Loading branch information
bdlukaa authored Nov 18, 2024
2 parents 15e250e + 5626ef7 commit f327a58
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [next]

- fix: Add missing properties (`closeIconSize`, `closeButtonStyle`) in `debugFillProperties` and `InfoBarThemeData.merge` ([#1128](https://github.com/bdlukaa/fluent_ui/issues/1128)
- feat: Add `TabView.reservedStripWidth`, which adds a minimum empty area between the tabs and the tab view footer ([#1106](https://github.com/bdlukaa/fluent_ui/issues/1106))

## 4.9.2

Expand Down
1 change: 1 addition & 0 deletions example/lib/screens/navigation/tab_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ TabView(
height: 400,
child: TabView(
tabs: tabs!,
reservedStripWidth: 100,
currentIndex: currentIndex,
onChanged: (index) => setState(() => currentIndex = index),
tabWidthBehavior: tabWidthBehavior,
Expand Down
33 changes: 28 additions & 5 deletions lib/src/controls/navigation/tab_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class TabView extends StatefulWidget {
this.tabWidthBehavior = TabWidthBehavior.equal,
this.header,
this.footer,
this.reservedStripWidth,
this.stripBuilder,
this.closeDelayDuration = const Duration(seconds: 1),
});
Expand Down Expand Up @@ -170,6 +171,19 @@ class TabView extends StatefulWidget {
/// Usually a [Text] widget.
final Widget? footer;

/// The minimum width reserved at the end of the tab strip.
///
/// This reserved space ensures a consistent drag area for window manipulation
/// (e.g., dragging, resizing) even when many tabs are present. This is particularly
/// crucial when `TabView` is used in a title bar.
///
/// When using TabView in a title bar, this space ensures minimum drag area even
/// when many tabs are present. This is critical for window manipulation (dragging, etc)
/// as it guarantees a consistent drag target regardless of tab count.
///
/// If `null`, no reserved width is enforced.
final double? reservedStripWidth;

/// The builder for the strip that contains the tabs.
final Widget Function(BuildContext context, Widget strip)? stripBuilder;

Expand Down Expand Up @@ -244,7 +258,8 @@ class TabView extends StatefulWidget {
defaultValue: const Duration(seconds: 1),
))
..add(DoubleProperty('minTabWidth', minTabWidth, defaultValue: 80.0))
..add(DoubleProperty('maxTabWidth', maxTabWidth, defaultValue: 240.0));
..add(DoubleProperty('maxTabWidth', maxTabWidth, defaultValue: 240.0))
..add(DoubleProperty('minFooterWidth', reservedStripWidth));
}
}

Expand Down Expand Up @@ -476,10 +491,11 @@ class _TabViewState extends State<TabView> {
'You can only create a TabView in a box with defined width',
);

preferredTabWidth =
((width - (widget.showNewButton ? _kButtonWidth : 0)) /
widget.tabs.length)
.clamp(widget.minTabWidth, widget.maxTabWidth);
preferredTabWidth = ((width -
(widget.showNewButton ? _kButtonWidth : 0) -
(widget.reservedStripWidth ?? 0)) /
widget.tabs.length)
.clamp(widget.minTabWidth, widget.maxTabWidth);

final Widget listView = Listener(
onPointerSignal: (PointerSignalEvent e) {
Expand Down Expand Up @@ -583,18 +599,22 @@ class _TabViewState extends State<TabView> {
}

final strip = Row(children: [
// scroll buttons if needed
if (showScrollButtons)
direction == TextDirection.ltr
? backwardButton()
: forwardButton(),
// tabs area (flexible/expanded)
if (scrollable)
Expanded(child: listView)
else
Flexible(child: listView),
// scroll buttons if needed
if (showScrollButtons)
direction == TextDirection.ltr
? forwardButton()
: backwardButton(),
// new tab button
if (widget.showNewButton)
Padding(
padding: const EdgeInsetsDirectional.only(
Expand Down Expand Up @@ -624,6 +644,9 @@ class _TabViewState extends State<TabView> {
localizations.newTabLabel,
),
),
// reserved strip width
if (widget.reservedStripWidth != null)
SizedBox(width: widget.reservedStripWidth),
]);

if (widget.stripBuilder != null) {
Expand Down

0 comments on commit f327a58

Please sign in to comment.