Skip to content

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.

Open full source ↗

Props

PropTypeDefaultDescription
onSubmit(data: FormData, signal: AbortSignal) => Promise<void>—Native validity runs before submission. Signal aborts on unmount.
successMessagestring"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.

Works alongside