showProviderAwareMenu<T> method

Future<T?> showProviderAwareMenu<T>({
  1. required RelativeRect position,
  2. required List<PopupMenuEntry<T>> items,
  3. T? initialValue,
  4. double? elevation,
  5. Color? shadowColor,
  6. Color? surfaceTintColor,
  7. String? semanticLabel,
  8. ShapeBorder? shape,
  9. Color? color,
  10. BoxConstraints? constraints,
  11. Clip clipBehavior = Clip.none,
  12. RouteSettings? routeSettings,
  13. AnimationStyle? popUpAnimationStyle,
  14. bool useRootNavigator = false,
})

Shows a popup menu that maintains access to Riverpod providers.

This automatically wraps the menu items in an UncontrolledProviderScope so that widgets inside the menu can access providers from the parent context.

Implementation

Future<T?> showProviderAwareMenu<T>({
  required RelativeRect position,
  required List<PopupMenuEntry<T>> items,
  T? initialValue,
  double? elevation,
  Color? shadowColor,
  Color? surfaceTintColor,
  String? semanticLabel,
  ShapeBorder? shape,
  Color? color,
  BoxConstraints? constraints,
  Clip clipBehavior = Clip.none,
  RouteSettings? routeSettings,
  AnimationStyle? popUpAnimationStyle,
  bool useRootNavigator = false,
}) {
  // Capture the provider container from the current context
  final container = ProviderScope.containerOf(this);

  // Wrap each menu item in UncontrolledProviderScope
  final wrappedItems = items.map<PopupMenuEntry<T>>((item) {
    if (item is PopupMenuItem<T>) {
      return PopupMenuItem<T>(
        key: item.key,
        value: item.value,
        onTap: item.onTap,
        enabled: item.enabled,
        height: item.height,
        padding: item.padding,
        textStyle: item.textStyle,
        labelTextStyle: item.labelTextStyle,
        mouseCursor: item.mouseCursor,
        child: UncontrolledProviderScope(
          container: container,
          child: item.child ?? const SizedBox.shrink(),
        ),
      );
    } else if (item is CheckedPopupMenuItem<T>) {
      return CheckedPopupMenuItem<T>(
        key: item.key,
        value: item.value,
        checked: item.checked,
        enabled: item.enabled,
        padding: item.padding,
        height: item.height,
        labelTextStyle: item.labelTextStyle,
        mouseCursor: item.mouseCursor,
        onTap: item.onTap,
        child: UncontrolledProviderScope(
          container: container,
          child: item.child ?? const SizedBox.shrink(),
        ),
      );
    }
    // Return other types (like PopupMenuDivider) as-is
    return item;
  }).toList();

  return showMenu<T>(
    context: this,
    position: position,
    items: wrappedItems,
    initialValue: initialValue,
    elevation: elevation,
    shadowColor: shadowColor,
    surfaceTintColor: surfaceTintColor,
    semanticLabel: semanticLabel,
    shape: shape,
    color: color,
    constraints: constraints,
    clipBehavior: clipBehavior,
    routeSettings: routeSettings,
    popUpAnimationStyle: popUpAnimationStyle,
    useRootNavigator: useRootNavigator,
  );
}