SubmitButton
A form’s submit button, and the busy one that replaces it while the request is on its way.
import { SubmitButton } from '@zitdevs/ui';Examples
Section titled “Examples”This form posts natively, into a hidden frame so this page stays put. The page runs
enhanceSubmitState(document) from @zitdevs/ui/enhance; press Send to see the sending state.
In each size, before anything is sent:
<form method="post" action="/contact#zd-result"> {/* the questions */} <SubmitButton label="Send request" sendingLabel="Sending request…" /></form>A form the page sends itself
Section titled “A form the page sends itself”A submit the page cancels — client-side validation, a React onSubmit that calls
preventDefault, a function action — never navigates, so the button leaves it alone. Pass
pending to show the sending state for the request the page makes, from your own state or React’s
useFormStatus:
'use client';
const [pending, setPending] = useState(false);
<form onSubmit={async (event) => { event.preventDefault(); setPending(true); await send(); setPending(false); }}> <SubmitButton label="Send" sendingLabel="Sending…" pending={pending} /></form>;| Prop | Type | Default | Notes |
|---|---|---|---|
label |
string |
required | The send button’s words. |
sendingLabel |
string |
required | The busy button’s words, while the request is on its way. |
size |
'sm' | 'md' | 'lg' |
'lg' |
As Button’s. |
pending |
boolean |
— | For a form the page sends itself: the sending state shows while true. |
ref |
Ref<HTMLButtonElement> |
— | The send button. |
className |
string |
— | Placement, on both buttons: one stands in for the other. |
| anything else | <button> attributes |
— | On the send button: name, value, form… |
Exported types: SubmitButtonProps. From @zitdevs/ui/enhance: enhanceSubmitState,
SubmitStateEnhancement (reset(), setPending()).
Accessibility
Section titled “Accessibility”- The send button is a native
type="submit"; the busy one is atype="button"witharia-busy="true"and a spinner that holds still for reduced motion. - On a submit, focus moves to the busy button, the one the reader is now watching, and comes back to the send button when the state clears.
- A long label wraps inside the button, since the copy decides how long it is.
- Another submit button of the same form, such as an “Edit” with its own
formaction, sends without this spinner; a second submit is blocked either way.
Without JavaScript
Section titled “Without JavaScript”The form posts natively; the button is a plain submit. The busy button is in the page already, hidden, so the enhancer draws nothing:
- React: nothing to do. The send button is a small client part that runs the enhancer once it has hydrated.
- No React: load
@zitdevs/ui/enhanceand callenhanceSubmitState(document). The back/forward cache restores a page as it was left, still spinning, so it resets onpageshow.
The page needs Tailwind’s preflight, or a reset with its [hidden] rule: the busy button is a
flex box switched with hidden.
Theming
Section titled “Theming”Button’s primary variant, and its busy state.