new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

shadcn/ui · all subjects

blocks/forms

29 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Next.js form approach with useActionState and Server Actions

Next.js forms can be built using the <Form /> component for navigation and progressive enhancement, <Field /> components for building accessible forms, useActionState for managing form state and errors, Server Actions for handling form submissions, and Zod for server-side validation.

FormState type definition for Next.js forms

The FormState type should include three properties: values (optional, inferred from the Zod schema), errors (null or a Partial Record mapping field names to arrays of error strings), and success (boolean). This type is used to type the form state on both client and server components.

Basic form anatomy with Field component

A basic form structure uses <Form action={formAction}>, <FieldGroup>, <Field data-invalid={condition}>, <FieldLabel>, <Input>, <FieldDescription>, <FieldError>, and a submit <Button>. The Field component provides complete flexibility over markup and styling.

Server action validation with safeParse

Use safeParse() on the Zod schema in the server action to validate form data. When validation fails, return the values, success set to false, and errors from result.error.flatten().fieldErrors. When validation succeeds, return errors as null and success as true.

Return values on validation errors to preserve user input

When the server action validation fails, return the values in the response so the form state maintains the user's input. This prevents the form from being reset and allows the user to see what they entered alongside the error messages.

Reset form on successful submission

To reset the form on successful submission, omit the values from the server action return. React will automatically reset the form state to initial values. Only return errors as null and success as true.

Using pending state for loading indicators and disabled fields

The pending prop returned from useActionState indicates whether the form is currently submitting. Use it to disable form inputs with the disabled prop, disable the submit button, and show loading indicators like spinners. Apply data-disabled prop to <Field /> components for styling disabled state.

Displaying form field errors

To display field errors, add data-invalid prop to the <Field /> component and aria-invalid prop to the input element. Render <FieldError /> conditionally when errors exist for that field, displaying the first error message from the errors array.

Business logic validation in server actions

After schema validation succeeds, you can add custom business logic validation in the server action, such as checking if an email already exists in the database. Return values, success set to false, and a custom errors object if business logic validation fails.

useActionState hook initialization with default state

Initialize useActionState with three arguments: the server action function, and an initial form state object with properties errors (typically null), and success (typically false). useActionState returns formState, formAction, and pending.

Zod schema validation with min/max constraints

Use Zod to define form schemas with validation rules. For strings, use .min(length, message) for minimum character length and .max(length, message) for maximum character length. Error messages are returned in validation errors.

Schema and FormState must be in separate file for client and server use

Define the Zod schema and FormState type in a separate file that can be imported into both client and server components. This allows both the client and server to reference the same schema and type definitions.

Disable Field component using data-disabled prop

To apply disabled state styling to a <Field /> component, use the data-disabled prop and pass the pending value. Also set disabled={pending} on the input element inside the field.

Disable submit button during form submission

Use disabled={pending} on the submit button to prevent multiple submissions while the form is processing. Optionally display a spinner when pending is true.

TanStack Form overview

TanStack Form is a headless form handling library used to build forms in React. It provides the useForm hook for form state management, the form.Field component with a render prop pattern for controlled inputs, client-side validation using Zod, and real-time validation feedback.

useForm hook setup with Zod validation

Use the useForm hook from TanStack Form to create a form instance. Pass defaultValues (an object with initial form field values), validators (with onSubmit, onChange, and/or onBlur modes), and onSubmit (an async function called with the validated form data). Example: const form = useForm({ defaultValues: { title: "", description: "" }, validators: { onSubmit: formSchema }, onSubmit: async ({ value }) => { toast.success("Form submitted successfully") } })

TanStack Form validation modes

TanStack Form supports three validation modes via the validators option: "onChange" (validation triggers on every change), "onBlur" (validation triggers on blur), and "onSubmit" (validation triggers on submit). Multiple modes can be configured simultaneously by providing schemas for multiple modes in the validators object.

form.Field component for controlled inputs

The form.Field component from TanStack Form accepts a name prop and a children render prop that receives a field object. The field object contains state (with meta.isTouched, meta.isValid, value), handleBlur, and handleChange methods. This render prop pattern gives complete control over markup and styling.

Accessibility for invalid form fields

To make invalid fields accessible: add the data-invalid prop to the Field component with the value field.state.meta.isTouched && !field.state.meta.isValid, and add the aria-invalid prop to the form control (Input, SelectTrigger, Checkbox, etc.) with the same value.

Input field pattern with TanStack Form

For input fields: use field.state.value and field.handleChange on the Input component. Set id, name, onBlur, onChange, and aria-invalid props. Add data-invalid to the Field wrapper and display errors with FieldError when isInvalid is true.

Textarea field pattern with TanStack Form

For textarea fields: use field.state.value and field.handleChange on the Textarea component. Set id, name, onBlur, onChange, and aria-invalid props. Add data-invalid to the Field wrapper and display errors with FieldError when isInvalid is true.

Select field pattern with TanStack Form

For select components: use field.state.value and field.handleChange (via onValueChange) on the Select component. Set aria-invalid on the SelectTrigger component and data-invalid on the Field wrapper. Display errors with FieldError when isInvalid is true.

Checkbox field pattern with TanStack Form

For checkbox fields: use field.state.value and field.handleChange on the Checkbox component. Set aria-invalid on Checkbox and data-invalid on the Field wrapper. For checkbox arrays, use mode="array" on form.Field and add data-slot="checkbox-group" to the FieldGroup for proper styling. Use field.pushValue() to add and field.removeValue(index) to remove items.

Radio group field pattern with TanStack Form

For radio groups: use field.state.value and field.handleChange (via onValueChange) on the RadioGroup component. Set aria-invalid on RadioGroupItem components and data-invalid on the Field wrapper. Display errors with FieldError when isInvalid is true.

Switch field pattern with TanStack Form

For switches: use field.state.value and field.handleChange (via onCheckedChange) on the Switch component. Set aria-invalid on Switch and data-invalid on the Field wrapper. Display errors with FieldError when isInvalid is true.

Reset form to default values

Use form.reset() to reset the form to its default values. This is typically called in an onClick handler on a button element.

Array field management with TanStack Form

Use mode="array" on the form.Field component to enable array field management. Access individual array items using bracket notation: fieldName[index].propertyName in nested form.Field components. Use field.pushValue(item) to add items and field.removeValue(index) to remove items.

Array field validation with Zod

Validate array fields using Zod's array methods. Example: z.object({ emails: z.array(z.object({ address: z.string().email("Enter a valid email address.") })).min(1, "Add at least one email address.").max(5, "You can add up to 5 email addresses.") })

Form submission with TanStack Form

Wrap form submission by calling e.preventDefault() and then form.handleSubmit() in the form's onSubmit handler. TanStack Form will validate the form data before calling the onSubmit callback function defined in useForm.

Give your agent this brain