GlassStepper class

A glass-aesthetic numeric stepper matching iOS 26's UIStepper control.

GlassStepper is the Flutter equivalent of iOS 26's UIStepper. It renders a compact horizontal pill with a decrement () button on the left, an increment (+) button on the right, and a thin vertical divider between them — all wrapped in a liquid glass material.

Behaviour

  • Tapping or + calls onChanged with the updated value and fires HapticFeedback.lightImpact.
  • Holding either button triggers auto-repeat after autoRepeatDelay, firing every autoRepeatInterval until released (matching iOS behaviour).
  • At min the button is visually disabled; at max the + button is disabled (unless wraps is true, in which case the value cycles).
  • Button sides animate to a slightly pressed scale on touch-down.

Value display

iOS 26's native UIStepper does not show the value inside the control — the value is always displayed in a separate label by the app. GlassStepper follows this convention. To show the value, place a Text widget next to it:

Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Text(
      '$_quantity',
      style: TextStyle(fontSize: 22, color: Colors.white, fontWeight: FontWeight.w600),
    ),
    const SizedBox(width: 16),
    GlassStepper(
      value: _quantity.toDouble(),
      min: 1,
      max: 99,
      onChanged: (v) => setState(() => _quantity = v.toInt()),
    ),
  ],
)

Properties

Property iOS equivalent Default
value value
min minimumValue 0
max maximumValue 100
step stepValue 1
wraps wraps false
autoRepeat autorepeat true
Inheritance

Constructors

GlassStepper({Key? key, required double value, required ValueChanged<double>? onChanged, double min = 0.0, double max = 100.0, double step = 1.0, bool wraps = false, bool autoRepeat = true, Duration autoRepeatDelay = const Duration(milliseconds: 500), Duration autoRepeatInterval = const Duration(milliseconds: 100), double height = 34.0, double width = 94.0, double dividerWidth = 0.5, LiquidGlassSettings? settings, GlassQuality? quality})
Creates an iOS 26-style glass stepper.
const

Properties

autoRepeat bool
When true, holding a button fires repeated events like iOS.
final
autoRepeatDelay Duration
How long to wait after the first tap before auto-repeat begins.
final
autoRepeatInterval Duration
Interval between auto-repeat firings once they begin.
final
dividerWidth double
Thickness of the vertical divider between the two buttons.
final
hashCode int
The hash code for this object.
no setterinherited
height double
Height of the control. Defaults to 34 logical pixels (matches iOS 26 pt).
final
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
max double
The maximum value. Defaults to 100.
final
min double
The minimum value. Defaults to 0.
final
onChanged ValueChanged<double>?
Called when the value changes via tap or auto-repeat.
final
quality GlassQuality?
Rendering quality. Defaults to GlassQuality.standard.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
settings LiquidGlassSettings?
Glass effect settings for the pill background.
final
step double
The amount added/subtracted on each tap. Defaults to 1.
final
value double
The current numeric value.
final
width double
Width of the control. Defaults to 94 logical pixels (matches iOS 26 pt).
final
wraps bool
When true, stepping past max wraps back to min and vice-versa.
final

Methods

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