Form Builder
Preview

Schema-driven form rendering with TanStack Form, Zod validation, and accessible Cubitt fields.

Form Builder turns a typed Zod schema and a formDefs tree into Cubitt form UI. Use FormBuilder.Single for one record and FormBuilder.Bulk when the same definitions need CSV import, column mapping, grid editing, and row validation.

Usage

import {
  FormBuilder,
  type FormDefs,
} from "@tilt-legal/cubitt-components/form-builder";
const formDefs = [
  {
    kind: "field",
    name: "email",
    label: "Email",
    component: "email",
    size: "full",
  },
] as const satisfies FormDefs<Member>;

Core Model

import { z } from "zod";
import type { FormDefs } from "@tilt-legal/cubitt-components/form-builder";

const memberSchema = z.object({
  firstName: z.string().min(1, "Required"),
  lastName: z.string().min(1, "Required"),
  email: z.string().email("Invalid email"),
});

type Member = z.infer<typeof memberSchema>;

const memberFormDefs = [
  {
    kind: "field",
    name: "firstName",
    label: "First name",
    component: "text",
    size: "half",
  },
  {
    kind: "field",
    name: "lastName",
    label: "Last name",
    component: "text",
    size: "half",
  },
  {
    kind: "field",
    name: "email",
    label: "Email",
    component: "email",
    size: "full",
  },
] as const satisfies FormDefs<Member>;

Utilities

UtilityDescription
useFormBuilderLow-level hook for single-record TanStack forms
useBulkFormBuilderLow-level hook for bulk row validation
injectZodErrorsInject Zod issues into field errors
injectFormErrorAdd form-level error messages
flattenFormDefsFlatten nested definitions into field metadata
shapeRowsCoerce CSV rows using field metadata
mapZodErrorMap Zod issues to field paths
FieldRendererRender a field from a definition inside a field context

On this page