UiPersistentSheet class

A non-modal, persistent bottom sheet that keeps the host body visible and interactive — the design used by Apple Maps / Google Maps filter panels and modern search sheets.

Unlike UiSheetScope.show this is not a Navigator route. Place the widget inside your page tree (typically as the last child of a Stack) and the host content remains tappable everywhere the sheet does not paint.

Stack(
  children: [
    MapView(),                     // still interactive under the sheet
    const Align(
      alignment: Alignment.bottomCenter,
      child: UiPersistentSheet(
        snaps: [
          UiSheetSnap.fraction(0.2),  // peek
          UiSheetSnap.fraction(0.5),  // half
          UiSheetSnap.fraction(0.95), // full
        ],
        child: UiSheet(child: _Filters()),
      ),
    ),
  ],
)

Host interaction model

By design there is no modal barrier and no dim scrim. The host body behind/around the sheet stays fully interactive. If you need to block host interaction at large snaps (e.g. when the sheet covers most of the screen), wrap the host body in an AbsorbPointer or IgnorePointer that you toggle via the controller — we deliberately do not impose a barrier policy.

Snap behavior

snaps must be a non-empty list of fraction-based UiSheetSnaps (UiSheetSnap.fit is rejected because there is no meaningful drag-destination without a target height). The list is consumed in the order given; it does not need to be sorted but is typically ascending. Dragging past the midpoint between two neighbours snaps to the further one, matching the iOS Maps feel.

Dismiss

Set allowClose to let the user swipe below the first snap to dismiss. onClose fires when the user completes the swipe. The sheet does not rebuild itself away after dismiss — the host is responsible for removing the widget (usually by setting a visibility flag in state).

Inheritance

Constructors

UiPersistentSheet({Key? key, required List<UiSheetSnap> snaps, required Widget child, UiPersistentSheetController? controller, bool enableDrag = true, bool allowClose = false, VoidCallback? onClose, UiMotionDuration duration = UiMotionDuration.standard, Curve? curve})
const

Properties

allowClose bool
Allow swipe-to-dismiss below the first snap.
final
child Widget
Sheet body. Typically a UiSheet.
final
controller UiPersistentSheetController?
External controller. If null, an internal one is created and disposed with this widget.
final
curve Curve?
Animation curve. Falls back to the theme's motion.standardCurve.
final
duration UiMotionDuration
final
enableDrag bool
Enables drag-to-snap. When false the sheet is driven exclusively through the controller.
final
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
onClose VoidCallback?
Fires when a dismiss gesture completes (only when allowClose).
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
snaps List<UiSheetSnap>
Snap points as fractions of the available vertical space.
final

Methods

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<UiPersistentSheet>
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