flutter_preview_context_menu 0.2.1 copy "flutter_preview_context_menu: ^0.2.1" to clipboard
flutter_preview_context_menu: ^0.2.1 copied to clipboard

A flexible WhatsApp-style context menu for Flutter with custom previews, top content, actions, animation, and viewport-aware overflow handling.

flutter_preview_context_menu #

A flexible contextual menu for Flutter inspired by modern messaging apps. It is designed for chat bubbles, media previews, list rows, files, cards, or any widget that needs a long-press action menu.

Features #

  • Long-press context menu for any widget.
  • Optional custom preview, separate from the pressed child.
  • Optional top content for reactions, chips, shortcuts, or any custom widget.
  • Configurable action rows with icons, descriptions, trailing widgets, disabled states, separators, and destructive styling.
  • Viewport-aware positioning so the preview and actions stay on screen when possible.
  • Automatic horizontal alignment by default: menus stay centered on the pressed widget when they fit, then align to the closest source edge near screen boundaries.
  • Configurable panel shape, background color, foreground color, barrier color, and blur.
  • Keyboard-aware focus handling: focused inputs are unfocused while the menu is open and restored when it closes.
  • Smooth entrance animations for the preview, optional top content, and action panel.
  • Widget-based custom actions through actionChildren, useful when actions need keys or fully custom layouts.
  • Optional animated preview from the original source position.
  • No app-specific dependencies.

Basic usage #

ContextMenuRegion(
  actions: [
    ContextMenuActionData(
      label: 'Reply',
      icon: const Icon(Icons.reply),
      onPressed: () {
        // Run your own logic here.
      },
    ),
    ContextMenuActionData(
      label: 'Delete',
      icon: const Icon(Icons.delete_outline),
      destructive: true,
      separatedBefore: true,
      onPressed: () {
        // Confirm or delete from the caller.
      },
    ),
  ],
  child: const Text('Long press me'),
)

alignment is optional. When omitted, the menu chooses a dynamic alignment from the pressed widget position. Pass AlignmentDirectional.centerStart, AlignmentDirectional.center, or AlignmentDirectional.centerEnd only when the caller needs a fixed layout.

Appearance #

The action panel uses ColorScheme.surfaceContainer by default and keeps the same rounded shape used by modern messaging menus. Override only what your app needs:

ContextMenuRegion(
  panelShape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(28),
  ),
  panelBackgroundColor: Theme.of(context).colorScheme.surfaceContainerHighest,
  panelForegroundColor: Theme.of(context).colorScheme.onSurface,
  barrierColor: Colors.black.withValues(alpha: 0.20),
  blur: 14,
  actions: actions,
  child: child,
)

Custom preview #

The preview defaults to child. Provide preview when the menu should show a different or more compact widget.

ContextMenuRegion(
  child: messageBubble,
  preview: ConstrainedBox(
    constraints: const BoxConstraints(maxWidth: 280),
    child: messageBubblePreview,
  ),
  actions: actions,
)

Widget-based actions #

Use actionChildren when an action needs a Key, a custom layout, or behavior that does not fit ContextMenuActionData.

ContextMenuRegion(
  actionChildren: [
    ContextMenuAction(
      key: const ValueKey('reply-action'),
      label: 'Reply',
      icon: const Icon(Icons.reply),
      onPressed: () {
        // The menu closes before this callback runs.
      },
    ),
  ],
  child: messageBubble,
)

Reactions or top content #

topContent accepts any widget. This keeps reactions and shortcuts outside of the package’s business logic.

ContextMenuRegion(
  topContent: Container(
    padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(24),
    ),
    child: const Text('👍 ❤️ 😂 😮 😢 🙏'),
  ),
  actions: actions,
  child: messageBubble,
)

Overflow behavior #

Use overflowStrategy when the menu may be opened near the screen edges or when the action list can be long.

ContextMenuRegion(
  overflowStrategy: ContextMenuOverflowStrategy.repositionThenScroll,
  maxPanelHeightFactor: 0.45,
  actions: actions,
  child: child,
)

Available strategies:

  • repositionThenScroll: tries to reposition the menu and constrains the action panel if needed.
  • scrollAll: lets the whole contextual content scroll together.

Animation #

The default preview animates from the original widget position. If you pass a custom preview, enable animatePreview when that transition is still desired.

ContextMenuRegion(
  preview: customPreview,
  animatePreview: true,
  dismissKeyboardOnOpen: true,
  restoreFocusOnClose: true,
  actions: actions,
  child: child,
)

Notes #

The package only renders the interaction. It intentionally does not perform app actions such as replying, copying, reporting, deleting, or mutating data. Those side effects belong to the app through each action’s onPressed.

ContextMenuActionData does not require an identifier. If you need analytics or routing, keep that mapping in your app layer and call it from onPressed.

1
likes
0
points
410
downloads

Publisher

unverified uploader

Weekly Downloads

A flexible WhatsApp-style context menu for Flutter with custom previews, top content, actions, animation, and viewport-aware overflow handling.

Homepage

License

unknown (license)

Dependencies

flutter

More

Packages that depend on flutter_preview_context_menu