Skip to main content

Starwind UI v3.0 is now available! Migration guide

Form remains a native HTML form. The Runtime adds validation timing, field coordination, and an accessible error summary without requiring React or a form-state library.

Installation

Start here

The browser still owns submission and FormData. Use ordinary action, method, submit, and reset behavior; Runtime controls serialize through their installed hidden inputs.

Start with the defaults

Most forms do not need to set a validation policy. Starwind waits until submit to validate and reveal errors, then validates accepted corrections on change after the first submission attempt.

Understand validation

Form separates two questions: when a Field is validated, and when an existing error is revealed. Validation itself has a before-submit phase and an after-submit phase.

  1. 1. Interact

    A value changes, focus leaves a Field, the Form submits, or code requests validation.

  2. 2. Validate

    The current before- or after-submit timing decides whether validators run.

  3. 3. Reveal

    Error visibility independently decides whether existing errors may render.

  4. 4. Continue

    Valid submission proceeds; invalid submission focuses the first invalid Field.

Validation policy

SettingWhat it controlsDefault
validationTimingInteraction validation before the first submission attemptsubmit
revalidationTimingThe interaction timing that replaces validationTiming after a submission attemptchange
errorVisibilityWhich cause makes existing errors eligible to rendersubmit
ValueMeaning
changeEvery accepted value revision from a native or Runtime control, including typing, selecting, checking, and sliding
blurFocus leaves the entire Field, rather than moving between descendants of a composite Field
submitA whole-Form submission attempt
manualImperative validate(); no automatic interaction matches it
GoalBefore submitAfter submitReveal errors
Calm by default, responsive during correctionsubmitchangesubmit
Live validationchangechangechange
Submit-only feedbacksubmitsubmitsubmit
Imperative wizard or step validationmanualmanualmanual
Phase and reset details

A successful or blocked submission attempt switches the whole Form to revalidationTiming, including Fields registered later. The phase does not change after a Field’s first blur or first validation.

Native reset or a full resetValidation() returns the Form to its before-submit phase. Changing a timing prop is prospective: it does not clear submission state, validation results, or already revealed errors.

Coming from TanStack Form

Conceptually, validationTiming is Starwind’s before-submit mode and revalidationTiming is its mode after submission. Starwind separately controls sticky error revelation, ARIA descriptions, summaries, and invalid-field focus.

Try a policy

Choose the before-submit trigger, its after-submit replacement, and the independent reveal trigger. Form-level values apply to every Field unless that Field overrides one of them.

Try submitting an empty or incomplete address.

This Field validates on change before submit, then only on blur afterward.

Before submit: submit. After submit: change. Errors: submit.

Validation and error revelation

Validation computes errors; revelation determines whether those errors participate in visible messages, descriptions, and the Form summary. A hidden error can set aria-invalid, but it does not enter aria-describedby or FormErrorSummary until its Field is revealed.

Reveal eligibility is sticky. Becoming valid hides the current message but does not make the Field “unrevealed”; a later error can appear immediately. Native reset, full resetValidation(), Field removal, or setErrorsVisible(false) removes that eligibility.

form.checkValidity()

Runs native and synchronous custom validation without revealing errors, moving focus, or changing the Form phase.

form.reportValidity()

Runs synchronous validation, reveals every checked invalid Field, and focuses the first one without changing the Form phase.

Submit attempt

Runs native, synchronous custom, and managed async validation. It applies each Field’s error policy, focuses the first invalid Field, and enters the after-submit phase.

formApi.validate()

Runs the complete validator pipeline with optional focus and revelation, returning one coherent async outcome without changing the Form phase.

Solve a common problem

Choose the task that matches the form you are building. Only one complete recipe is shown at a time; each recipe includes Astro and React code.

Add custom rules

Add domain rules without replacing native constraints. Field validators handle one value, form validators compare values, and the managed submit callback only runs after every rule passes.

Without a Runtime onSubmit option, Starwind blocks invalid submission and lets a valid native submission continue. Supplying onSubmit to createForm() activates managed submission: Runtime prevents the native submit, runs synchronous and configured async validators, then calls the handler with values, registered fields, the submitter, and the original event. A JSX onSubmit prop is an ordinary DOM callback and does not by itself activate the managed async path.

Try “admin” or a value matching the workspace.

Submit to run the custom rules.

Accessibility

Validation and presentation stay synchronized across native and Runtime-backed controls:

  • Invalid checked Fields receive aria-invalid even when their messages are still hidden.
  • Only revealed errors participate in aria-describedby and FormErrorSummary.
  • reportValidity(), blocked submission, and validate({ focus: true }) focus the first applicable invalid Field in DOM order; checkValidity() and default validate() do not move focus.
  • Summary entries remain in DOM order and keep duplicate-name Field roots distinct. Activating an entry focuses its Field control.
  • Focus moving among descendants of one composite Field does not count as blur.

Keep FormErrorSummary explicit so its placement, heading, and surrounding instructions match the product. Field-level timing props can override the owning Form independently, but omitting them keeps the policy easier to understand and maintain.

API Reference

Styled Component API

These props are added or materially changed by the installed styled component. Standard HTML attributes remain available through the inherited interfaces noted below. Expand a prop to see named type definitions and framework-specific imports. Follow the Primitive and Runtime links for lower-level behavior props.

Form

Inherits form attributes.

Contains the following additional props:

Prop Type Default Toggle details
errorVisibility "blur" | "change" | "manual" | "submit" "submit"
Description
Selects whether semantic change, blur, submit, or manual validation reveals errors; defaults to submit.
Classification
Primitive override
Primitive prop
form.Root.errorVisibility
revalidationTiming "blur" | "change" | "manual" | "submit" "change"
Description
After a Form submission attempt, replaces validationTiming with semantic change, blur, submit, or manual validation; defaults to change.
Classification
Primitive override
Primitive prop
form.Root.revalidationTiming
validationTiming "blur" | "change" | "manual" | "submit" "submit"
Description
Selects semantic change, blur, submit, or manual validation before a Form submission attempt; defaults to submit.
Classification
Primitive override
Primitive prop
form.Root.validationTiming

Primitive And Runtime API

Use these references when you need the lower-level behavior APIs behind Form.

Primitive API

Runtime API

Form primitive
createForm from @starwind-ui/runtime/form

Changelog

v1.0.1

  • Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.

v1.0.0

  • Added Runtime-backed native form coordination and validation timing.
  • See the Form Primitive for the underlying unstyled anatomy and behavior API.