Form
Fully-featured form component with validation, error messages, and more. Built on top of React Hook Form and zod.
Installation
npx @rahimstack@latest add form
Usage
import {defineSchema, Field, Form} from "@/workshop/form"
const schema = defineSchema(({ z, presets }) => z.object({
name: z.string().min(2),
birthday: presets.datePicker,
bounty: z.string()
.refine(v => Number(v) >= 3_000_000_000,
{ message: "Bounty must be at least ฿3,000,000,000" })
}))
export function FormDemo() {
return (
<Form
schema={schema}
onSubmit={data => {/* ... */}}
defaultValues={/* ... */}
>
<div className="flex gap-3">
<Field.Text name="name" label="Name" />
<Field.DatePicker name="birthday" label="Birthday" />
</div>
<Field.Currency
name="bounty"
label="Bounty"
prefix="฿"
/>
<Field.Submit role="save">Save</Field.Submit>
</Form>
)
}
Define a schema
You can define a schema using the defineSchema
function. This function takes a callback function that provides you with a z
object and a presets
object.
The z
object is the zod library, and the presets
object contains some useful presets for common form fields.
You can see or edit the presets in @/components/ui/form/schema-presets.ts
.
Example
import { defineSchema } from "@/components/ui/form"
const schema = defineSchema(({z, presets}) => z.object({
name: z.string().min(2),
birthday: presets.datePicker,
phone: presets.phone,
profilePicture: presets.files,
// ...
}))
Render the form
import { Form, Field, defineSchema } from "@/components/ui/form"
const schema = defineSchema(({ z, presets }) => z.object({
full_name: z.string().min(2),
phone: presets.phone,
}))
export function FormDemo() {
return (
<Form
schema={schema}
onSubmit={data => { // `data` is correctly typed
console.log("full_name", data.full_name)
console.log("phone", data.phone)
}}
>
<Field.Text
label="Full name"
name="full_name"
/>
<Field.PhoneNumber
label="Phone"
name="phone"
/>
<Field.Submit>Submit</Field.Submit>
</Form>
)
}
Field
Field
is a polymorphic component made with pre-built input components.
You can see the implementation of these inputs in @/components/ui/form/fields.tsx
.
Submit
Field.Submit
is a button that submits the form. It has some built-in features:
- Setting
disableIfInvalid
totrue
will disable the button if the form is invalid. - Setting
showLoadingOverlayOnCreate
totrue
will render a loading overlay when therole
is"create"
and the form is submitted. (This istrue
by default) - Setting
showLoadingOverlayOnSuccess
totrue
will render a loading overlay when the form is submitted. - Setting
disableOnSuccess
totrue
will disable the button when the form is submitted. (This istrue
by default whenrole
is"create"
)
API Reference
No styles