Grouped Layout
Form with multiple field groups and various field sizes.
"use client";
import { z } from "zod";
import { FormBuilder } from "@tilt-legal/cubitt-components/form-builder";
const schema = z.object({
title: z.string().min(1, "Required"),
code: z.string().optional(),
description: z.string().optional(),
practiceArea: z.string(),
priority: z.enum(["low", "normal", "high"]),
confidential: z.boolean().default(false),
});
const formDefs = [
{
kind: "group",
title: "Matter Basics",
children: [
{
kind: "field",
name: "title",
label: "Title",
component: "text",
size: "half",
},
{
kind: "field",
name: "code",
label: "Matter Code",
component: "text",
size: "half",
},
{
kind: "field",
name: "description",
label: "Description",
component: "textarea",
size: "full",
},
],
},
{
kind: "group",
title: "Classification",
children: [
{
kind: "field",
name: "practiceArea",
label: "Practice Area",
component: "select",
options: [
{ label: "Corporate", value: "corp" },
{ label: "Litigation", value: "lit" },
{ label: "IP", value: "ip" },
],
},
{
kind: "field",
name: "priority",
label: "Priority",
component: "radio",
options: [
{ id: "low", value: "low", label: "Low" },
{ id: "normal", value: "normal", label: "Normal" },
{ id: "high", value: "high", label: "High" },
],
},
{
kind: "field",
name: "confidential",
label: "Confidential",
component: "switch",
},
],
},
] as const satisfies FormDefs;
export default function GroupedForm() {
return (
<FormBuilder.Single
schema={schema}
formDefs={formDefs}
defaultValues={{
title: "",
code: "",
description: "",
practiceArea: "",
priority: "normal",
confidential: false,
}}
submitLabel="Save"
onSubmit={async (values) => console.log(values)}
/>
);
}How It Works
- Wrap fields in group nodes – Use
kind: "group"with atitleandchildrenarray - Use size hints – Set
size: "half"orsize: "full"to control field widths - Mix component types – Text, textarea, select, radio, and switch all work together
See Group Nodes for all available group properties.