Overlay

Popover Menu

A popover menu displays a menu in a portal aligned to a child.

FHeader(
  title: const Text('Edit Notes'),
  suffixes: [
    FPopoverMenu(
      autofocus: true,
      menuAnchor: Alignment.topRight,
      childAnchor: Alignment.bottomRight,
      menu: [
        FItemGroup(
          children: [
            FItem(prefix: const Icon(FIcons.user), title: const Text('Personalization'), onPress: () {}),
            FItem(prefix: const Icon(FIcons.paperclip), title: const Text('Add attachments'), onPress: () {}),
            FItem(prefix: const Icon(FIcons.qrCode), title: const Text('Scan Document'), onPress: () {}),
          ],
        ),
        FItemGroup(
          children: [
            FItem(prefix: const Icon(FIcons.list), title: const Text('List View'), onPress: () {}),
            FItem(prefix: const Icon(FIcons.layoutGrid), title: const Text('Grid View'), onPress: () {}),
          ],
        ),
      ],
      builder: (_, controller, _) => FHeaderAction(icon: const Icon(FIcons.ellipsis), onPress: controller.toggle),
    ),
  ],
);

CLI

To generate and customize this style:

dart run forui style create popover-menu

Usage

FPopoverMenu(...)

FPopoverMenu(
  control: FPopoverControl.managed(),
  scrollController: ScrollController(),
  style: (style) => style.copyWith(...),
  cacheExtent: 100,
  maxHeight: double.infinity,
  dragStartBehavior: DragStartBehavior.start,
  divider: FItemDivider.full,
  menuAnchor: Alignment.topCenter,
  childAnchor: Alignment.bottomCenter,
  spacing: FPortalSpacing.spacing(4),
  overflow: FPortalOverflow.flip,
  offset: Offset.zero,
  groupId: 'popover-menu-group',
  hideRegion: FPopoverHideRegion.excludeChild,
  onTapHide: () {},
  autofocus: true,
  focusNode: FocusScopeNode(),
  onFocusChange: (focused) {},
  traversalEdgeBehavior: TraversalEdgeBehavior.closedLoop,
  menu: [FItemGroup(children: [])],
  builder: (context, controller, child) => const Placeholder(),
  child: const Placeholder(),
);

FPopoverMenu.tiles(...)

FPopoverMenu.tiles(
  control: FPopoverControl.managed(),
  scrollController: ScrollController(),
  style: (style) => style.copyWith(...),
  cacheExtent: 100,
  maxHeight: double.infinity,
  dragStartBehavior: DragStartBehavior.start,
  divider: FTileDivider.full,
  menuAnchor: Alignment.topCenter,
  childAnchor: Alignment.bottomCenter,
  spacing: FPortalSpacing.spacing(4),
  overflow: FPortalOverflow.flip,
  offset: Offset.zero,
  groupId: 'popover-menu-group',
  hideRegion: FPopoverHideRegion.excludeChild,
  autofocus: true,
  focusNode: FocusScopeNode(),
  onFocusChange: (focused) {},
  traversalEdgeBehavior: TraversalEdgeBehavior.closedLoop,
  menu: [FTileGroup(children: [])],
  builder: (context, controller, child) => const Placeholder(),
  child: const Placeholder(),
);

Examples

Tiles

FHeader(
  title: const Text('Edit Notes'),
  suffixes: [
    FPopoverMenu.tiles(
      autofocus: true,
      menuAnchor: Alignment.topRight,
      childAnchor: Alignment.bottomRight,
      menu: [
        FTileGroup(
          children: [
            FTile(prefix: const Icon(FIcons.user), title: const Text('Personalization'), onPress: () {}),
            FTile(prefix: const Icon(FIcons.paperclip), title: const Text('Add attachments'), onPress: () {}),
            FTile(prefix: const Icon(FIcons.qrCode), title: const Text('Scan Document'), onPress: () {}),
          ],
        ),
        FTileGroup(
          children: [
            FTile(prefix: const Icon(FIcons.list), title: const Text('List View'), onPress: () {}),
            FTile(prefix: const Icon(FIcons.layoutGrid), title: const Text('Grid View'), onPress: () {}),
          ],
        ),
      ],
      builder: (_, controller, _) => FHeaderAction(icon: const Icon(FIcons.ellipsis), onPress: controller.toggle),
    ),
  ],
);

On this page