Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b4f7436
Add sync navigate wrapper for Page.push_route
FeodorFitsner Mar 18, 2026
60513e4
Initial router implementation
FeodorFitsner Mar 18, 2026
c0fa405
Use modal AlertDialog for auth guard, fix routing
FeodorFitsner Mar 19, 2026
c88fef9
Add typing hints for router, page, and contexts
FeodorFitsner Mar 19, 2026
d99c971
Reorganize router examples; add pyproject files
FeodorFitsner Mar 19, 2026
0621955
feat: Add 'visible' attribute to Component
FeodorFitsner Apr 9, 2026
0130a35
Add manage_views mode to Router for view-stack navigation
FeodorFitsner Apr 9, 2026
3c08739
Add featured_views example; add READMEs to router examples
FeodorFitsner Apr 10, 2026
6929f20
Update router docs to docusaurus/crocodocs format
FeodorFitsner Apr 10, 2026
f86c310
Regenerate sidebars.js; update pubspec.lock transitive deps
FeodorFitsner Apr 10, 2026
ef61cc1
Add Router changelog entry for 0.85.0
FeodorFitsner Apr 10, 2026
06b8f0a
Merge remote-tracking branch 'origin/release/v0.85.0' into router-3
FeodorFitsner Apr 10, 2026
9f58fd3
Add Router entries to sidebars.yml
FeodorFitsner Apr 10, 2026
210206e
fix: update link to NavigationRail documentation in router.md
FeodorFitsner Apr 10, 2026
e7239b5
Merge branch 'release/v0.85.0' into router-3
FeodorFitsner Apr 13, 2026
b7fd442
Add use_view_path hook and fix LocationInfo.pathname
FeodorFitsner Apr 14, 2026
712684e
Add app_drawer router example
FeodorFitsner Apr 14, 2026
5c7220c
Add integration tests for router examples; fix example layouts
FeodorFitsner Apr 14, 2026
aa05cb6
chore: refresh pubspec.lock transitive deps
FeodorFitsner Apr 14, 2026
5b54dac
Document use_view_path() hook
FeodorFitsner Apr 14, 2026
0cfe478
chore: regenerate code_editor golden images
FeodorFitsner Apr 14, 2026
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### New features

