MorphTargetSpec.popover constructor
- required Rect anchor,
- Size size = const Size(260, 300),
- double gap = 10,
- double margin = 12,
- MorphSurfaceSpec? surface,
- ShapeBorder? shape,
- Color? surfaceColor,
A popover anchored to the control that summoned it (the iOS 26
button-to-menu shape). Prefers sitting below the anchor, flips
above when there is no room, and stays inside the overlay with
margin. Capture the anchor rect at tap time with
morphAnchorRect - it measures in the coordinates of the overlay
the flight renders in, so a popover inside a nested navigator
stays anchored instead of drifting by the navigator's own offset.
Implementation
factory MorphTargetSpec.popover({
required Rect anchor,
Size size = const Size(260, 300),
double gap = 10,
double margin = 12,
MorphSurfaceSpec? surface,
ShapeBorder? shape,
Color? surfaceColor,
}) {
return MorphTargetSpec(
surface: surface,
shape:
shape ??
const RoundedRectangleBorder(borderRadius: .all(.circular(20))),
surfaceColor: surfaceColor,
rectFor: (Size overlay, EdgeInsets padding) {
// All four safe-area sides count: a home indicator or a
// landscape notch is system chrome the popover must not sit
// under.
final double leftMin = padding.left + margin;
final double leftMax = math.max(
leftMin,
overlay.width - padding.right - size.width - margin,
);
final double left = (anchor.center.dx - size.width / 2).clamp(
leftMin,
leftMax,
);
double top = anchor.bottom + gap;
if (top + size.height > overlay.height - padding.bottom - margin) {
top = anchor.top - gap - size.height;
}
final double topMin = padding.top + margin;
final double topMax = math.max(
topMin,
overlay.height - padding.bottom - size.height - margin,
);
top = top.clamp(topMin, topMax);
return Rect.fromLTWH(left, top, size.width, size.height);
},
);
}