This is the interactive counterpart to our talk at Remix Conf 2022. Get the full slides.
Custom layout
Finally, let's make the form look exactly as before.
54
lines of code
import { ActionFunction } from '@remix-run/node'
import { z } from 'zod'
import { InputError, makeDomainFunction } from 'domain-functions'
// Learn how to create these files on "Get Started" ๐๐ฝ
import { formAction } from '~/form-action'
import { Form } from '~/form'
const reservationSchema = z.object({
city: z.enum(['saltLakeCity', 'lasVegas', 'losAngeles']),
checkIn: z.date(),
checkOut: z.date(),
adults: z.number().int().positive(),
children: z.number().int(),
bedrooms: z.number().int().positive(),
specialRequests: z.string().optional(),
})
const makeReservation = makeDomainFunction(reservationSchema)(
async (values) => {
if (values.specialRequests?.match(/towels/i)) {
throw new InputError("Don't be such a diva!", 'specialRequests')
}
// Here you would store data instead
console.log(values)
},
)
export const action: ActionFunction = async ({ request }) =>
formAction({
request,
schema: reservationSchema,
mutation: makeReservation,
successPath: 'conf/success/09',
})
export default function Component() {
return (
<Form schema={reservationSchema}>
{({ Field, Errors, Button }) => (
<>
<Field name="city" />
<div className="flex w-full space-x-4">
<Field name="checkIn" className="flex-1" />
<Field name="checkOut" className="flex-1" />
</div>
<div className="flex w-full space-x-4">
<Field name="adults" />
<Field name="children" />
<Field name="bedrooms" />
</div>
<Field name="specialRequests" multiline />
<Errors />
<Button>Make reservation</Button>
</>
)}
</Form>
)
}
This is the interactive counterpart to our talk at Remix Conf 2022. Get the full slides.
Custom layout
Finally, let's make the form look exactly as before.
54
lines of code
import { ActionFunction } from '@remix-run/node'
import { z } from 'zod'
import { InputError, makeDomainFunction } from 'domain-functions'
// Learn how to create these files on "Get Started" ๐๐ฝ
import { formAction } from '~/form-action'
import { Form } from '~/form'
const reservationSchema = z.object({
city: z.enum(['saltLakeCity', 'lasVegas', 'losAngeles']),
checkIn: z.date(),
checkOut: z.date(),
adults: z.number().int().positive(),
children: z.number().int(),
bedrooms: z.number().int().positive(),
specialRequests: z.string().optional(),
})
const makeReservation = makeDomainFunction(reservationSchema)(
async (values) => {
if (values.specialRequests?.match(/towels/i)) {
throw new InputError("Don't be such a diva!", 'specialRequests')
}
// Here you would store data instead
console.log(values)
},
)
export const action: ActionFunction = async ({ request }) =>
formAction({
request,
schema: reservationSchema,
mutation: makeReservation,
successPath: 'conf/success/09',
})
export default function Component() {
return (
<Form schema={reservationSchema}>
{({ Field, Errors, Button }) => (
<>
<Field name="city" />
<div className="flex w-full space-x-4">
<Field name="checkIn" className="flex-1" />
<Field name="checkOut" className="flex-1" />
</div>
<div className="flex w-full space-x-4">
<Field name="adults" />
<Field name="children" />
<Field name="bedrooms" />
</div>
<Field name="specialRequests" multiline />
<Errors />
<Button>Make reservation</Button>
</>
)}
</Form>
)
}