Material sheets, menus and popovers that adapt to the window size, showing bottom sheets on mobile and dialogs, popovers and popup menus on desktop
  • Dart 93.8%
  • Nix 6.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-03 14:51:33 -05:00
assets/screenshots initial commit 2026-11-03 14:51:33 -05:00
lib initial commit 2026-11-03 14:51:33 -05:00
test initial commit 2026-11-03 14:51:33 -05:00
.envrc initial commit 2026-11-03 14:51:33 -05:00
.gitignore initial commit 2026-11-03 14:51:33 -05:00
.metadata initial commit 2026-11-03 14:51:33 -05:00
analysis_options.yaml initial commit 2026-11-03 14:51:33 -05:00
CHANGELOG.md initial commit 2026-11-03 14:51:33 -05:00
flake.lock initial commit 2026-11-03 14:51:33 -05:00
flake.nix initial commit 2026-11-03 14:51:33 -05:00
LICENSE initial commit 2026-11-03 14:51:33 -05:00
pubspec.lock initial commit 2026-11-03 14:51:33 -05:00
pubspec.yaml initial commit 2026-11-03 14:51:33 -05:00
README.md initial commit 2026-11-03 14:51:33 -05:00

Material sheets, menus and popovers that adapt to the window size. On narrow windows they show as bottom sheets, and on wide windows as dialogs, popovers and popup menus.

Features

  • showAdaptiveSheet: a dialog on desktop, or a bottom sheet on mobile
  • showAdaptivePopover: a popover anchored to a widget or point on desktop, or a bottom sheet on mobile
  • showAdaptiveMenu: a popup menu on desktop, or a bottom sheet of the same PopupMenuEntrys on mobile
  • AdaptiveMenuButton: like PopupMenuButton, but shows a bottom sheet on mobile
  • SheetLayout: a title, scrollable content and actions, laid out for both sheets and dialogs
  • AdaptiveBreakpoint: configure the width where the desktop layout starts

Screenshots

Mobile Desktop
Sheet A bottom sheet asking to delete conversations A dialog asking to delete conversations
Menu A bottom sheet with menu items A popup menu over the menu button
Popover A bottom sheet with inbox details A popover with inbox details below the info button

Getting started

Add the package to your project with flutter pub add material_adaptive_sheets.

Usage

All of the show methods are extensions on BuildContext, and return the value the sheet was closed with.

Sheets

final confirmed = await context.showAdaptiveSheet<bool>(
  (context) => SheetLayout(
    title: const Text("Delete message?"),
    actions: [
      TextButton(
        onPressed: () => Navigator.of(context).pop(false),
        child: const Text("Cancel"),
      ),
      FilledButton(
        onPressed: () => Navigator.of(context).pop(true),
        child: const Text("Delete"),
      ),
    ],
    children: [const Text("This can't be undone.")],
  ),
);

Menus

AdaptiveMenuButton<String>(
  icon: const Icon(Icons.more_vert),
  itemBuilder: (context) => const [
    PopupMenuItem(value: "edit", child: Text("Edit")),
    PopupMenuItem(value: "delete", child: Text("Delete")),
  ],
  onSelected: (value) => print(value),
);

Or show a menu at a point, like where the user right clicked:

GestureDetector(
  onSecondaryTapUp: (details) => context.showAdaptiveMenu(
    items,
    globalPosition: details.globalPosition,
  ),
  child: child,
);

Popovers

IconButton(
  icon: const Icon(Icons.info),
  onPressed: () => context.showAdaptivePopover(
    (context) => const Padding(
      padding: EdgeInsets.all(16),
      child: Text("Some details"),
    ),
  ),
);

On desktop, the popover opens below the widget the context belongs to, or above it if there isn't room. Pass anchor to open it somewhere else, such as context.globalRectAt(details.globalPosition).

Breakpoint

By default, the desktop layout is used for windows wider than 650 logical pixels. To change this, wrap your app in an AdaptiveBreakpoint:

AdaptiveBreakpoint(
  width: 800,
  child: MaterialApp(...),
);

context.isDesktop is also exported, so the rest of your layout can use the same breakpoint.