Skip to content

feat: add use_dialog hook for declarative dialog management#6335

Open
FeodorFitsner wants to merge 8 commits intomainfrom
declr-dialogs-api
Open

feat: add use_dialog hook for declarative dialog management#6335
FeodorFitsner wants to merge 8 commits intomainfrom
declr-dialogs-api

Conversation

@FeodorFitsner
Copy link
Contributor

@FeodorFitsner FeodorFitsner commented Mar 21, 2026

Summary

  • Add use_dialog() hook that portals a DialogControl to page._dialogs overlay from within @component functions
  • Uses frozen diff (patch_control(frozen=True)) to send only actual property deltas on re-render, preserving Flutter widget identity (e.g. TextField cursor position)
  • Automatically manages open=True/open=False lifecycle and cleanup on unmount
  • Includes two example apps: basic delete confirmation dialog and multi-file list with rename/delete dialogs

Test plan

  • Run use_dialog_basic.py — verify dialog show/dismiss, async delete with "Deleting..." state, cancel
  • Run use_dialog_multiple.py — verify typing in rename TextField preserves cursor, rename/delete work across multiple files
  • Verify imperative page.show_dialog() still works alongside use_dialog
  • Run existing tests: cd sdk/python && python -m pytest

🤖 Generated with Claude Code

Summary by Sourcery

Introduce a declarative dialog management hook for Flet components and demonstrate its usage with example apps.

New Features:

  • Add a use_dialog hook to declaratively portal DialogControl instances to the page dialog overlay with automatic lifecycle handling.
  • Add two declarative example apps showcasing basic and multiple concurrent dialogs using the new use_dialog hook.

Enhancements:

  • Export the use_dialog hook from the main Flet Python package for external use.

Documentation:

  • Document the use_dialog hook in the hooks/types reference and add it to the mkdocs navigation.

Replace setattr field-copy loop with patch_control(frozen=True) so only
actual property deltas are sent to Flutter. This preserves widget identity
via _migrate_state (e.g. TextField cursor position) and avoids full
re-creation of structural children on every re-render.

Also update use_dialog_multiple example with a list of files to
demonstrate rename/delete on multiple items.
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

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 21, 2026

Deploying flet-examples with  Cloudflare Pages  Cloudflare Pages

Latest commit: cde433c
Status: ✅  Deploy successful!
Preview URL: https://7f96e30d.flet-examples.pages.dev
Branch Preview URL: https://declr-dialogs-api.flet-examples.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 21, 2026

Deploying flet-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: cde433c
Status: ✅  Deploy successful!
Preview URL: https://6e8b1d6b.flet-docs.pages.dev
Branch Preview URL: https://declr-dialogs-api.flet-docs.pages.dev

View logs

showDialog's future completes when the route is popped (before the exit animation finishes), causing the dismiss event to fire too early. Capture the ModalRoute in the dialog builder and wait for its .completed Future to finish before updating _open/open properties and triggering the 'dismiss' event. Adds a comment explaining the behavior and moves route capture into the builder.
Keep dismissed dialogs alive in _dialogs.controls and ref until the
next render so they remain in session.__index (WeakValueDictionary)
long enough for Flutter's dismiss event to reach Python handlers.

Remove __prev_lists sync from deferred cleanup to avoid poisoning
the diff state when other hooks append to _dialogs.controls in the
same render cycle.

Add chained dialogs example demonstrating on_dismiss-based sequencing.
…e controls

Wait for TransitionRoute.completed before firing dismiss event in
BottomSheet, CupertinoAlertDialog, CupertinoBottomSheet, DatePicker,
DateRangePicker, and TimePicker — matching the fix already applied to
AlertDialog.
Make code samples runnable by adding `ft.run(lambda page: page.render(App))` to the declarative dialogs cookbook. Updated two example blocks in sdk/python/packages/flet/docs/cookbook/declarative-dialogs.md so the App examples are executed when copied/run.
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.

1 participant