A submit button that collapses into a circle with an orbiting spinner, then expands into a green success pill or a red error pill that shakes. It follows the promise returned by onSubmit.
Start your free trial
14 days, no card required.
npx shadcn@latest add https://hyperblur.dev/r/button-submit-morph.jsonWorks in any React project set up with the shadcn CLI. The file lands in components/hyperblur/button-submit-morph.tsx.
import { ButtonSubmitMorph } from "@/components/hyperblur/button-submit-morph"
<ButtonSubmitMorph onSubmit={() => api.signup(form)}>Create account</ButtonSubmitMorph>| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | "Create account" | Idle label. |
| successLabel | ReactNode | "Account created" | Label in the success pill. |
| errorLabel | ReactNode | "Try again" | Label in the error pill. |
| status | "idle" | "loading" | "success" | "error" | undefined | Controlled state. Leave unset to let the button manage itself. |
| onSubmit | () => unknown | undefined | Called on click. A returned promise decides success or error. |
| outcome | "success" | "error" | "success" | Result used when onSubmit does not return a promise. |
| duration | number | 1600 | Milliseconds of loading when onSubmit does not return a promise. |
| resetAfter | number | 2200 | Milliseconds before success or error returns to idle. |
| accent | string | "#2f7bff" | Idle color and spinner color. |
| successColor | string | "#1fb866" | Success pill color. |
| errorColor | string | "#f04452" | Error pill color. |
| disabled | boolean | false | Disables interaction and dims the control. |