### Customize Form Field Rendering and Behavior with Remix Forms
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
This example showcases how to customize the rendering and behavior of form fields using `SchemaForm`. It allows setting labels, placeholders, input types, options for enums, and global settings like `autoFocus` and `buttonLabel`.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
const schema = z.object({
password: z.string().min(8),
website: z.string().url(),
birthDate: z.string(),
bio: z.string().optional(),
country: z.enum(['us', 'uk', 'ca']),
notifications: z.boolean(),
})
export default function CustomPropsForm() {
return (
)
}
```
--------------------------------
### UseFetcher Integration for Non-Navigating Submissions
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Facilitates non-navigating form submissions using React Router's `useFetcher`. This is ideal for modal forms, inline updates, or scenarios where the user should remain on the same page after submission.
```tsx
import { SchemaForm } from 'remix-forms'
import { useFetcher } from 'react-router'
import { z } from 'zod'
const schema = z.object({
name: z.string().min(1),
email: z.string().email(),
})
export default function FetcherForm() {
const fetcher = useFetcher()
return (
{
// Handle successful submission
if (fetcher.formAction && formState.isDirty) {
setFocus('name') // Focus first field
reset() // Clear form
}
}}
>
{({ Field, Button, Errors }) => (
<>
{fetcher.state === 'submitting' && (
Saving...
)}
{fetcher.data?.success && (
Saved successfully!
)}
>
)}
)
}
```
--------------------------------
### Perform Mutation with Remix Forms
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Executes mutations at a lower level without automatic redirects. This is useful for custom response handling or non-navigating submissions when using `useFetcher`. It requires the request, schema, mutation function, and a context object.
```tsx
import { performMutation } from 'remix-forms'
import { applySchema } from 'composable-functions'
import { json, redirect } from 'react-router'
import type { Route } from './+types/profile'
const schema = z.object({
name: z.string().min(1),
bio: z.string().optional(),
})
const mutation = applySchema(schema)(async (values, context) => {
const user = await updateProfile(context.userId, values)
return user
})
export const action = async ({ request }: Route.ActionArgs) => {
const userId = await getUserId(request)
const result = await performMutation({
request,
schema,
mutation,
context: { userId },
})
if (!result.success) {
// Custom error handling
return json(
{ errors: result.errors, values: result.values },
{ status: 422 }
)
}
// Custom success handling
await logActivity('profile_updated', result.data.id)
return redirect('/profile')
}
```
--------------------------------
### Customizing Components in Remix Forms with Zod
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Learn how to replace default form components like inputs and selects with custom implementations in Remix Forms. This allows seamless integration with design systems or the addition of specialized functionality, using Zod for schema definition.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
import * as RadixSelect from '@radix-ui/react-select'
const schema = z.object({
name: z.string().min(1),
country: z.enum(['us', 'uk', 'ca']),
})
function CustomSelect({
name,
options,
value,
onChange,
...props
}: any) {
return (
{options.map((option: any) => (
{option.label}
))}
)
}
function CustomInput({ error, ...props }: any) {
return (
)
}
export default function CustomComponentsForm() {
return (
(
)}
>
{({ Field, Button }) => (
<>
>
)}
)
}
```
--------------------------------
### Context for Authorization in Mutations
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Allows passing context to mutations for authorization checks, user data, or any request-specific information needed within the business logic. Includes validation for both schema and context.
```tsx
import { formAction } from 'remix-forms'
import { applySchema } from 'composable-functions'
import { z } from 'zod'
import type { Route } from './+types/admin'
const schema = z.object({
title: z.string().min(1),
content: z.string().min(10),
})
const contextSchema = z.object({
userId: z.string(),
role: z.enum(['admin', 'editor']),
})
const mutation = applySchema(
schema,
contextSchema
)(async (values, context) => {
// Context is validated and type-safe
if (context.role !== 'admin') {
throw new Error('Unauthorized')
}
const post = await createPost({
...values,
authorId: context.userId,
})
return post
})
export const action = async ({ request }: Route.ActionArgs) => {
const session = await getSession(request)
return formAction({
request,
schema,
mutation,
context: {
userId: session.userId,
role: session.role,
},
successPath: '/admin/posts',
})
}
```
--------------------------------
### formAction Helper: Server-Side Form Processing
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
The formAction helper function processes form submissions on the server. It validates data against a Zod schema, executes a provided mutation, and handles success redirects or error responses. Dependencies include 'remix-forms', 'composable-functions', and 'zod'. Input is the request object, schema, mutation, and paths; output is a server action response.
```tsx
import { formAction } from 'remix-forms'
import { applySchema } from 'composable-functions'
import { z } from 'zod'
import type { Route } from './+types/signup'
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ['confirmPassword'],
})
// Define mutation with business logic
const mutation = applySchema(schema)(async (values) => {
// Simulate API call
const user = await createUser({
email: values.email,
password: values.password,
})
if (!user) {
throw new Error('User already exists')
}
return { userId: user.id, email: user.email }
})
// Action handler with redirect on success
export const action = async ({ request }: Route.ActionArgs)
=> formAction({
request,
schema,
mutation,
successPath: '/dashboard',
// Optional: Transform values before mutation
transformValues: (values) => ({
...values,
email: values.email.toLowerCase(),
}),
})
```
--------------------------------
### SchemaForm Component: Custom Layout with Zod Schema
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Allows for custom form layouts using the SchemaForm component by providing children as a function. This enables granular control over the rendering of each field and form elements. Dependencies include 'remix-forms' and 'zod'. Input is a Zod schema and render props, output is a custom-laid-out form.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
// Define schema
const schema = z.object({
firstName: z.string().min(1, 'Required'),
email: z.string().email('Invalid email'),
age: z.number().min(18, 'Must be 18+'),
howDidYouFindUs: z.enum(['aFriend', 'google', 'twitter']),
message: z.string().optional(),
})
// Custom layout with children function
export default function CustomForm() {
return (
{({ Field, Errors, Button }) => (
<>
You'll hear from us at this address 👆
>
)}
)
}
```
--------------------------------
### Handling Array Fields with Remix Forms and Zod
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Demonstrates how to manage arrays of primitives or objects using Zod's array schemas within Remix Forms. It enables automatic field generation and dynamic add/remove functionality for array elements, like tags or contact information.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
const schema = z.object({
name: z.string().min(1),
tags: z.array(z.string()).min(1, 'At least one tag required'),
contacts: z.array(
z.object({
email: z.string().email(),
phone: z.string().optional(),
})
).min(1),
})
export default function ArrayFieldsForm() {
return (
{({ Field, Button, register, watch, setValue }) => {
const contacts = watch('contacts') || []
return (
<>
Tags
Contacts
{contacts.map((_, index) => (
))}
>
)
}}
)
}
```
--------------------------------
### Implement Global Error Handling in Remix Forms
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
This snippet demonstrates how to handle global form errors, such as authentication failures, that do not pertain to specific fields. It uses `formAction` and `applySchema` from `remix-forms` and `composable-functions`, along with `zod` for schema validation.
```tsx
import { formAction } from 'remix-forms'
import { applySchema } from 'composable-functions'
import { z } from 'zod'
import type { Route } from './+types/login'
const schema = z.object({
email: z.string().email(),
password: z.string().min(1),
})
const mutation = applySchema(schema)(async (values) => {
const user = await authenticate(values.email, values.password)
if (!user) {
// Return global error
return {
success: false,
errors: {
_global: ['Invalid email or password'],
},
}
}
return { userId: user.id }
})
export const action = async ({ request }: Route.ActionArgs)
=> formAction({
request,
schema,
mutation,
successPath: '/dashboard',
})
export default function LoginForm() {
return (
{({ Field, Errors, Button }) => (
<>
>
)}
)
}
```
--------------------------------
### SchemaForm Component: Auto-Generated Form with Zod Schema
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
The SchemaForm component automatically generates form fields based on a provided Zod schema. It handles input types, validation, and submission. Dependencies include 'remix-forms' and 'zod'. Input is a Zod schema object, and output is a fully rendered form.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
// Define schema
const schema = z.object({
firstName: z.string().min(1, 'Required'),
email: z.string().email('Invalid email'),
age: z.number().min(18, 'Must be 18+'),
howDidYouFindUs: z.enum(['aFriend', 'google', 'twitter']),
message: z.string().optional(),
})
// Auto-generated form
export default function SimpleForm() {
return (
)
}
```
--------------------------------
### Use Hidden Fields and Pre-fill Form Values with Remix Forms
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
This snippet demonstrates how to utilize hidden fields for sensitive data like IDs or CSRF tokens and how to pre-fill form fields with initial data fetched from a loader. It uses `SchemaForm` from `remix-forms` and `zod` for schema validation.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
import type { Route } from './+types/edit'
const schema = z.object({
id: z.string(),
title: z.string().min(1),
slug: z.string().min(1),
content: z.string().min(10),
})
export const loader = async ({ params }: Route.LoaderArgs) => {
const post = await getPost(params.id)
return { post }
}
export default function EditForm({ loaderData }: Route.ComponentProps) {
const { post } = loaderData
return (
{({ Field, Button }) => (
<>
>
)}
)
}
```
--------------------------------
### Custom Field Rendering with SchemaForm
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Enables granular control over individual field layouts using the `Field` component's children function. This allows for custom markup and component composition within forms.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
const schema = z.object({
email: z.string().email(),
terms: z.boolean().refine((val) => val === true, {
message: 'You must accept the terms',
}),
})
export default function CustomFieldForm() {
return (
{({ Field, Button }) => (
<>
{({ Label, SmartInput, Errors }) => (
You'll hear from us at this address 👇
)}
{({ SmartInput, Label, Errors }) => (
)}
>
)}
)
}
```
--------------------------------
### React Hook Form Integration with SchemaForm
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
This snippet shows how to use the SchemaForm component from 'remix-forms' with Zod for schema validation. It exposes react-hook-form's methods via a children render prop, allowing for dynamic UI updates based on form state, programmatic field manipulation (setValue), form resetting, and validation triggering.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
const schema = z.object({
firstName: z.string().min(1),
lastName: z.string().min(1),
email: z.string().email(),
})
export default function ReactHookFormIntegration() {
return (
{({
Field,
Button,
formState,
watch,
setValue,
reset,
trigger,
}) => {
const firstName = watch('firstName')
const isDirty = formState.isDirty
const touchedFields = formState.touchedFields
return (
<>
{firstName && (
Hello, {firstName}!
)}
{isDirty && (
You have unsaved changes
)}
>
)
}}
)
}
```
--------------------------------
### Configuring Validation Modes in Remix Forms with Zod
Source: https://context7.com/seasonedcc/remix-forms/llms.txt
Control the timing of form validation in Remix Forms using different 'mode' and 'reValidateMode' options, paired with Zod schemas. This allows for fine-tuning user experience, from immediate feedback on change to validation solely upon submission.
```tsx
import { SchemaForm } from 'remix-forms'
import { z } from 'zod'
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
// Validate on blur (default)
export function OnBlurForm() {
return (
)
}
// Validate on change (immediate feedback)
export function OnChangeForm() {
return (
)
}
// Validate on submit only (least intrusive)
export function OnSubmitForm() {
return (
)
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.