show static method

Future<int?> show({
  1. required BuildContext context,
  2. String? title,
  3. String? message,
  4. List<CNSheetItem> items = const [],
  5. List<CNSheetDetent> detents = const [CNSheetDetent.large],
  6. bool prefersGrabberVisible = true,
  7. bool isModal = true,
  8. bool prefersEdgeAttachedInCompactHeight = false,
  9. bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
  10. double? preferredCornerRadius,
  11. Color? itemBackgroundColor,
  12. Color? itemTextColor,
  13. Color? itemTintColor,
  14. void onItemSelected(
    1. int index
    )?,
})

Shows a native sheet with the given content.

Uses native UISheetPresentationController for rendering. All items are rendered as native UIKit components for optimal performance and true nonmodal behavior.

title - Optional title for the sheet (displays in content area with close button) message - Optional message below the title items - List of items to display in the sheet detents - Heights at which the sheet can rest (iOS only, defaults to large) prefersGrabberVisible - Whether to show the grabber handle (iOS only) isModal - Whether the sheet is modal (blocks interaction with parent view). Default is true. Set to false for nonmodal sheets that allow background interaction (iOS/iPadOS only, always modal on macOS/visionOS/watchOS). prefersEdgeAttachedInCompactHeight - Whether sheet attaches to edge in compact height widthFollowsPreferredContentSizeWhenEdgeAttached - Whether width follows preferred content size preferredCornerRadius - Custom corner radius for the sheet itemBackgroundColor - Background color for sheet item buttons (default: clear) itemTextColor - Text color for sheet item buttons (default: system label) itemTintColor - Tint color for icons in sheet item buttons (default: system tint) onItemSelected - Callback invoked when a sheet item is tapped, receives the item index

Implementation

static Future<int?> show({
  required BuildContext context,
  String? title,
  String? message,
  List<CNSheetItem> items = const [],
  List<CNSheetDetent> detents = const [CNSheetDetent.large],
  bool prefersGrabberVisible = true,
  bool isModal = true,
  bool prefersEdgeAttachedInCompactHeight = false,
  bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
  double? preferredCornerRadius,
  Color? itemBackgroundColor,
  Color? itemTextColor,
  Color? itemTintColor,
  void Function(int index)? onItemSelected,
}) async {
  try {
    // Initialize handlers on first call
    _initializeHandlers();

    // Create a completer to wait for the native dismissal callback
    final completer = Completer<int?>();
    final sheetId = _generateSheetId();
    _pendingSheets[sheetId] = completer;

    // Set up callback handler if provided
    if (onItemSelected != null) {
      _channel.setMethodCallHandler((call) async {
        if (call.method == 'onItemSelected') {
          final index = call.arguments['index'] as int;
          onItemSelected(index);
        } else if (call.method == 'onDismiss') {
          final args = call.arguments as Map;
          final selectedIndex = args['selectedIndex'] as int?;

          // Complete the pending sheet completer for onDismiss
          if (_pendingSheets.isNotEmpty) {
            final key = _pendingSheets.keys.first;
            final completer = _pendingSheets.remove(key);
            completer?.complete(selectedIndex == -1 ? null : selectedIndex);
          }
        }
      });
    }

    // Call native method (result will be null from this call)
    await _channel.invokeMethod('showSheet', {
      'title': title,
      'message': message,
      'items': items.map((item) => item.toMap()).toList(),
      'detents': detents.map((d) => d.toMap()).toList(),
      'prefersGrabberVisible': prefersGrabberVisible,
      'isModal': isModal,
      'prefersEdgeAttachedInCompactHeight':
          prefersEdgeAttachedInCompactHeight,
      'widthFollowsPreferredContentSizeWhenEdgeAttached':
          widthFollowsPreferredContentSizeWhenEdgeAttached,
      'preferredCornerRadius': preferredCornerRadius,
      if (itemBackgroundColor != null)
        'itemBackgroundColor': itemBackgroundColor.value,
      if (itemTextColor != null) 'itemTextColor': itemTextColor.value,
      if (itemTintColor != null) 'itemTintColor': itemTintColor.value,
    });

    // Wait for the sheet dismissal callback to complete the completer
    return completer.future;
  } catch (e) {
    debugPrint('Error showing native sheet: $e');
    return null;
  }
}