Repository: flutter/flutter
File: packages/flutter/lib/src/cupertino/sheet.dart (Dart)

Code before:
/// ** See code in examples/api/lib/cupertino/sheet/cupertino_sheet.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This example shows how to show a Cupertino Sheet with nested navigation manually
/// set up in order to enable restorable state.
///
/// ** See code in examples/api/lib/cupertino/sheet/cupertino_sheet.2.dart **
/// {@end-tool}
///
/// See also:
///   * [showCupertinoSheet], which is a convenience method for pushing a
///     `CupertinoSheetRoute`, with optional nested navigation built in.
class CupertinoSheetRoute<T> extends PageRoute<T> with _CupertinoSheetRouteTransitionMixin<T> {
  /// Creates a page route that displays an iOS styled sheet.
  CupertinoSheetRoute({super.settings, required this.builder, this.enableDrag = true, this.topGap})
      : assert(topGap == null || (topGap >= 0.0 && topGap <= 1.0), 'topGap must be between 0.0 and 1.0');

  /// Builds the primary contents of the sheet route.
  final WidgetBuilder builder;

  @override
  final bool enableDrag;

  @override
  final double? topGap;

  @override
  Widget buildContent(BuildContext context) {
    final double topPadding = MediaQuery.heightOf(context) * (topGap ?? _kTopGapRatio);
    return MediaQuery.removePadding(
      context: context,
      removeTop: true,
      child: Padding(
        padding: EdgeInsets.only(top: topPadding),
        child: ClipRSuperellipse(
          borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
          child: CupertinoUserInterfaceLevel(
            data: CupertinoUserInterfaceLevelData.elevated,
            child: _CupertinoSheetScope(child: builder(context)),
          ),
        ),
      ),
    );
  }

  /// Checks if a Cupertino sheet view exists in the widget tree above the current
  /// context.
  static bool hasParentSheet(BuildContext context) {
    return _CupertinoSheetScope.maybeOf(context) != null;
  }

Review comment (suggestion):
I think we could make this a little friendlier. We can add a private `_topGap` value. The constructor sets `_topGap` to whatever user defined property, or leaves it null. Then this override only sets a getter `topGap` that returns `_topGap ?? _kTopGapRatio`. Then we can both just use `topGap` everywhere and if another bit of code looks at `topGap` than it will be a reliable source of truth.

Also, I think we don't want to expose a setter for now. In the future we will probably want to enable programmatically changing the top gap while the sheet is open and having it animate the difference, and leaving no open setter for now makes that easier.

Code after:
  }

  @override
  Widget build(BuildContext context) {
    return _StretchDragControllerProvider(
      controller: _stretchDragController,
      child: SizedBox.expand(
        child: AnimatedBuilder(
          animation: _stretchDragAnimation,
          builder: (BuildContext context, Widget? child) {
            return Padding(
              padding: EdgeInsets.only(
                top: MediaQuery.heightOf(context) * _stretchDragAnimation.value,
              ),
              child: _coverSheetSecondaryTransition(
                widget.secondaryRouteAnimation,
                _coverSheetPrimaryTransition(
                  context,
                  widget.primaryRouteAnimation,
                  widget.linearTransition,
                  widget.child,
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

// Internally used to provide the controller for upward stretch animation.
class _StretchDragControllerProvider extends InheritedWidget {
  const _StretchDragControllerProvider({required this.controller, required super.child});

  final AnimationController controller;

  static _StretchDragControllerProvider? maybeOf(BuildContext context) {
    return context.getInheritedWidgetOfExactType<_StretchDragControllerProvider>();
  }

  @override
  bool updateShouldNotify(_StretchDragControllerProvider oldWidget) {
    return false;
  }
}

/// Route for displaying an iOS sheet styled page.
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=5H-WvH5O29I}
///