Stateful Button
Button that morphs through loading, success and error states while a Promise settles.
- 2.0 KB gzipped
- Zero dependencies
- Reduced-motion safe
- Base UI & Radix compatible
Installation
pnpm dlx shadcn@latest add https://velora.colorlib.com/r/stateful-button.jsonAdds components/velora/stateful-button.tsx.
Examples
Save form
A profile form where Save changes succeeds and Sync to CRM fails.
Props
| Prop | Type | Default |
|---|---|---|
onClickClick handler; return a Promise to show loading, then success or error | (event: React.MouseEvent<HTMLButtonElement>) => unknown | — |
resetAfterMilliseconds the success or error state stays before returning to idle | number | 2000 |
successTextShown beside the check and announced when the promise resolves | string | "Done" |
errorTextShown beside the cross and announced when the promise rejects | string | "Failed" |
Also accepts every <button> attribute, forwarded to the root element.
Accessibility
- Reduced motion
- The pill no longer shrinks to a circle, the spinner stands still and the labels swap instantly; colour changes remain.
- Keyboard
- A native button with a visible focus ring. While pending it uses aria-disabled rather than disabled, so focus stays put and repeat presses are ignored.
- Screen readers
- The accessible name stays the button's own label in every state; aria-busy is set while pending and a polite status region announces the success or error text.