scrollByViewport method

Future<CockpitScrollStepResult> scrollByViewport({
  1. bool reverse = false,
  2. double viewportFraction = 0.8,
  3. String? scrollableKey,
  4. CockpitLocator? targetLocator,
  5. CockpitLocator? scrollableLocator,
  6. Duration duration = const Duration(milliseconds: 220),
  7. CockpitGestureProfile gestureProfile = CockpitGestureProfile.userLike,
  8. bool continuous = false,
  9. bool postScrollEnsureVisible = true,
  10. bool probeDuringScroll = true,
})

Implementation

Future<CockpitScrollStepResult> scrollByViewport({
  bool reverse = false,
  double viewportFraction = 0.8,
  String? scrollableKey,
  CockpitLocator? targetLocator,
  CockpitLocator? scrollableLocator,
  Duration duration = const Duration(milliseconds: 220),
  CockpitGestureProfile gestureProfile = CockpitGestureProfile.userLike,
  bool continuous = false,
  bool postScrollEnsureVisible = true,
  bool probeDuringScroll = true,
}) async {
  final rootContext = _boundaryKey.currentContext;
  if (rootContext == null) {
    return const CockpitScrollStepResult(didScroll: false);
  }

  final scrollables = _discoverScrollables(rootContext as Element)
      .where((candidate) {
        final position = candidate.state.position;
        if (!position.haveDimensions || position.maxScrollExtent <= 0) {
          return false;
        }
        if (scrollableKey == null || scrollableKey.isEmpty) {
          return true;
        }
        return candidate.keyValue == scrollableKey;
      })
      .toList(growable: false);
  if (scrollables.isEmpty) {
    return const CockpitScrollStepResult(didScroll: false);
  }
  final targetElement = targetLocator == null
      ? null
      : _findMountedElementForLocator(rootContext, targetLocator);
  final selection = _selectScrollableCandidate(
    scrollables,
    targetLocator: targetLocator,
    targetElement: targetElement,
    scrollableLocator: scrollableLocator,
  );
  if (selection == null) {
    final targetMounted = targetElement != null;
    return CockpitScrollStepResult(
      didScroll: false,
      scrollableCandidateCount: scrollables.length,
      targetVisibilityObserved: targetLocator != null,
      targetMounted: targetMounted,
      targetVisible: targetMounted && _locatorIsVisible(targetLocator),
    );
  }
  final scrollable = selection.candidate;
  final position = scrollable.state.position;
  if (_locatorIsVisible(targetLocator)) {
    return _withScrollableSelection(
      CockpitScrollStepResult(
        didScroll: false,
        strategy: 'alreadyVisible',
        scrollableKey: scrollable.keyValue,
        scrollablePath: scrollable.path,
        scrollableTypeName: scrollable.typeName,
        pixelsBefore: position.pixels,
        pixelsAfter: position.pixels,
        nextPixels: position.pixels,
        minScrollExtent: position.minScrollExtent,
        maxScrollExtent: position.maxScrollExtent,
        viewportDimension: position.viewportDimension,
        acceptsUserOffset: position.physics.shouldAcceptUserOffset(position),
        allowsProgrammaticScroll: position.physics.allowUserScrolling,
        targetMounted: true,
        targetVisible: true,
      ),
      selection,
      targetLocator: targetLocator,
    );
  }

  return _withScrollableSelection(
    await _scrollScrollableByViewport(
      scrollable,
      reverse: reverse,
      viewportFraction: viewportFraction,
      duration: duration,
      gestureProfile: gestureProfile,
      continuous: continuous,
      postScrollEnsureVisible: postScrollEnsureVisible,
      preferProgrammatic: probeDuringScroll && targetLocator != null,
    ),
    selection,
    targetLocator: targetLocator,
  );
}