Back to Playground

Reference SchemaForm

Build the schema and see the form breathe.

Add fields, arrange sections and groups, tune grid spans, then preview with the reference FieldRenderer.

Palette

Add production field types fast.

Layout

Tune section, group, colSpan and rowSpan.

Schema

Flip between live preview and zod metadata.

Live builder

6 fields in the current schema.

Field palette

Add fields, then select one to configure it.

Full Name
text / 6 of 12
Email
email / 6 of 12
Role
select / 4 of 12
Bio
textarea / 8 of 12
Skills
multiselect / 6 of 12
Subscribe to newsletter
checkbox / 6 of 12

Form Preview

Rendered through the reference FieldRenderer. Press Ctrl+Enter to submit.

Employment

Role Details
Skills & Expertise
JSON previewlive values
{}

Submit captures a snapshot — live values update as you type.

Field Config

Select a field to edit its schema metadata.

Select a field

Palette: add production field types with one click and configure labels, validation, and options.

Layout: arrange fields into sections and groups with colSpan and rowSpan grid control.

Preview: live FieldRenderer maps schema to inputs — what you configure is what renders.

Usage

TSX
import { z } from 'zod'
import { SchemaForm } from '@/components/form/SchemaForm'
import { fieldMeta } from '@/components/form/fieldMeta'

const schema = z.object({
  full_name: z.string().min(1).describe(fieldMeta({
    label: 'Full Name', placeholder: 'Enter your name', colSpan: 6
  })),
  email: z.string().email().describe(fieldMeta({
    label: 'Email', placeholder: 'you@example.com', colSpan: 6
  })),
  role: z.enum(['developer','designer','manager']).describe(fieldMeta({
    label: 'Role', colSpan: 6, section: 'Employment', inputType: 'select',
    options: [{ label: 'Developer', value: 'developer' }, { label: 'Designer', value: 'designer' }]
  })),
})

export default function EmployeeForm() {
  return (
    <SchemaForm
      schema={schema}
      onSubmit={(data) => console.log(data)}
      submitLabel="Submit"
    />
  )
}

What is a schema-based form?

A schema-based form is a form whose fields, layout, and validation rules are declared as data instead of hand-written JSX. Instead of hard-coding every input and button, you describe the form in a typed metadata object — field type, label, validation, section, grid span — and a generic renderer turns that metadata into the actual UI.

This playground is a working demonstration of that pattern. Use the palette on the left to add fields, arrange them into sections and groups, tune colSpan and rowSpan, then watch the reference FieldRenderer build the live preview from that schema.

How it works

The builder produces a TypeScript-typed schema describing every field and its layout. That same schema drives the live preview and can be exported as generated Zod schema code — so the runtime validation, the type definitions, and the rendered form never drift apart.

The reusable FieldRenderer maps each field definition to its React input component, applies the configured validation, and respects the section and grid layout metadata. Add a field type once and every form built with the system inherits it.

Features

  • Visual field palette with production field types
  • Live FieldRenderer preview as you configure
  • Sections, groups, colSpan and rowSpan layout control
  • Multi-select, password, switch, checkbox, select and text fields
  • Generated Zod schema code with TypeScript metadata
  • Schema-driven rendering — no hand-written form JSX

When to use schema-driven forms

This pattern pays off when an application ships many similar forms — ERP modules, admin panels, CRM entry screens, settings pages. Teams building role-based access control systems also benefit: fields and sections can be filtered per role using the same schema metadata that drives the UI.

Built with React, TypeScript and Zod. Related demo: the React DataTable playground, which pairs these forms with sortable, paginated data grids.