Button

Press physics and async state handling.

Spring preview

Button knobs

How this works

A press should feel like the button is physically resisting your click, not just changing color. That's why this uses a spring instead of a timed animation by default — springs respond instantly to interruption, the same way a real button does if you let go mid-press.

Spring stiffness
How quickly the button starts moving toward its pressed (or released) state. Low stiffness feels sluggish and rubbery; high stiffness feels immediate and light. The default (500) is intentionally high — a press needs to register the instant you click, not ease into it.
Spring damping
How much the motion resists overshooting and wobbling. Low damping lets the button bounce past its target and settle like a spring toy; high damping stops it dead at the target. This library keeps damping high (30) everywhere — Linear's UI never overshoots on routine actions, which is part of why it reads as 'premium' instead of 'playful.'
Press mode: spring vs. duration
Switch to 'duration-based' to feel the difference a spring makes. Duration-based motion always takes the same fixed time and ignores how fast you're clicking; a spring continues from wherever it currently is, so rapid clicks feel continuous instead of stuttery.
Press scale
How far the button shrinks when pressed, from 1 (no visible press) down toward 0.85 (a very deep, almost cartoonish push). The default, 0.97, is deliberately subtle — per the motion principles, this is a state change, not a performance.
Loading → success/error
Use the trigger buttons to simulate an async action. The label fades out and a spinner fades in without changing the button's width, so nothing shifts around it. When the action resolves, the spinner is replaced by a check or X that scales in slightly — enough presence to register as 'this is now confirmed,' without the bounce that would make it feel celebratory.