GlassMenu class
A liquid glass context menu that morphs from its trigger button.
GlassMenu implements the iOS 26 "liquid glass" morphing pattern where a button seamlessly transforms into a menu. The same glass container transitions between button and menu states using spring physics.
Features
- True morphing: Button transforms into menu (not overlay)
- Smooth spring physics: Gentle settle with no harsh bounces (stiffness: 300, damping: 24)
- Liquid swoop: Subtle 5px parabolic arc for seamless down-and-up motion
- Seamless crossfade: Button only appears at final 5% to preserve morph illusion
- Dimension interpolation: Width, height, and border radius morph smoothly
- Position aware: Menu expands from button position
- Settings inheritance: Inherits parent layer settings like GlassContainer.card (thin rim by default)
- No button animation: Trigger button remains static, only shape morphs
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- GlassMenu
- Available extensions
Constructors
-
GlassMenu({Key? key, Widget? trigger, Widget triggerBuilder(BuildContext context, VoidCallback toggleMenu)?, required List<
Widget> items, bool autoAdjustToScreen = false, double itemBorderRadius = 24.0, LiquidGlassSettings? settings, GlassQuality? quality, double stretch = 0.5, double interactionScale = 1.02, double stretchResistance = 0.08, Axis? stretchAxis, bool? allowPositiveX, bool? allowNegativeX, bool? allowPositiveY, bool? allowNegativeY, double? maxStackHeight, Color selectionColor = const Color(0x3DFFFFFF), bool enableInteractionGlow = true, bool glowOnTapOnly = false, Color? glowColor, double glowRadius = 0.6, double glowIntensity = 0.0, VoidCallback? onClose, GlassMenuController? controller, bool showDismissBarrier = true, bool morphFromZero = false, bool platformViewBackdrop = false, MorphSpeed morphSpeed = MorphSpeed.normal, bool enableContinuousSwipe = false, double continuousSwipeSlop = 10.0, String? semanticLabel, void onLevelChanged(int depth, double height)?}) -
Creates a liquid glass menu.
const
Properties
- allowNegativeX → bool?
-
Whether to allow stretch in the negative X direction (Left).
If null, automatically determined by menu position.
final
- allowNegativeY → bool?
-
Whether to allow stretch in the negative Y direction (Up).
If null, automatically determined by menu position.
final
- allowPositiveX → bool?
-
Whether to allow stretch in the positive X direction (Right).
If null, automatically determined by menu position.
final
- allowPositiveY → bool?
-
Whether to allow stretch in the positive Y direction (Down).
If null, automatically determined by menu position.
final
- autoAdjustToScreen → bool
-
Whether to automatically adjust the menu position to keep it on screen.
final
- continuousSwipeSlop → double
-
The movement threshold in logical pixels required to arm continuous swipe.
final
- controller → GlassMenuController?
-
Optional controller to drive the menu imperatively
(GlassMenuController.open / GlassMenuController.close) instead of — or
in addition to — tapping the trigger.
final
- enableContinuousSwipe → bool
-
Whether to enable iOS-style continuous swipe-to-select.
final
- enableInteractionGlow → bool
-
Whether to show glow/glare on touch for tactile feedback. Default: true.
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. Default: 0.6.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- interactionScale → double
-
Scale factor applied on touch. Default: 1.02.
final
- itemBorderRadius → double
-
Border radius of the selection highlight and menu items.
final
-
items
→ List<
Widget> -
The list of items to display in the menu.
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- maxStackHeight → double?
-
Maximum vertical extent of the root and all layered submenu cards.
final
-
The alignment of the menu relative to the trigger.
final
-
Border radius of the expanded menu.
final
-
Optional fixed height for the menu.
final
-
The minimum distance between the menu and the screen edges.
final
-
Width of the expanded menu.
final
- morphFromZero → bool
-
Whether the open/close morph blooms from a zero-size point at the trigger
center instead of from a glass blob the size of the trigger. Defaults to
false(the menu spawns as a small rounded "metaball" matching the trigger and morphs outward — the standard iOS-26 liquid-glass behavior).final - morphSpeed → MorphSpeed
-
Speed profile for the open/close morph animation.
final
- onClose → VoidCallback?
-
Called when the menu begins closing.
final
- onLevelChanged → void Function(int depth, double height)?
-
Called with the submenu depth (0 = root list) and the resting height of
the whole visible stack — the menu body, plus every open submenu card
that extends past it — whenever the stack changes: when the menu opens,
and on every GlassMenuItem.submenu push or header pop, just before the
layering morph animates.
final
- platformViewBackdrop → bool
-
When true (typically for iOS PlatformViews), forces the BackdropFilter
fallback render path instead of the Impeller-native shader. Forwarded to
the underlying AdaptiveLiquidGlassLayer.
final
- quality → GlassQuality?
-
Rendering quality for the glass effect.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- selectionColor → Color
-
Custom color for the menu selection background.
final
- semanticLabel → String?
-
What the trigger opens, announced by screen readers (for example
"More actions").
final
- settings → LiquidGlassSettings?
-
Custom glass settings for the menu container.
final
- showDismissBarrier → bool
-
Whether to render the full-screen tap-to-dismiss barrier behind the open
menu. Defaults to
true(modal: a tap outside the menu closes it).final - stretch → double
-
Liquid stretch factor. Default: 0.5.
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.
Higher values make the drag feel "stickier". Default: 0.08.
final
- trigger → Widget?
-
The widget that triggers the menu.
final
- triggerBuilder → Widget Function(BuildContext context, VoidCallback toggleMenu)?
-
A builder for the trigger widget that provides access to the menu toggle callback.
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< GlassMenu> -
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
-
glassContextMenu(
{Key? key, required List< Widget> actions, WidgetBuilder? previewBuilder, bool enabled = true, bool enableHaptics = true, double borderRadius = 32.0, double? previewBorderRadius, double rowBorderRadius = 16.0, BorderRadius? rowCorners, Color? originSlotColor, Color? backgroundColor, LiquidGlassSettings? settings, GlassQuality? quality, double backdropBlur = 0.0, Color? barrierColor, VoidCallback? onOpened, VoidCallback? onDismissed, Duration longPressDuration = const Duration(milliseconds: 700)}) → Widget -
Available on Widget, provided by the GlassContextMenuExtension extension
Wraps this widget in a GlassContextMenu displayingactionson long-press or right-click. -
glassFullScreenCover(
{required bool isPresented, VoidCallback? onDismiss, required WidgetBuilder content, bool enableSwipeToDismiss = true, double dismissThreshold = 140.0, LiquidGlassSettings? settings, GlassQuality? quality}) → Widget -
Available on Widget, provided by the GlassFullScreenCoverExtension extension
Presents a full-viewport modal cover wheneverisPresentedis true. -
Available on Widget, provided by the GlassNavigationTitleExtension extension
Annotates this widget with a navigation title that drives enclosing or descendant GlassAppBar / GlassAppBar.pinned bars (when their explicittitleis null) as well as header accessibility semantics. -
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