showWithCustomHeader static method

Future<int?> showWithCustomHeader({
  1. required BuildContext context,
  2. required String title,
  3. String? subtitle,
  4. double? subtitleSize,
  5. Color? subtitleColor,
  6. String? message,
  7. List<CNSheetItem> items = const [],
  8. List<CNSheetItemRow> itemRows = const [],
  9. List<CNSheetInlineActions> inlineActions = const [],
  10. List<CNSheetDetent> detents = const [CNSheetDetent.large],
  11. bool prefersGrabberVisible = true,
  12. bool isModal = true,
  13. bool prefersEdgeAttachedInCompactHeight = false,
  14. bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
  15. double? preferredCornerRadius,
  16. void onInlineActionSelected(
    1. int rowIndex,
    2. int actionIndex
    )?,
  17. void onItemSelected(
    1. int index
    )?,
  18. void onItemRowSelected(
    1. int rowIndex,
    2. int actionIndex
    )?,
  19. double? headerTitleSize,
  20. FontWeight? headerTitleWeight,
  21. Color? headerTitleColor,
  22. String headerTitleAlignment = 'left',
  23. double? headerHeight,
  24. Color? headerBackgroundColor,
  25. bool showHeaderDivider = true,
  26. Color? headerDividerColor,
  27. String closeButtonPosition = 'trailing',
  28. String closeButtonIcon = 'xmark',
  29. double? closeButtonSize,
  30. Color? closeButtonColor,
  31. Color? itemBackgroundColor,
  32. Color? itemTextColor,
  33. Color? itemTintColor,
  34. BaseParam? baseParam,
})

Shows a native sheet with custom header (title + close button).

This is like the Apple Notes formatting sheet - it has a custom header bar with the title on the left and a close button (X) on the right.

Key differences from show():

  • Custom header with title and close button (like Notes app)
  • Title is displayed in the header bar, not in the content area
  • Close button allows manual dismissal
  • Still supports nonmodal behavior with isModal: false
  • Full control over header styling
  • Supports inline action buttons (horizontal rows of buttons)
  • Supports item rows (side-by-side items with equal width)

Example:

await BaseNativeSheet.showWithCustomHeader(
  context: context,
  title: 'Format',
  headerTitleSize: 20,
  headerTitleWeight: FontWeight.w600,
  headerHeight: 56,
  inlineActions: [
    CNSheetInlineActions(
      actions: [
        CNSheetInlineAction(label: 'B', icon: 'bold', isToggled: true),
        CNSheetInlineAction(label: 'I', icon: 'italic'),
      ],
    ),
  ],
  items: [
    CNSheetItem(title: 'Bold', icon: 'bold'),
    CNSheetItem(title: 'Italic', icon: 'italic'),
  ],
  onInlineActionSelected: (rowIndex, actionIndex) {
    print('Inline action: row $rowIndex, action $actionIndex');
  },
  onItemSelected: (index) {
    print('Item selected: $index');
  },
  detents: [CNSheetDetent.custom(280)],
  isModal: false, // Nonmodal - can interact with background
);

context - Build context for presentation title - Title displayed in the header (required for custom header) subtitle - Optional subtitle below the title in header message - Optional message below the header items - List of items to display (full width, vertical list) itemRows - List of item rows (side-by-side items with equal width) inlineActions - List of inline action button rows detents - Heights at which the sheet can rest prefersGrabberVisible - Whether to show the grabber handle isModal - Whether the sheet blocks background interaction

Callbacks: onItemSelected - Callback for when a vertical list item is tapped (receives index) onInlineActionSelected - Callback for inline action buttons (receives rowIndex, actionIndex)

Header Styling Options: headerTitleSize - Font size for the title (default: 20) headerTitleWeight - Font weight for the title (default: semibold/600) headerTitleColor - Color for the title (default: label color) headerTitleAlignment - Alignment of title: 'left', 'center', 'right' (default: 'left') headerHeight - Height of the header bar (default: 56) headerBackgroundColor - Background color of the header (default: system background) showHeaderDivider - Whether to show divider below header (default: true) headerDividerColor - Color of the header divider (default: separator color) closeButtonPosition - Position of close button: 'leading' or 'trailing' (default: 'trailing') closeButtonIcon - SF Symbol name for close button (default: 'xmark') closeButtonSize - Size of the close button icon (default: 17) closeButtonColor - Color of the close button (default: label color) 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) baseParam - Platform override parameter

Implementation

static Future<int?> showWithCustomHeader({
  required BuildContext context,
  required String title,
  String? subtitle,
  double? subtitleSize,
  Color? subtitleColor,
  String? message,
  List<CNSheetItem> items = const [],
  List<CNSheetItemRow> itemRows = const [],
  List<CNSheetInlineActions> inlineActions = const [],
  List<CNSheetDetent> detents = const [CNSheetDetent.large],
  bool prefersGrabberVisible = true,
  bool isModal = true,
  bool prefersEdgeAttachedInCompactHeight = false,
  bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
  double? preferredCornerRadius,
  // Callbacks
  void Function(int rowIndex, int actionIndex)? onInlineActionSelected,
  void Function(int index)? onItemSelected,
  void Function(int rowIndex, int itemIndex)? onItemRowSelected,

  // Header styling
  double? headerTitleSize,
  FontWeight? headerTitleWeight,
  Color? headerTitleColor,
  String headerTitleAlignment = 'left',
  double? headerHeight,
  Color? headerBackgroundColor,
  bool showHeaderDivider = true,
  Color? headerDividerColor,
  String closeButtonPosition = 'trailing',
  String closeButtonIcon = 'xmark',
  double? closeButtonSize,
  Color? closeButtonColor,
  // Item styling
  Color? itemBackgroundColor,
  Color? itemTextColor,
  Color? itemTintColor,
  BaseParam? baseParam,
}) async {
  final param = baseParam ?? BaseParam();

  // Determine if we should use Cupertino or Material implementation
  final useCupertino = param.forceUseCupertino ||
                      (!param.forceUseMaterial && _shouldUseCupertino());

  if (useCupertino) {
    return await CNSheet.showWithCustomHeader(
      context: context,
      title: title,
      subtitle: subtitle,
      subtitleSize: subtitleSize,
      subtitleColor: subtitleColor,
      message: message,
      items: items,
      itemRows: itemRows,
      inlineActions: inlineActions,
      detents: detents,
      prefersGrabberVisible: prefersGrabberVisible,
      isModal: isModal,
      prefersEdgeAttachedInCompactHeight: prefersEdgeAttachedInCompactHeight,
      widthFollowsPreferredContentSizeWhenEdgeAttached: widthFollowsPreferredContentSizeWhenEdgeAttached,
      preferredCornerRadius: preferredCornerRadius,
      onInlineActionSelected: onInlineActionSelected,
      onItemSelected: onItemSelected,
      onItemRowSelected: onItemRowSelected,
      headerTitleSize: headerTitleSize,
      headerTitleWeight: headerTitleWeight,
      headerTitleColor: headerTitleColor,
      headerTitleAlignment: headerTitleAlignment,
      headerHeight: headerHeight,
      headerBackgroundColor: headerBackgroundColor,
      showHeaderDivider: showHeaderDivider,
      headerDividerColor: headerDividerColor,
      closeButtonPosition: closeButtonPosition,
      closeButtonIcon: closeButtonIcon,
      closeButtonSize: closeButtonSize,
      closeButtonColor: closeButtonColor,
      itemBackgroundColor: itemBackgroundColor,
      itemTextColor: itemTextColor,
      itemTintColor: itemTintColor,
    );
  } else {
    return await _NativeSheetMaterial.showWithCustomHeader(
      context: context,
      title: title,
      subtitle: subtitle,
      subtitleSize: subtitleSize,
      subtitleColor: subtitleColor,
      message: message,
      items: items,
      itemRows: itemRows,
      inlineActions: inlineActions,
      detents: detents,
      prefersGrabberVisible: prefersGrabberVisible,
      isModal: isModal,
      prefersEdgeAttachedInCompactHeight: prefersEdgeAttachedInCompactHeight,
      widthFollowsPreferredContentSizeWhenEdgeAttached: widthFollowsPreferredContentSizeWhenEdgeAttached,
      preferredCornerRadius: preferredCornerRadius,
      onInlineActionSelected: onInlineActionSelected,
      onItemSelected: onItemSelected,
      onItemRowSelected: onItemRowSelected,
      headerTitleSize: headerTitleSize,
      headerTitleWeight: headerTitleWeight,
      headerTitleColor: headerTitleColor,
      headerTitleAlignment: headerTitleAlignment,
      headerHeight: headerHeight,
      headerBackgroundColor: headerBackgroundColor,
      showHeaderDivider: showHeaderDivider,
      headerDividerColor: headerDividerColor,
      closeButtonPosition: closeButtonPosition,
      closeButtonIcon: closeButtonIcon,
      closeButtonSize: closeButtonSize,
      closeButtonColor: closeButtonColor,
      itemBackgroundColor: itemBackgroundColor,
      itemTextColor: itemTextColor,
      itemTintColor: itemTintColor,
    );
  }
}