presentationFor method

ShowcasePresentation? presentationFor(
  1. String anchorKey
)

The presentation for anchorKey under the active guide, or null when no guide is active or no step targets this anchor.

Implementation

ShowcasePresentation? presentationFor(String anchorKey) {
  final state = _orchestrator.state;
  if (state == null) return null;
  final scope = VariableScope.fromSchemas(
    state.campaign.config.defaultVariables,
    state.payload.variables,
  );
  final config = state.config;
  final anchorGlobalKey = _registry.keyFor(anchorKey);
  final anchorContext = anchorGlobalKey.currentContext;
  final viewportWidth = anchorContext == null
      ? null
      : MediaQuery.maybeSizeOf(anchorContext)?.width;
  final designScale = viewportWidth != null
      ? campaignCanvasDesignScale(
          viewportWidth: viewportWidth,
          designWidth: config.designWidth,
        )
      : 1.0;

  final disableBarrier =
      config.outsideTapBehavior == OutsideTapBehavior.nothing;

  if (config is TooltipGuideConfig) {
    final step = _firstWhere(config.steps, (s) => s.anchorKey == anchorKey);
    if (step == null) return null;
    final canvas = step.layoutMode == 'canvas' ? step.canvas : null;
    return ShowcasePresentation(
      container: canvas != null
          ? VariableScopeProvider(
              scope: scope,
              child: GuideCanvasTooltipSurface(
                canvas: canvas,
                designWidth: config.designWidth,
                cornerRadius: step.cornerRadius,
                borderWidth: step.borderWidth,
                borderColor: step.borderColor,
                shadow: step.shadow,
                showArrow: step.showArrow,
                arrowSize: step.arrowSize,
                side: guideCanvasTooltipSide(step.placement),
                onActions: handleCanvasActions,
              ),
            )
          : GuideBubble.tooltip(
              step: step,
              scope: scope,
              onAction: handleAction,
            ),
      // Tooltip = no dim (RN renders the bubble over a transparent scrim).
      overlayColor: const Color(0x00000000),
      overlayOpacity: 0,
      targetShapeBorder: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(8),
      ),
      targetBorderRadius: BorderRadius.circular(8),
      targetPadding: EdgeInsets.zero,
      targetGlowColor: const Color(0x00000000),
      targetGlowWidth: 0,
      tooltipPosition: _tooltipPosition(step.placement),
      showArrow: canvas == null && step.showArrow,
      // RN: arrowColor ?? backgroundColor — the arrow matches the bubble.
      arrowColor: step.arrowColor ?? step.backgroundColor,
      // RN: arrowBorderColor ?? borderColor; border width follows the bubble.
      arrowBorderColor: step.arrowBorderColor ?? step.borderColor,
      arrowBorderWidth: step.borderWidth,
      arrowSize: step.arrowSize,
      // RN tooltip: gap = showArrow ? arrowSize + 4 : 8. The arrow height is
      // reserved by the renderer, so we pass only the clearance beyond it.
      targetTooltipGap:
          canvas != null ? step.gap * designScale : (step.showArrow ? 4 : 8),
      disableBarrierInteraction: disableBarrier,
    );
  }
  if (config is SpotlightGuideConfig) {
    final step = _firstWhere(config.steps, (s) => s.anchorKey == anchorKey);
    if (step == null) return null;
    return _spotlightPresentation(
      step: step,
      config: config,
      scope: scope,
      designScale: designScale,
      disableBarrier: disableBarrier,
    );
  }
  return null;
}