AsyncForm
A form that follows the save promise and preserves input when a save fails.
Live — this one is real
Usage
import { AsyncForm, TextField } from "mizu-ui";
export function Example() {
return (
<AsyncForm
onSubmit={async (data, signal) => {
const response = await fetch("/api/settings", {
method: "POST",
body: data,
signal,
});
if (!response.ok) throw new Error("Could not save settings.");
}}
>
<TextField label="Display name" name="name" required />
<button type="submit" className="mizu-text-button">
Save settings
</button>
</AsyncForm>
);
}
Source & setup
Import mizu-ui/styles.css once. Fonts are optional via mizu-ui/fonts.css. Override --mizu-* tokens or use className for local styling. Uses native React and CSS; install the package peers for root imports.
Inspect forms/AsyncForm.tsx
Source is included in the npm package under src/forms/AsyncForm.tsx.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| onSubmit | (data: FormData, signal: AbortSignal) => Promise<void> | — | Native validity runs before submission. Signal aborts on unmount. |
| successMessage | string | "Saved." | Successful save feedback. |
Accessibility
Uses native form validation and disables the fieldset while pending. Errors are live; fields stay intact for correction.
Motion
Pending state follows a real promise, never a simulated timeout.