Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Simple Text Input Form for React

The smallest form here: one username field that needs at least 2 characters, a description, and an error.

Username starts empty, with the note This is your public display name. Fewer than 2 characters shows Username must be at least 2 characters. Submit checks that and nothing else.

Start here for a single setting. A name plus an email is a second Input, not a bigger version of this. In React, Base UI does not set the 2-character floor.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Usage

<form className="w-full max-w-md" onSubmit={form.handleSubmit(onSubmit)}>
  <FieldGroup>
    <Controller
      control={form.control}
      name="username"
      render={({ field, fieldState }) => (
        <Field invalid={fieldState.invalid}>
          <FieldLabel htmlFor="simple-text-input-form-username">
            Username
          </FieldLabel>
          <Input
            {...field}
            id="simple-text-input-form-username"
            placeholder="johndoe"
            type="text"
          />
          <FieldDescription>
            This is your public display name.
          </FieldDescription>
          <FieldError>{fieldState.error?.message}</FieldError>
        </Field>
      )}
    />
    <Field orientation="horizontal">
      <Button type="submit">Submit</Button>
    </Field>
  </FieldGroup>
</form>

FAQ

How is the username input wired to React Hook Form?

useForm gets resolver: zodResolver(formSchema) and defaultValues of username: "". The Controller for name="username" renders the Input with field spread on it, so its value, onChange, onBlur and ref come from the form. FieldLabel htmlFor matches the input's id, simple-text-input-form-username.

Where does the 2 character error come from?

username is z.string().min(2, "Username must be at least 2 characters."). The Controller gives fieldState: invalid goes on the Field and error.message into FieldError.

What is the line under the input for?

FieldDescription stays on the page with "This is your public display name." The placeholder johndoe is only the empty-field hint.

When does this form validate?

useForm doesn't set mode, so React Hook Form validates on submit, then on each change after a failed submit. onSubmit only runs once the schema passes, and this demo logs the values.

What does the Submit button send?

Submit is a type="submit" button inside the form, whose onSubmit is form.handleSubmit(onSubmit). A username shorter than 2 characters never reaches that function.

Why is the username default an empty string?

defaultValues sets username to "", so the input is controlled from the first render and the placeholder shows. The schema still rejects that empty string on submit.

API Reference

Field

Sets invalid={fieldState.invalid}, htmlFor="simple-text-input-form-username" and orientation="horizontal". The rest is on the Field page.

Input

Sets field, id="simple-text-input-form-username", placeholder="johndoe" and type="text". The rest is on the Input page.

Button

Sets type="submit". The rest is on the Button page.