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
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- GlassStepper
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