Skip to content

Conversation

@ndonkoHenri
Copy link
Contributor

@ndonkoHenri ndonkoHenri commented Jul 30, 2025

Fixes #5494

Test code

class MyContainer(ft.Container):
    def __init__(self, text):
        super().__init__(
            height=150,
            bgcolor=ft.Colors.random(),
            alignment=ft.Alignment.CENTER,
        )
        self.content = ft.Text(text)


def main(page: ft.Page):
    def handle_new_tab(e: ft.Event[ft.CupertinoFilledButton]):
        bar.tabs.append(ft.Tab(label=ft.Text(f"Tab {len(bar.tabs) + 1}")))
        view.controls.append(MyContainer(text=f"Tab {len(view.controls) + 1} content"))
        tabs.length = len(bar.tabs)

    def handle_move_to(e: ft.Event[ft.CupertinoFilledButton]):
        tabs.move_to(
            index=0,
            animation_curve=ft.AnimationCurve.FAST_OUT_SLOWIN,
            animation_duration=ft.Duration(seconds=3),
        )
        # or
        # tabs.selected_index = 0

    page.add(
        tabs := ft.Tabs(
            length=3,
            expand=True,
            on_change=print,
            animation_duration=ft.Duration(seconds=3),
            content=ft.Column(
                expand=True,
                controls=[
                    bar := ft.TabBar(
                        # on_hover=print,
                        tab_alignment=ft.TabAlignment.CENTER,
                        indicator=ft.UnderlineTabIndicator(
                            border_side=ft.BorderSide(3, ft.Colors.RED),
                            border_radius=10,
                        ),
                        tabs=[
                            ft.Tab(label=ft.Text("Tab 1")),
                            ft.Tab(label=ft.Text("Tab 2")),
                            ft.Text("Tab 3"),
                        ],
                    ),
                    ft.Row(
                        alignment=ft.MainAxisAlignment.CENTER,
                        controls=[
                            ft.CupertinoFilledButton(
                                content="Add new Tab",
                                icon=ft.Icons.ADD,
                                on_click=handle_new_tab,
                            ),
                            ft.CupertinoFilledButton(
                                content="Move to Tab 1",
                                icon=ft.Icons.MOVE_UP,
                                on_click=handle_move_to,
                            ),
                        ],
                    ),
                    view := ft.TabBarView(
                        expand=True,
                        controls=[
                            ft.Column(  # must be used so container respects its size
                                expand=True,
                                controls=[MyContainer(text="Tab 1 content")],
                            ),
                            MyContainer(text="Tab 2 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=[
                                                MyContainer(text="Sub Tab 1 content"),
                                                ft.Text("Sub Tab 2 content"),
                                            ],
                                        ),
                                    ],
                                ),
                            ),
                        ],
                    ),
                ],
            ),
        )
    )

Summary by Sourcery

Split and enhance the Tabs component by introducing dedicated TabBar and TabBarView controls, a TabAlignment enum, and refined API properties (length, content, initial_index, animation_duration), along with corresponding Dart implementations using DefaultTabController. Expand project tooling with new Taskfile commands, update pre-commit hooks, and reorganize documentation to surface TabBar and TabBarView under a unified tabs section.

New Features:

  • Add TabAlignment enum and separate TabBar and TabBarView controls in Python, updating Tabs with length, content, initial_index, and animation_duration properties
  • Implement Dart counterparts for Tab, TabBar, and TabBarView using DefaultTabController and simplify TabsControl logic
  • Introduce new Taskfile tasks for environment setup, docs serving, pre-commit management, free-port handling, and extension pre-commit installation

Enhancements:

  • Refactor ElevatedButton to unify style handling with copy_with and remove duplicate TabAlignment definition in Python types

CI:

  • Bump ruff pre-commit hook to v0.12.5 and add sort-all hook

Documentation:

  • Reorganize mkdocs navigation to include dedicated TabBar and TabBarView documentation under controls/tabs

Summary by Sourcery

Enhance the Tabs system by splitting it into TabBar and TabBarView with richer Python and Dart APIs, introduce supporting enums and indicator controls, refine button styling, bolster project tooling, update pre-commit hooks, and reorganize documentation

New Features:

  • Extract Tabs into dedicated TabBar and TabBarView controls in Python with new TabAlignment, TabIndicatorAnimation, TabBarIndicatorSize, UnderlineTabIndicator types and enhanced Tabs API (length, content, selected_index, animation_duration, move_to)
  • Implement Dart counterparts for Tab, TabBar, TabBarView with DefaultTabController-based logic, negative index support, and refined event handling

Enhancements:

  • Refactor ElevatedButton to consolidate style overrides via copy_with

CI:

  • Bump ruff pre-commit hook to v0.12.7 and add sort-all hook

Documentation:

  • Reorganize mkdocs navigation to group Tabs, Tab, TabBar, and TabBarView under a unified section and add new example snippets for dynamic tab addition, programmatic switching, and custom indicators

Chores:

  • Expand Python Taskfile with commands for environment setup, docs serving, pre-commit management, free-port handling, and extension pre-commit installation

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jul 30, 2025

Deploying flet-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: c13b204
Status: ✅  Deploy successful!
Preview URL: https://446a206a.flet-docs.pages.dev
Branch Preview URL: https://v1-improve-tabs.flet-docs.pages.dev

View logs

@ndonkoHenri ndonkoHenri marked this pull request as ready for review August 2, 2025 16:17
@ndonkoHenri
Copy link
Contributor Author

@sourcery-ai review

@ndonkoHenri ndonkoHenri requested a review from Copilot August 2, 2025 16:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the Tabs component by splitting it into separate TabBar and TabBarView controls, introducing new configuration options and improved API design. It provides better flexibility for tab layouts with dedicated controls for tab headers and content areas.

Key changes include:

  • Split Tabs into TabBar and TabBarView components with a unified Tabs wrapper
  • Added new properties like length, content, initial_index, and enhanced animation controls
  • Introduced TabAlignment enum and related tab indicator customization options

Reviewed Changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
sdk/python/packages/flet/src/flet/controls/types.py Removed duplicate TabAlignment enum definition
sdk/python/packages/flet/src/flet/controls/theme.py Renamed TabsTheme to TabBarTheme with updated properties
sdk/python/packages/flet/src/flet/controls/material/tabs.py Major refactor splitting Tabs into TabBar, TabBarView, and Tabs components
sdk/python/packages/flet/src/flet/controls/material/elevated_button.py Refactored style handling to use copy_with pattern
packages/flet/lib/src/controls/tabs.dart Complete rewrite implementing separate TabBar and TabBarView controls
sdk/python/examples/controls/tabs/*.py Updated examples to use new TabBar/TabBarView structure
Documentation files Updated navigation and documentation structure for new components

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

Copy link

@SourceryAI SourceryAI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@FeodorFitsner

This comment was marked as resolved.

@FeodorFitsner

This comment was marked as resolved.

@FeodorFitsner FeodorFitsner merged commit 81a74b6 into main Aug 6, 2025
3 checks passed
@FeodorFitsner FeodorFitsner deleted the v1-improve-tabs branch August 6, 2025 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhance Tabs for complex layouts [v1] Container's decoration not rendered inside Tabs Tabs dont change while asynchronously creation

4 participants