shadcn.io is an independent project built on shadcn/ui
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, Ark UI does not set the 2-character floor.
Installation
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>Username</FieldLabel>
<Input {...field} 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. Field links FieldLabel to the input.
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.
API Reference
Field
Sets invalid={fieldState.invalid} and orientation="horizontal". The rest is on the Field page.
Input
Sets field, placeholder="johndoe" and type="text". The rest is on the Input page.
Button
Sets type="submit". The rest is on the Button page.