* Add declarative `ft.Router` component for `@ft.component` apps with nested routes, layout routes with outlets, dynamic segments, optional segments, splats, custom regex constraints, data loaders, active link detection, authentication patterns, and `manage_views=True` mode for view-stack navigation with swipe-back gestures and `AppBar` back button on mobile ([#6406](https://github.com/flet-dev/flet/pull/6406)) by @FeodorFitsner.
* Add `ft.use_dialog()` hook for declarative dialog management from within `@ft.component` functions, with frozen-diff reactive updates and automatic open/close lifecycle ([#6335](https://github.com/flet-dev/flet/pull/6335)) by @FeodorFitsner.
* Add `scrollable`, `pin_leading_to_top`, and `pin_trailing_to_bottom` properties to `NavigationRail` for scrollable content with optional pinned leading/trailing controls ([#1923](https://github.com/flet-dev/flet/issues/1923), [#6356](https://github.com/flet-dev/flet/pull/6356)) by @ndonkoHenri.
* Add `issues` property to `CodeEditor` (along with `Issue` and `IssueType` types) for displaying code analysis error markers in the gutter, with analysis performed on the Python side ([#6407](https://github.com/flet-dev/flet/pull/6407)) by @FeodorFitsner.
Expand Down
18 changes: 9 additions & 9 deletions client/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.4.1"
charcode:
dependency: transitive
description:
Expand Down Expand Up @@ -359,7 +359,7 @@ packages:
path: "../packages/flet"
relative: true
source: path
version: "0.82.2"
version: "0.85.0"
flet_ads:
dependency: "direct main"
description:
Expand Down Expand Up @@ -911,18 +911,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev"
source: hosted
version: "0.12.17"
version: "0.12.19"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
url: "https://pub.dev"
source: hosted
version: "0.11.1"
version: "0.13.0"
media_kit:
dependency: transitive
description:
Expand Down Expand Up @@ -1628,10 +1628,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
url: "https://pub.dev"
source: hosted
version: "0.7.7"
version: "0.7.10"
torch_light:
dependency: transitive
description:
Expand Down
76 changes: 76 additions & 0 deletions sdk/python/examples/apps/router/active_links/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Active links — nav highlighting with is_route_active()."""

import flet as ft


@ft.component
def Home():
return ft.Text("Home page", size=24)


@ft.component
def Products():
return ft.Text("Products page", size=24)


@ft.component
def Settings():
return ft.Text("Settings page", size=24)


@ft.component
def NavLink(label, path):
"""A navigation link that highlights when its path is active."""
active = ft.is_route_active(path)
return ft.Container(
content=ft.Text(
label,
weight=ft.FontWeight.BOLD if active else ft.FontWeight.NORMAL,
color=ft.Colors.BLUE if active else ft.Colors.ON_SURFACE,
),
bgcolor=ft.Colors.BLUE_50 if active else None,
padding=ft.Padding.symmetric(horizontal=16, vertical=8),
border_radius=8,
on_click=lambda: ft.context.page.navigate(path),
)


@ft.component
def AppLayout():
"""Layout route — NavLink must be inside Router to use is_route_active()."""
outlet = ft.use_route_outlet()
return ft.Column(
[
ft.Row(
[
NavLink("Home", "/"),
NavLink("Products", "/products"),
NavLink("Settings", "/settings"),
]
),
ft.Divider(),
outlet,
]
)


@ft.component
def App():
return ft.SafeArea(
content=ft.Router(
[
ft.Route(
component=AppLayout,
children=[
ft.Route(index=True, component=Home),
ft.Route(path="products", component=Products),
ft.Route(path="settings", component=Settings),
],
),
]
)
)


if __name__ == "__main__":
ft.run(lambda page: page.render(App))
26 changes: 26 additions & 0 deletions sdk/python/examples/apps/router/active_links/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[project]
name = "router-active-links"
version = "1.0.0"
description = "Navigation link highlighting using is_route_active() with bold text and background color."
requires-python = ">=3.10"
keywords = ["router", "active", "navigation", "links", "highlight"]
authors = [{ name = "Flet team", email = "hello@flet.dev" }]
dependencies = ["flet"]

[dependency-groups]
dev = ["flet-cli", "flet-desktop", "flet-web"]

[tool.flet.gallery]
categories = ["Navigation/Router"]

[tool.flet.metadata]
title = "Active links"
controls = ["SafeArea", "Column", "Row", "Container", "Text", "Divider", "Router", "Route"]
layout_pattern = "app-shell"
complexity = "basic"
features = ["is_route_active", "active link styling", "use_route_outlet"]

[tool.flet]
org = "dev.flet"
company = "Flet"
copyright = "Copyright (C) 2023-2026 by Flet"
34 changes: 34 additions & 0 deletions sdk/python/examples/apps/router/app_drawer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# App Settings Drawer

Demonstrates a NavigationDrawer with deep-linkable tabs, driven by nested routes.

## Routes

- `/` — Home
- `/apps` — Apps list
- `/apps/:app_id` — App details (drawer closed)
- `/apps/:app_id/settings/general` — App details with drawer open on General tab
- `/apps/:app_id/settings/permissions` — App details with drawer open on Permissions tab

## How it works

The `:app_id` route has `outlet=True` and two child routes for the settings tabs.
`AppDetails` always renders as a single View. Inside it:

- `use_route_outlet()` returns the matched tab component (or `None` if just `/apps/:app_id`)
- A `use_effect` watches whether the outlet is set and calls `page.open(drawer)` /
`page.close(drawer)` accordingly
- The drawer's `on_dismiss` navigates back to `/apps/:app_id` when the user swipes
the drawer away
- Tab buttons inside the drawer use `is_route_active(..., exact=True)` to highlight
the current tab and navigate between tabs
- The View's `route` is the same (`/apps/:app_id`) regardless of the active tab,
so Flutter's Navigator doesn't animate the View when switching tabs

## View stack

- `/` — 1 view (Home)
- `/apps` — 2 views (Home, AppsList)
- `/apps/2` — 3 views (Home, AppsList, AppDetails); back button to AppsList
- `/apps/2/settings/general` — same 3 views; drawer slides open on top
- `/apps/2/settings/permissions` — same 3 views; drawer stays open, tab content swaps
Loading
Loading