Momentary Buttons
A momentary button sets a bound Property<T> to valueOn while the pointer holds it down, and back to valueOff the instant it's released — unlike Sticky Toggle Buttons, it never latches. scenerystack/sun exports RectangularMomentaryButton<T> and RoundMomentaryButton<T>, both built on the shared MomentaryButtonModel<T>. Reach for these for "hold to activate" controls — a horn, a temporary boost, a press-and-hold camera shutter — where releasing should immediately undo the effect.
import { RectangularMomentaryButton } from 'scenerystack/sun';
import { Text } from 'scenerystack/scenery';
import { Property } from 'scenerystack/axon';
import { Tandem } from 'scenerystack/tandem';
const hornStateProperty = new Property<'off' | 'on'>( 'off' );
const hornButton = new RectangularMomentaryButton(
hornStateProperty,
'off', // valueOff
'on', // valueOn
{
content: new Text( 'Horn' ),
baseColor: 'orange',
tandem: Tandem.REQUIRED
}
);RoundMomentaryButton has the identical (property, valueOff, valueOn, options?) constructor — only the button shape differs, same as RoundPushButton/RectangularPushButton.
MomentaryButtonModel
Both classes construct a MomentaryButtonModel<T> internally, the non-visual model (extending the shared ButtonModel base documented on PushButtonModel, not PushButtonModel itself) that owns the on/off logic: downProperty transitioning to true sets valueProperty to valueOn; transitioning to false sets it back to valueOff. For alternative-input (keyboard/switch) activation, it behaves like a toggle instead — one activation turns it on, the next turns it off — and it always reverts to valueOff if the button loses focus while on.
Property.valueComparisonStrategy must be 'reference' (the default) for the bound Property, since the model compares valueProperty.value against valueOn/valueOff with ===.
Options
Both classes accept the same appearance options as their non-momentary counterparts (RectangularButtonOptions / RoundButtonOptions) plus:
| Option | Effect |
|---|---|
valueOffSoundPlayer | Sound played when the button releases back to valueOff (default: shared 'toggleOff' player) |
valueOnSoundPlayer | Sound played when the button is pressed to valueOn (default: shared 'toggleOn' player) |
accessibleContextResponseValueOn / accessibleContextResponseValueOff | Alertable spoken/announced content for each transition |
Momentary buttons render aria-pressed, not a toggle-switch semantic
Both classes set the aria-pressed PDOM attribute to reflect whether property.value === valueOn, but the underlying interaction is still "hold to activate" — don't confuse this with Sticky Toggle Buttons, which use ariaRole: 'switch' and latch until pressed again.