FieldCraftDocsServicesBlogWork With Me →

FormEngineRenderer

The drop-in React component for rendering forms.

FormEngineRenderer is the primary React component for rendering a form from a schema. It creates the engine internally, applies theming, renders all fields, and handles navigation and submission.

Basic Usage

import { FormEngineRenderer } from "@squaredr/fieldcraft-react";
import type { FormEngineSchema } from "@squaredr/fieldcraft-core";

const schema: FormEngineSchema = {
id: "contact",
version: "1.0.0",
title: "Contact Us",
submitAction: { type: "callback" },
sections: [
{
id: "main",
title: "Your Details",
questions: [
{ id: "name", type: "short_text", label: "Name", required: true },
{ id: "email", type: "email", label: "Email", required: true },
],
},
],
};

export default function ContactForm() {
return (
<FormEngineRenderer
schema={schema}
onSubmit={(response) => console.log(response)}
/>
);
}

Props

PropTypeDescription
schemaFormEngineSchemaThe form schema (required)
onSubmit(response: FormResponse) => voidCallback when form is submitted
adaptersSubmitAdapter | SubmitAdapter[]Storage adapters for persistence
themeFormEngineThemeTheme preset or custom theme
componentsFieldRegistryCustom field component overrides
prefillRecord<string, unknown>Pre-fill values from external data
initialValuesRecord<string, unknown>Initial field values
classNamestringCSS class for the wrapper
sessionTokenstringToken for draft persistence
validatorsRecord<string, CustomValidator>Custom sync validators
asyncValidatorsRecord<string, AsyncValidator>Custom async validators

Callback Props

PropTypeDescription
onReady(engine: FormEngine) => voidCalled when the engine is initialized
onFieldChange(fieldId: string, value: unknown) => voidCalled on every field change
onSectionChange(sectionId: string, index: number) => voidCalled when navigating between sections
onValidationError(errors: Record<string, string[]>) => voidCalled when validation fails
onStateChange(state: FormState) => voidCalled on any state change

Label Props

PropTypeDefault
prevLabelstring"Back"
nextLabelstring"Next"
submitLabelstring"Submit"

With Theme

import { FormEngineRenderer } from "@squaredr/fieldcraft-react";
import { darkPreset } from "@squaredr/fieldcraft-react";

<FormEngineRenderer
schema={schema}
theme={darkPreset}
onSubmit={handleSubmit}
/>

With Custom Components

import { FormEngineRenderer } from "@squaredr/fieldcraft-react";
import type { FieldProps } from "@squaredr/fieldcraft-react";

function MyRatingField({ field, value, onChange }: FieldProps) {
return <div>{/* custom rating UI */}</div>;
}

<FormEngineRenderer
schema={schema}
components={{ rating: MyRatingField }}
onSubmit={handleSubmit}
/>

With Adapters

import { FormEngineRenderer } from "@squaredr/fieldcraft-react";
import { createSupabaseAdapter } from "@squaredr/fieldcraft-supabase";

const adapter = createSupabaseAdapter({
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
});

<FormEngineRenderer
schema={schema}
adapters={adapter}
onSubmit={(response) => console.log("Saved:", response)}
/>

With Draft Persistence

<FormEngineRenderer
schema={schema}
sessionToken="user-abc-123"
onSubmit={handleSubmit}
/>

When sessionToken is provided and the schema has allowDraftSave: true, the renderer automatically saves drafts and shows a resume prompt if a previous draft is found.

Accessing the Engine

Use the onReady callback to get a reference to the engine for imperative operations:

function MyForm() {
const engineRef = useRef<FormEngine | null>(null);

return (
<>
<FormEngineRenderer
schema={schema}
onReady={(engine) => { engineRef.current = engine; }}
onSubmit={handleSubmit}
/>
<button onClick={() => engineRef.current?.jumpTo("section_3")}>
Skip to Section 3
</button>
</>
);
}

What It Renders

Internally, FormEngineRenderer composes these sub-components:

  • FormEngineThemeProvider — applies CSS variables for theming
  • ProgressBar — section progress indicator
  • SectionRenderer — renders the current section and its fields
  • NavigationButtons — Back / Next / Submit buttons
  • ErrorSummary — validation errors after submit attempt
  • DraftResumePrompt — resume prompt when a draft is detected
  • CompletionScreen — shown after successful submission