Overview
FormEngineBlock renders dynamic forms from block definitions stored in the database. Unlike FormBlock which is built with JSX at compile time, FormEngineBlock interprets block schemas at runtime, enabling administrators to create and modify surveys without code changes.
Key Features
- Render forms from database-stored block definitions
- Support for text inputs, single/multi choice, rating scales, and content blocks
- Built-in validation with required field support
- Success state with customizable message or content
When to Use
Use FormEngineBlock when:
- Building participant-facing surveys or quizzes from database schemas
- Form structure needs to be editable by administrators without code deployment
- Rendering resources with dynamic block-based content
Use FormBlock instead when:
- -Building admin forms with compile-time known structure
- -Forms require complex field interactions or custom components
Live Examples
Product Feedback Survey
Complete survey demonstrating all block types working together
Rating Scale Variants
Stars, numbers, and labeled rating scales
Rating scales support three styles: stars (interactive icons), numbers (toggle group), and labels (custom text buttons).
Block Types
| Block Type | Purpose | Key Config |
|---|---|---|
| content | Static text, instructions, or HTML | content, format |
| text_input | Short or long text entry | variant, placeholder, minLength, maxLength |
| single_choice | Radio button selection | options, layout, allowOther |
| multi_choice | Checkbox multi-selection | options, minSelections, maxSelections |
| rating_scale | Star, number, or label ratings | minValue, maxValue, style, labels |
// Content block - static text/instructions
{
id: 'intro',
blockType: 'content',
config: {
content: 'Instructions text...',
format: 'text' | 'markdown' | 'html',
},
required: false,
order: 0,
}
// Text input - short or long text
{
id: 'feedback',
blockType: 'text_input',
config: {
label: 'Your Feedback',
description: 'Optional description',
placeholder: 'Enter text...',
variant: 'short' | 'long',
minLength: 10,
maxLength: 500,
},
required: true,
order: 1,
}
// Single choice - radio buttons
{
id: 'preference',
blockType: 'single_choice',
config: {
label: 'Your Preference',
options: [
{ id: 'opt1', label: 'Option 1' },
{ id: 'opt2', label: 'Option 2' },
],
layout: 'vertical' | 'horizontal' | 'grid',
allowOther: true,
},
required: true,
order: 2,
}
// Multi choice - checkboxes
{
id: 'features',
blockType: 'multi_choice',
config: {
label: 'Select Features',
options: [...],
minSelections: 1,
maxSelections: 3,
},
required: true,
order: 3,
}
// Rating scale - stars, numbers, or labels
{
id: 'rating',
blockType: 'rating_scale',
config: {
label: 'Rate Your Experience',
minValue: 1,
maxValue: 5,
step: 1,
style: 'stars' | 'numbers' | 'labels',
labels: { min: 'Poor', max: 'Excellent' },
},
required: true,
order: 4,
}Props Reference
FormEngineBlock Props
| Prop | Type | Default | Description |
|---|---|---|---|
blocks | FormEngineBlockDef[] | required | Block definitions from database |
onSubmit | (responses) => Promise<void> | required | Called with form responses on submit |
defaultValues | FormEngineResponses | - | Pre-fill form with existing responses |
isLoading | boolean | false | Show loading state on submit button |
submitLabel | string | "Submit" | Text for the submit button |
successMessage | string | "Submitted successfully!" | Message shown after successful submit |
successContent | ReactNode | - | Custom content to show after submit |
disabled | boolean | false | Disable all form inputs |
className | string | - | Additional CSS classes |
FormEngineBlockDef Type
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | required | Unique block identifier (used as form field name) |
blockType | string | required | Block type (content, text_input, single_choice, etc.) |
config | Record<string, unknown> | required | Block-specific configuration |
required | boolean | required | Whether the field requires a response |
order | number | required | Display order (blocks are sorted by this) |
Usage
import { FormEngineBlock } from '@/ui/blocks';
import type { FormEngineBlockDef } from '@/ui/blocks/form-engine/types';
// Blocks typically come from your database
const blocks: FormEngineBlockDef[] = [
{
id: 'intro',
blockType: 'content',
config: { content: 'Please answer the following questions.' },
required: false,
order: 0,
},
{
id: 'name',
blockType: 'text_input',
config: { label: 'Your Name', placeholder: 'Enter your name...' },
required: true,
order: 1,
},
{
id: 'satisfaction',
blockType: 'rating_scale',
config: {
label: 'Overall Satisfaction',
minValue: 1,
maxValue: 5,
step: 1,
style: 'stars',
},
required: true,
order: 2,
},
];
<FormEngineBlock
blocks={blocks}
onSubmit={async (responses) => {
await saveResponses(responses);
}}
submitLabel="Submit Survey"
/>