Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popup menu on NavigationSheet overflows screen bounds #167

Open
fujidaiti opened this issue Jun 10, 2024 · 2 comments
Open

Popup menu on NavigationSheet overflows screen bounds #167

fujidaiti opened this issue Jun 10, 2024 · 2 comments
Assignees
Labels
bug Something isn't working has workaround There is a workaround that temporarily or partially solves the issue P1
Milestone

Comments

@fujidaiti
Copy link
Owner

If the navigation sheet is not fullscreen, a popup menu may exceed the screen boundaries, depending on where the popup appears.

RocketSim_Recording_iPhone_15_6.1_2024-06-10_20.32.47.mp4
Code
import 'package:flutter/material.dart';
import 'package:smooth_sheets/smooth_sheets.dart';

void main() {
  runApp(const _MyApp());
}

class _MyApp extends StatelessWidget {
  const _MyApp();

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Stack(
        children: [
          Scaffold(),
          _Sheet(),
        ],
      ),
    );
  }
}

final _transitionObserver = NavigationSheetTransitionObserver();

class _Sheet extends StatelessWidget {
  const _Sheet();

  @override
  Widget build(BuildContext context) {
    return NavigationSheet(
      transitionObserver: _transitionObserver,
      child: Material(
        color: Colors.blue,
        child: Navigator(
          observers: [_transitionObserver],
          onGenerateRoute: (settings) {
            return DraggableNavigationSheetRoute(
              builder: (context) => const _NestedPage(),
            );
          },
        ),
      ),
    );
  }
}

class _NestedPage extends StatelessWidget {
  const _NestedPage();

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.lightBlue[100],
      width: double.infinity,
      height: 500,
      child: SafeArea(
        child: Align(
          alignment: Alignment.bottomCenter,
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              DropdownMenu(
                initialSelection: 'Red',
                label: const Text('Color'),
                onSelected: (color) {},
                dropdownMenuEntries:
                    ['Red', 'Green', 'Blue', 'Grey'].map((color) {
                  return DropdownMenuEntry(value: color, label: color);
                }).toList(),
              ),
              DropdownButton(
                value: 'Option 1',
                menuMaxHeight: 150,
                onChanged: (newValue) {},
                items: ['Option 1', 'Option 2', 'Option 3', 'Option 4']
                    .map((value) {
                  return DropdownMenuItem(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
@fujidaiti fujidaiti self-assigned this Jun 10, 2024
@fujidaiti fujidaiti added bug Something isn't working P1 labels Jun 10, 2024
@fujidaiti fujidaiti added this to the v1 milestone Jun 10, 2024
@fujidaiti
Copy link
Owner Author

If the sheet content is wrapped in a widget with a predefined height (e.g. the Container in the above code), we can workaround this issue by inserting an Overlay widget directly below it (see the following patch). This only works for DropdownMenu and not for DropdownMenuButton, due to the differences in their internal implementations.

class _NestedPage extends StatelessWidget {
  const _NestedPage();

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.lightBlue[100],
      width: double.infinity,
      height: 500,
-       child: SafeArea(
+      child: Overlay(
+        initialEntries: [
+          OverlayEntry(
+            opaque: true,
+            maintainState: true,
+            builder: (_) {
+              return SafeArea(
                child: Align(
                  alignment: Alignment.bottomCenter,
                  child: Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      DropdownMenu(
                        initialSelection: 'Red',
                        label: const Text('Color'),
                        onSelected: (color) {},
                        dropdownMenuEntries:
                            ['Red', 'Green', 'Blue', 'Grey'].map((color) {
                          return DropdownMenuEntry(value: color, label: color);
                        }).toList(),
                      ),
                      DropdownButton(
                        value: 'Option 1',
                        menuMaxHeight: 150,
                        onChanged: (newValue) {},
                        items: ['Option 1', 'Option 2', 'Option 3', 'Option 4']
                            .map((value) {
                          return DropdownMenuItem(
                            value: value,
                            child: Text(value),
                          );
                        }).toList(),
                      ),
                    ],
                  ),
                ),
+              );
+            },
+          )
+        ],
      ),
    );
  }
}
RocketSim_Recording_iPhone_15_6.1_2024-06-12_00.58.53.mp4

@fujidaiti fujidaiti added the has workaround There is a workaround that temporarily or partially solves the issue label Jun 11, 2024
@fujidaiti
Copy link
Owner Author

An idea to resolve this issue:

  1. Change SheetContentScaffold to have an Overlay widget.
  2. Change SheetContentScaffold to resize itself to fit the content widget. This will also resize the Overlay, ensuring that popup menus appear within the content viewport.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working has workaround There is a workaround that temporarily or partially solves the issue P1
Projects
None yet
Development

No branches or pull requests

1 participant