GlassPopover class
A liquid glass popover that morphs from its trigger button.
GlassPopover implements the same iOS 26 liquid morph animation as GlassMenu, but instead of presenting a list of menu items, it presents any custom widget. Use it for tooltips, mini forms, preview cards, colour pickers, or any content that should appear in a glass overlay.
The popover morphs from the trigger button using spring physics and the dual-blob metaball technique, creating a teardrop expansion effect.
Features
- Liquid morph animation: Same teardrop physics as GlassMenu
- Custom content: Any widget, not just menu items
- Self-closing: Content receives a
closecallback - Auto-positioning: Detects best alignment from trigger position
- Screen-edge clamping: Keeps popover within safe area
- Barrier dismissal: Tap outside to close (configurable)
- Blur ramp: The backdrop blur eases in with the morph instead of paying its full raster cost from the first frame — see blurRampDuration
Usage
Basic Usage
GlassPopover(
trigger: Icon(CupertinoIcons.info_circle, color: Colors.white),
contentBuilder: (context, close) => Padding(
padding: EdgeInsets.all(16),
child: Text('Hello from the popover!',
style: TextStyle(color: Colors.white)),
),
)
With Interactive Trigger
GlassPopover(
triggerBuilder: (context, toggle) => GlassButton(
onTap: toggle,
child: Text('Show Details'),
),
contentBuilder: (context, close) => Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Profile Details', style: TextStyle(color: Colors.white)),
SizedBox(height: 12),
GlassButton(onTap: close, child: Text('Done')),
],
),
),
)
With Fixed Height (Scrollable)
GlassPopover(
popoverHeight: 300,
trigger: Icon(CupertinoIcons.list_bullet),
contentBuilder: (context, close) => ListView.builder(
itemCount: 50,
itemBuilder: (context, i) => ListTile(title: Text('Item $i')),
),
)
Custom Alignment
GlassPopover(
alignment: GlassMenuAlignment.bottomCenter,
trigger: Icon(CupertinoIcons.arrow_down),
contentBuilder: (context, close) => Text('Below the trigger'),
)
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- GlassPopover
Constructors
- GlassPopover({Key? key, Widget? trigger, Widget triggerBuilder(BuildContext context, VoidCallback togglePopover)?, required Widget contentBuilder(BuildContext context, VoidCallback close), double popoverWidth = 280, double? popoverHeight, double popoverBorderRadius = 24.0, GlassMenuAlignment? alignment, bool autoAdjustToScreen = true, EdgeInsets screenPadding = const EdgeInsets.all(12), LiquidGlassSettings? settings, GlassQuality? quality, double stretch = 0.3, double interactionScale = 1.02, double stretchResistance = 0.08, Axis? stretchAxis, bool? allowPositiveX, bool? allowNegativeX, bool? allowPositiveY, bool? allowNegativeY, bool enableInteractionGlow = true, bool glowOnTapOnly = true, Color? glowColor, double glowRadius = 0.6, double glowIntensity = 0.0, VoidCallback? onClose, VoidCallback? onOpen, bool barrierDismissible = true, Duration blurRampDuration = const Duration(milliseconds: 260), Curve blurRampCurve = Curves.easeOut, String? semanticLabel})
-
Creates a liquid glass popover.
const
Properties
- alignment → GlassMenuAlignment?
-
The alignment of the popover relative to the trigger.
final
- allowNegativeX → bool?
-
Whether to allow stretch in the negative X direction (Left).
If null, automatically determined by popover position.
final
- allowNegativeY → bool?
-
Whether to allow stretch in the negative Y direction (Up).
If null, automatically determined by popover position.
final
- allowPositiveX → bool?
-
Whether to allow stretch in the positive X direction (Right).
If null, automatically determined by popover position.
final
- allowPositiveY → bool?
-
Whether to allow stretch in the positive Y direction (Down).
If null, automatically determined by popover position.
final
- autoAdjustToScreen → bool
-
Whether to automatically adjust the popover position to keep it on screen.
final
- barrierDismissible → bool
-
Whether tapping outside the popover dismisses it.
final
- blurRampCurve → Curve
-
The easing curve the blur ramp follows from
0→ full strength over blurRampDuration.final - blurRampDuration → Duration
-
How long the backdrop blur takes to ramp from
0up to settings'sbluronce the popover starts morphing open.final - contentBuilder → Widget Function(BuildContext context, VoidCallback close)
-
Builder for the popover content.
final
- enableInteractionGlow → bool
-
Whether to show glow/glare on touch for tactile feedback.
final
- glowColor → Color?
-
Custom color for the touch interaction glow.
final
- glowIntensity → double
-
The intensity of the interactive glow.
final
- glowOnTapOnly → bool
-
Whether the glow should act as a momentary tap indicator.
final
- glowRadius → double
-
Radius of the touch interaction glow.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- interactionScale → double
-
Scale factor applied on touch.
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- onClose → VoidCallback?
-
Called when the popover begins closing.
final
- onOpen → VoidCallback?
-
Called when the popover begins opening.
final
- popoverBorderRadius → double
-
Border radius of the expanded popover.
final
- popoverHeight → double?
-
Fixed height for the popover.
final
- popoverWidth → double
-
Width of the expanded popover.
final
- quality → GlassQuality?
-
Rendering quality for the glass effect.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- screenPadding → EdgeInsets
-
Minimum distance between the popover and screen edges.
final
- semanticLabel → String?
-
What the trigger opens, announced by screen readers (for example
"More actions").
final
- settings → LiquidGlassSettings?
-
Custom glass settings for the popover container.
final
- stretch → double
-
Liquid stretch factor.
final
- stretchAxis → Axis?
-
The axis to constrain the stretch to. If null, stretches in both axes.
final
- stretchResistance → double
-
The resistance factor to apply to the drag offset.
final
- trigger → Widget?
-
The widget that triggers the popover.
final
- triggerBuilder → Widget Function(BuildContext context, VoidCallback togglePopover)?
-
A builder for the trigger widget that provides access to the popover
toggle callback.
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< GlassPopover> -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited