Skip to content
Merged
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
63 changes: 38 additions & 25 deletions packages/flet/lib/src/controls/tabs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -157,35 +157,48 @@ class TabBarViewControl extends StatelessWidget {

// Find the TabController from the nearest TabsControl ancestor
final tabsState = context.findAncestorStateOfType<_TabsControlState>();
if (tabsState != null) {
final tabController = tabsState._tabController;
if (tabsState == null) {
return const ErrorControl(
"TabBarView must be used within a Tabs control");
}

final tabController = tabsState._tabController;

Widget buildConstrainedTabView() {
return ConstrainedControl(
control: control,
child: TabBarView(
controller: tabController,
clipBehavior:
control.getClipBehavior("clip_behavior", Clip.hardEdge)!,
viewportFraction: control.getDouble("viewport_fraction", 1.0)!,
children: control.buildWidgets("controls"),
));
}

return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (constraints.maxHeight == double.infinity &&
control.getDouble("height") == null &&
control.getExpand("expand", 0)! <= 0) {
// If expand property was set, we return the result directly.
// Because having Expanded as direct child of LayoutBuilder is not allowed.
if (control.getExpand("expand", 0)! > 0) {
return buildConstrainedTabView();
}

return LayoutBuilder(
builder: (context, constraints) {
final hasFixedHeight = control.getDouble("height") != null;
final hasUnboundedHeight =
constraints.maxHeight == double.infinity && !hasFixedHeight;

if (hasUnboundedHeight) {
return const ErrorControl(
"Error displaying TabBarView: height is unbounded.",
description:
"Set a fixed height, a non-zero expand, or/and place inside "
"a control with bounded height.");
"Error displaying TabBarView: height is unbounded.",
description:
"Set a fixed height, a non-zero expand, or place it inside a control with bounded height.",
);
}

return ConstrainedControl(
control: control,
child: TabBarView(
controller: tabController,
clipBehavior:
control.getClipBehavior("clip_behavior", Clip.hardEdge)!,
viewportFraction: control.getDouble("viewport_fraction", 1.0)!,
children: control.buildWidgets("controls"),
));
});
} else {
return const ErrorControl(
"TabBarView must be used within a Tabs control");
}
return buildConstrainedTabView();
},
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion sdk/python/examples/controls/tabs/nested.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def main(page: ft.Page):
ft.TabBarView(
expand=True,
controls=[
ft.Text("Main Tab 1 content"),
ft.Tabs(
length=2,
expand=True,
Expand All @@ -41,7 +42,6 @@ def main(page: ft.Page):
],
),
),
ft.Text("Main Tab 1 content"),
],
),
],
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
77 changes: 64 additions & 13 deletions sdk/python/packages/flet/integration_tests/controls/test_tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


@pytest.mark.asyncio(loop_scope="module")
async def test_tabs_basic(flet_app: ftt.FletTestApp, request):
async def test_basic(flet_app: ftt.FletTestApp, request):
await flet_app.assert_control_screenshot(
name=request.node.name,
expand_screenshot=True,
Expand All @@ -19,20 +19,71 @@ async def test_tabs_basic(flet_app: ftt.FletTestApp, request):
ft.Tab(label="Tab 2", icon=ft.Icons.SETTINGS),
]
),
ft.Container(
ft.TabBarView(
expand=True,
content=ft.TabBarView(
controls=[
ft.Container(
content=ft.Text("This is Tab 1"),
alignment=ft.Alignment.CENTER,
),
ft.Container(
content=ft.Text("This is Tab 3"),
alignment=ft.Alignment.CENTER,
controls=[
ft.Container(
content=ft.Text("This is Tab 1"),
alignment=ft.Alignment.CENTER,
),
ft.Container(
content=ft.Text("This is Tab 3"),
alignment=ft.Alignment.CENTER,
),
],
),
],
),
),
)


@pytest.mark.asyncio(loop_scope="module")
async def test_nesting(flet_app: ftt.FletTestApp, request):
await flet_app.assert_control_screenshot(
name=request.node.name,
expand_screenshot=True,
control=ft.Tabs(
length=2,
expand=True,
selected_index=1,
content=ft.Column(
expand=True,
controls=[
ft.TabBar(
tabs=[
ft.Tab(label=ft.Text("Main Tab 1")),
ft.Tab(label=ft.Text("Main Tab 2")),
],
),
ft.TabBarView(
expand=True,
controls=[
ft.Text("Main Tab 1 content"),
ft.Tabs(
length=2,
expand=True,
content=ft.Column(
expand=True,
controls=[
ft.TabBar(
secondary=True,
tabs=[
ft.Tab(label=ft.Text("SubTab 1")),
ft.Tab(label=ft.Text("SubTab 2")),
],
),
ft.TabBarView(
expand=True,
controls=[
ft.Text("Nested Tab 1 content"),
ft.Text("Nested Tab 2 content"),
],
),
],
),
],
),
),
],
),
],
),
Expand Down
Loading