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.