Chalk UI
Getting started
Customization
Dark Mode
CLI
Components
Accordion
Address Input
Alert
App Layout
Autocomplete
Avatar
Badge
Breadcrumbs
Button
Calendar
Card
Carousel
Chart (Area)
Chart (Bar)
Chart (Donut)
Chart (Line)
Checkbox
Checkbox Group
Collapsible
Combobox
Command
Currency Input
DataGrid
Date Picker
Date Range Picker
Disclosure
Drawer
Dropdown Menu
Form
Horizontal Draggable Scroll
Hover Card
Loading Spinner
Loading Overlay
Modal
Native Select
Navigation Menu
Number Input
Page Header
Pagination
Phone Input
Popover
Progress Bar
Radio Group
Scroll Area
Select
Separator
Simple Dropzone
Skeleton
Static Tabs
Stats
Switch
Table
Tabs
Text Input
Textarea
Timeline
Toaster
Tooltip
Vertical Menu

Form

Fully-featured form component with validation, error messages, and more. Built on top of React Hook Form and zod.

Source

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 to true will disable the button if the form is invalid.
  • Setting showLoadingOverlayOnCreate to true will render a loading overlay when the role is "create" and the form is submitted. (This is true by default)
  • Setting showLoadingOverlayOnSuccess to true will render a loading overlay when the form is submitted.
  • Setting disableOnSuccess to true will disable the button when the form is submitted. (This is true by default when role is "create")

API Reference

No styles