Screen-local Overlay State

Represent dialogs and sheets with OverlayRequest? and render them through ScreenOverlayHost or AnimatedScreenOverlayHost. Clear or replace the request to update the visible overlay. The workflow remains easy to review.

Single overlay slot

Model the overlay as OverlayRequest? and clear it to dismiss. A null value means that no overlay is visible.

Dialog and sheet support

Use DialogRequest and BottomSheetRequest with optional payload data. The payload carries the data needed to build that overlay.

Back order control

Dismiss the overlay first, then pop pages through back-scope widgets. This keeps dismissal and page navigation in one explicit order.

Overlay Host Pattern

Keep overlay in state and build overlay UI through overlayBuilder.

Overlay State Rule

Animated Overlay Host

return AnimatedScreenOverlayHost(
  overlay: _overlay,
  onDismiss: _dismissOverlay,
  overlayBuilder: (context, req, dismiss) => switch (req) {
    DialogRequest(key: 'hello') => AlertDialog(
      title: const Text('Hello'),
      actions: [TextButton(onPressed: dismiss, child: const Text('Close'))],
    ),
    _ => null,
  },
  child: DeclarativePagesNavigator(
    pages: _pages,
    buildPage: _buildPage,
    onPopTop: _popTop,
    canPopTop: () => _overlay == null,
  ),
);
Important

When overlay is visible, block pop gestures with canPopTop to avoid back-swipe inconsistency on iOS.