Async button
Wraps any async action and manages idle, loading, success, and error states automatically. Spring physics on every transition — no linear easing.
Live demo
Why it animates
Users triggering async actions need unambiguous feedback before the server responds. The spring transition to the loading state signals 'I received your action' immediately, reducing repeat submissions and uncertainty.
Usage
import { AsyncButton } from '@/components/ui/AsyncButton'
// Automatically handles loading, success, and error states.
// Pass any async function — the component does the rest.
async function handleSave() {
await api.save(formData)
}
<AsyncButton onClick={handleSave}>
Save changes
</AsyncButton>