Page Designer - Forms Documentation
Version: 2.0
Last Updated: March 13, 2026
Scope: Form design, creation, validation, and workflow integration
Overview
The Form Designer enables creation of dynamic, data-driven forms with advanced features including:
- 25+ input field types for comprehensive data collection
- 13+ layout containers for complex form structures
- Client-side & server-side validation with custom rules
- Conditional logic for dynamic field visibility and behavior
- Calculated fields with formula support
- Workflow integration for post-submission automation
- Multi-step wizards for guided data collection
- File upload handling with size/type restrictions
- Responsive design with mobile support
Page Mode: "form"
All form configurations must set pageMode: "form" in the root configuration.
interface FormPage {
id: string;
name: string;
pageMode: 'form';
components: FormField[];
settings?: FormSettings;
}
interface FormSettings {
submitAction?: 'save' | 'submit' | 'draft';
confirmMessage?: string;
redirectUrl?: string;
successMessage?: string;
errorMessage?: string;
triggerWorkflow?: WorkflowConfig;
}
Input Components (25 Types)
Basic Text Input Fields
1. Text Field
Type: 'text'
Purpose: Single-line text input for names, titles, descriptions
When to Use: Names, email, usernames, short text entries
Parameters:
- label: string (required) | "User Name"
- placeholder: string | "Enter your name"
- maxLength: number | 100
- pattern: string | "^[a-zA-Z ]*$" (regex for validation)
- prefix: string | "👤" (icon or text prefix)
- suffix: string | ".com" (icon or text suffix)
- description: string | "Enter your full legal name"
- disabled: boolean | false
- required: boolean | true
- defaultValue: string | "Guest"
- showCharacterCount: boolean | true
- validation: ValidationRule[] | []
Example:
{
id: 'firstName',
type: 'text',
label: 'First Name',
placeholder: 'John',
maxLength: 50,
required: true,
validation: [
{ type: 'required', message: 'First name is required' },
{ type: 'minLength', value: 2, message: 'Minimum 2 characters' }
]
}
2. Textarea
Type: 'textarea'
Purpose: Multi-line text input for comments, descriptions, notes
When to Use: Long text entries, feedback, comments, descriptions
Parameters:
- label: string | "Comments"
- placeholder: string | "Enter your feedback..."
- rows: number | 4 (number of visible rows)
- maxLength: number | 500
- showCharacterCount: boolean | true
- required: boolean | false
- validation: ValidationRule[] | []
Example:
{
id: 'feedback',
type: 'textarea',
label: 'Feedback',
placeholder: 'Share your thoughts...',
rows: 6,
maxLength: 1000,
showCharacterCount: true,
required: true
}
3. Email Field
Type: 'email'
Purpose: Email address input with format validation
When to Use: Contact forms, user registration, newsletter signup
Parameters:
- label: string | "Email Address"
- placeholder: string | "john@example.com"
- multiple: boolean | false (allow comma-separated multiple emails)
- required: boolean | true
- validation: ValidationRule[] | (auto-includes email pattern)
Example:
{
id: 'email',
type: 'email',
label: 'Email Address',
placeholder: 'your@email.com',
required: true,
validation: [
{ type: 'email', message: 'Invalid email format' }
]
}
4. Password Field
Type: 'password'
Purpose: Secure password input with masked characters
When to Use: Login forms, password changes, sensitive data entry
Parameters:
- label: string | "Password"
- placeholder: string | "Enter your password"
- minLength: number | 8
- showStrengthMeter: boolean | true
- strengthRules: { min, contains } | { min: 8, contains: ['uppercase', 'number', 'special'] }
- required: boolean | true
Example:
{
id: 'password',
type: 'password',
label: 'Password',
minLength: 8,
showStrengthMeter: true,
required: true,
validation: [
{
type: 'pattern',
value: '^(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*]).*$',
message: 'Must contain uppercase, number, and special character'
}
]
}
5. Phone Number Field
Type: 'phone'
Purpose: Phone number input with country code formatting
When to Use: Contact information, mobile app authentication, support tickets
Parameters:
- label: string | "Phone Number"
- countryCode: string | "US" (country code for formatting)
- placeholder: string | "(555) 123-4567"
- required: boolean | false
- validation: ValidationRule[] | []
Example:
{
id: 'phone',
type: 'phone',
label: 'Mobile Number',
countryCode: 'US',
placeholder: '(555) 123-4567',
required: true,
validation: [
{ type: 'pattern', value: '^\\+?[0-9]{10,}$', message: 'Invalid phone number' }
]
}
6. URL Field
Type: 'url'
Purpose: Website URL input with validation
When to Use: Website links, portfolio links, social media profiles
Parameters:
- label: string | "Website"
- placeholder: string | "https://example.com"
- required: boolean | false
- validation: ValidationRule[] | (auto-includes URL pattern)
Example:
{
id: 'website',
type: 'url',
label: 'Portfolio Website',
placeholder: 'https://yoursite.com',
required: false
}
7. Number Field
Type: 'number'
Purpose: Numeric input for quantities, ages, measurements
When to Use: Quantities, ages, prices, measurements, ratings
Parameters:
- label: string | "Quantity"
- min: number | 0
- max: number | 1000
- step: number | 1 (increment/decrement value)
- placeholder: string | "Enter quantity"
- required: boolean | false
- validation: ValidationRule[] | []
Example:
{
id: 'quantity',
type: 'number',
label: 'Order Quantity',
min: 1,
max: 100,
step: 1,
required: true,
validation: [
{ type: 'min', value: 1, message: 'Must be at least 1' },
{ type: 'max', value: 100, message: 'Cannot exceed 100' }
]
}
8. Currency Field
Type: 'currency'
Purpose: Monetary amount input with currency formatting
When to Use: Prices, payments, budget amounts, financial data
Parameters:
- label: string | "Price"
- currency: string | "USD" (ISO 4217 code)
- min: number | 0
- max: number | 999999.99
- step: number | 0.01
- placeholder: string | "0.00"
Example:
{
id: 'price',
type: 'currency',
label: 'Product Price',
currency: 'USD',
min: 0.01,
max: 99999.99,
required: true
}
Date & Time Fields
9. Date Field
Type: 'date'
Purpose: Single date selection
When to Use: Birth dates, event dates, deadlines, appointment dates
Parameters:
- label: string | "Date of Birth"
- placeholder: string | "MM/DD/YYYY"
- min: string | "2000-01-01" (ISO format)
- max: string | "2023-12-31"
- disabledDates: string[] | ["2024-02-14"] (specific dates to disable)
- required: boolean | false
Example:
{
id: 'birthDate',
type: 'date',
label: 'Date of Birth',
required: true,
min: '1920-01-01',
max: new Date().toISOString().split('T')[0],
validation: [
{ type: 'custom', customValidation: 'new Date(value) < new Date()' }
]
}
10. Date Range Field
Type: 'daterange'
Purpose: Date range selection (start and end dates)
When to Use: Vacation dates, project duration, subscription periods, search filters
Parameters:
- label: string | "Travel Dates"
- startLabel: string | "Start Date"
- endLabel: string | "End Date"
- minDays: number | 1 (minimum gap between dates)
- maxDays: number | 365 (maximum range)
- presets: { label, range } | { label: 'Last 7 Days', range: [-7, 0] }
- required: boolean | false
Example:
{
id: 'travelDates',
type: 'daterange',
label: 'Travel Dates',
startLabel: 'Departure',
endLabel: 'Return',
minDays: 1,
maxDays: 30,
required: true,
presets: [
{ label: 'Weekend', range: [0, 1] },
{ label: 'Week', range: [0, 6] },
{ label: 'Two Weeks', range: [0, 13] }
]
}
11. Time Field
Type: 'time'
Purpose: Time selection (hours and minutes)
When to Use: Appointment times, business hours, event times, scheduling
Parameters:
- label: string | "Appointment Time"
- placeholder: string | "HH:MM"
- format: string | "HH:mm" or "h:mm A" (12/24 hour)
- min: string | "09:00" (business hours start)
- max: string | "17:00" (business hours end)
- step: number | 15 (minute increments)
- required: boolean | false
Example:
{
id: 'appointmentTime',
type: 'time',
label: 'Preferred Appointment Time',
format: 'h:mm A',
min: '09:00',
max: '17:00',
step: 30,
required: true
}
12. DateTime Field
Type: 'datetime'
Purpose: Date and time combined selection
When to Use: Appointment scheduling, event creation, meeting times, timestamps
Parameters:
- label: string | "Meeting DateTime"
- format: string | "MM/DD/YYYY HH:mm"
- min: string | ISO datetime string
- max: string | ISO datetime string
- required: boolean | false
Example:
{
id: 'meetingTime',
type: 'datetime',
label: 'Meeting Time',
format: 'MM/DD/YYYY h:mm A',
required: true
}
Selection Fields
13. Select (Dropdown)
Type: 'select'
Purpose: Choose single value from dropdown list
When to Use: Status selection, category selection, country/state selection
Parameters:
- label: string | "Country"
- placeholder: string | "Select a country"
- options: FieldOption[] | [{ label: 'USA', value: 'US' }]
- dataSource: DataSource | { type: 'api', url: '/api/countries' }
- searchable: boolean | true (enable search in dropdown)
- clearable: boolean | true (show clear button)
- required: boolean | false
- defaultValue: string | "US"
Example: Static Data
{
id: 'country',
type: 'select',
label: 'Country',
placeholder: 'Choose your country',
required: true,
options: [
{ label: 'United States', value: 'US' },
{ label: 'Canada', value: 'CA' },
{ label: 'Mexico', value: 'MX' }
]
}
Example: Dynamic Data from API
{
id: 'department',
type: 'select',
label: 'Department',
dataSource: {
type: 'api',
url: '/api/departments',
valueProperty: 'id',
labelProperty: 'name',
method: 'GET'
},
searchable: true,
clearable: true,
required: true
}
Example: Cascading Select (depends on other field)
{
id: 'state',
type: 'select',
label: 'State',
dataSource: {
type: 'api',
url: '/api/states',
dependsOn: ['country'],
valueProperty: 'code',
labelProperty: 'name'
}
}
14. Radio Buttons
Type: 'radio'
Purpose: Choose single value from radio button options
When to Use: Preferences, yes/no questions, rating scales, single choice selection
Parameters:
- label: string | "Preference"
- options: FieldOption[] | required
- layout: 'vertical' | 'horizontal' | 'row' (default: vertical)
- required: boolean | false
- defaultValue: string | "option1"
Example:
{
id: 'shipmentType',
type: 'radio',
label: 'Shipping Method',
layout: 'vertical',
required: true,
options: [
{ label: 'Standard (5-7 days)', value: 'standard', },
{ label: 'Express (2-3 days)', value: 'express' },
{ label: 'Overnight', value: 'overnight' }
],
defaultValue: 'standard'
}
15. Checkbox
Type: 'checkbox'
Purpose: Single boolean toggle (true/false)
When to Use: Agreement acceptance, feature toggles, yes/no questions, opt-in
Parameters:
- label: string | "I agree to terms" (label appears as checkbox label)
- defaultValue: boolean | false
- required: boolean | false
- description: string | "Read Terms before checking"
- helpContent: string | "Detailed terms and conditions"
Example: Agreement Checkbox
{
id: 'agreeToTerms',
type: 'checkbox',
label: 'I agree to the Terms & Conditions',
required: true,
helpContent: {
title: 'Terms & Conditions',
content: 'Please read our terms carefully...',
mediaUrl: 'https://example.com/terms.pdf',
mediaType: 'pdf'
}
}
16. Checkbox Group
Type: 'checkbox-group'
Purpose: Multiple selection from checkbox options
When to Use: Multiple choice selection, feature selection, skills/tags selection
Parameters:
- label: string | "Select interests"
- options: FieldOption[] | required
- layout: 'vertical' | 'horizontal' | 'grid'
- maxSelected: number | undefined (maximum checkboxes to select)
- minSelected: number | 0 (minimum checkboxes to select)
- required: boolean | false
- defaultValue: string[] | []
Example:
{
id: 'interests',
type: 'checkbox-group',
label: 'Select your interests',
layout: 'grid',
minSelected: 1,
maxSelected: 5,
required: true,
options: [
{ label: 'Technology', value: 'tech' },
{ label: 'Sports', value: 'sports' },
{ label: 'Music', value: 'music' },
{ label: 'Travel', value: 'travel' },
{ label: 'Food', value: 'food' }
]
}
File & Media Fields
17. File Upload
Type: 'file'
Purpose: Single file upload with validation
When to Use: Profile pictures, documents, resumes, certificates, images
Parameters:
- label: string | "Upload Document"
- accept: string | ".pdf,.doc,.docx" or "image/*" (MIME types)
- maxFileSize: number | 5242880 (bytes, default 5MB)
- showFilePreview: boolean | true (for images)
- required: boolean | false
- storage: 'local' | 's3' | 'azure' (where to store)
- allowedFileTypes: string[] | ['image/jpeg', 'application/pdf']
Example:
{
id: 'resume',
type: 'file',
label: 'Upload Resume',
accept: '.pdf,.doc,.docx',
maxFileSize: 10485760, // 10MB
required: true,
validation: [
{ type: 'required', message: 'Resume is required' }
]
}
Example: Image Upload
{
id: 'profilePicture',
type: 'file',
label: 'Profile Picture',
accept: 'image/*',
maxFileSize: 5242880, // 5MB
showFilePreview: true,
allowedFileTypes: ['image/jpeg', 'image/png']
}
18. Multiple File Upload
Type: 'multifile'
Purpose: Upload multiple files at once
When to Use: Portfolio uploads, multiple documents, image galleries, batch uploads
Parameters:
- label: string | "Upload Files"
- accept: string | "*" (file types)
- maxFileSize: number | 5242880 (per file)
- maxFiles: number | 10 (total files allowed)
- maxTotalSize: number | 52428800 (total upload size)
- showFilePreview: boolean | true
- dragDrop: boolean | true (enable drag-drop)
- required: boolean | false
Example:
{
id: 'portfolioFiles',
type: 'multifile',
label: 'Upload Portfolio',
accept: '.pdf,.jpg,.png,.mp4',
maxFiles: 20,
maxFileSize: 10485760, // 10MB each
maxTotalSize: 104857600, // 100MB total
dragDrop: true,
required: true
}
Advanced Input Fields
19. Tags Field
Type: 'tags'
Purpose: Input multiple tags/keywords with autocomplete
When to Use: Keywords, skills, interests, hashtags, categories
Parameters:
- label: string | "Skills"
- placeholder: string | "Add a skill..."
- maxTags: number | 20
- allowCustomTags: boolean | true (allow user to create new tags)
- tagSuggestions: string[] | ['JavaScript', 'Python', 'Java']
- dataSource: DataSource | for dynamic suggestions
- required: boolean | false
- defaultValue: string[] | []
Example:
{
id: 'skills',
type: 'tags',
label: 'Technical Skills',
placeholder: 'Add a skill and press Enter',
maxTags: 20,
allowCustomTags: true,
tagSuggestions: [
'JavaScript', 'TypeScript', 'Python', 'Java', 'C++',
'React', 'Vue', 'Angular', 'Node.js'
]
}
20. Signature Field
Type: 'signature'
Purpose: Digital signature capture
When to Use: Contract agreements, form signatures, authorization, e-signatures
Parameters:
- label: string | "Signature"
- width: number | 400 (canvas width)
- height: number | 200 (canvas height)
- penColor: string | "#000000" (stroke color)
- penSize: number | 2
- showClearButton: boolean | true
- required: boolean | false
- format: 'image/png' | 'image/jpeg' | 'svg' (output format)
Example:
{
id: 'signature',
type: 'signature',
label: 'Sign Here',
width: 400,
height: 150,
penColor: '#000000',
penSize: 2,
showClearButton: true,
required: true
}
21. Slider Field
Type: 'slider'
Purpose: Range slider for numeric values
When to Use: Volume control, price ranges, rating scales, satisfaction surveys
Parameters:
- label: string | "Price Range"
- min: number | 0
- max: number | 1000
- step: number | 10
- marks: { number: string } | { 0: '$0', 500: '$500', 1000: '$1000' }
- range: boolean | false (single vs range slider)
- defaultValue: number | [min, max] | 500
- showLabels: boolean | true
Example: Single Slider
{
id: 'satisfaction',
type: 'slider',
label: 'How satisfied are you?',
min: 1,
max: 10,
step: 1,
defaultValue: 5,
marks: {
1: '😞',
5: '😐',
10: '😄'
}
}
Example: Range Slider
{
id: 'priceRange',
type: 'slider',
label: 'Price Range',
range: true,
min: 0,
max: 1000,
step: 50,
defaultValue: [100, 900],
marks: {
0: '$0',
500: '$500',
1000: '$1000'
}
}
22. Rating Field
Type: 'rating'
Purpose: Star or icon-based rating selection
When to Use: Product/service ratings, feedback surveys, quality assessment
Parameters:
- label: string | "Rate this product"
- min: number | 0 or 1 (minimum rating)
- max: number | 5 (maximum stars)
- size: 'small' | 'medium' | 'large' (star size)
- allowHalf: boolean | false (allow half-star ratings)
- icon: 'star' | 'heart' | 'thumb' (icon type)
- required: boolean | false
- color: string | "#FFC107" (star color)
Example:
{
id: 'productRating',
type: 'rating',
label: 'Rate this product',
min: 1,
max: 5,
allowHalf: true,
icon: 'star',
size: 'large',
color: '#FFC107',
required: true
}
23. Switch/Toggle Field
Type: 'switch'
Purpose: Boolean toggle switch
When to Use: Enable/disable features, on/off settings, preferences toggling
Parameters:
- label: string | "Enable notifications"
- labelOn: string | "Enabled"
- labelOff: string | "Disabled"
- color: 'primary' | 'secondary' | 'success' | 'error'
- defaultValue: boolean | false
- required: boolean | false (rarely needed)
Example:
{
id: 'enableNotifications',
type: 'switch',
label: 'Enable Email Notifications',
labelOn: 'Enabled',
labelOff: 'Disabled',
defaultValue: false,
color: 'primary'
}
24. Autocomplete Field
Type: 'autocomplete'
Purpose: Typeahead search with suggestions
When to Use: User selection, company lookup, location search, entity selection
Parameters:
- label: string | "Search user"
- placeholder: string | "Type to search..."
- dataSource: DataSource | required for suggestions
- searchQueryName: string | "q" (API query parameter name)
- searchRequestDelay: number | 300 (ms debounce delay)
- minChars: number | 2 (minimum chars before search)
- clearable: boolean | true
- required: boolean | false
- multiple: boolean | false
Example:
{
id: 'assignedUser',
type: 'autocomplete',
label: 'Assign To',
placeholder: 'Search user...',
multiple: false,
dataSource: {
type: 'api',
url: '/api/users/search',
valueProperty: 'id',
labelProperty: 'name',
searchQueryName: 'q',
method: 'GET'
},
searchRequestDelay: 400,
minChars: 2,
required: true
}
25. Hidden Field
Type: 'hidden'
Purpose: Store values without user input (system fields)
When to Use: User ID storage, form version tracking, internal state
Parameters:
- label: string (not shown)
- defaultValue: any | required
- value: any | can be set via calculated property
Example:
{
id: 'userId',
type: 'hidden',
defaultValue: 'user123',
value: currentUser.id // Dynamic value
}
Example: For Form Version
{
id: 'formVersion',
type: 'hidden',
defaultValue: '2.0'
}
Layout Containers (13 Types)
Basic Containers
1. Panel
Type: 'panel'
Purpose: Grouped container with optional title and styling
When to Use: Section organization, form grouping, visual separation
Parameters:
- label: string | "Personal Information"
- collapsible: boolean | false (can collapse)
- collapsed: boolean | false (initially collapsed)
- variant: 'default' | 'primary' | 'success' | 'warning' | 'error'
- theme: PanelTheme | 'default'
- borderColor: string | css color
- backgroundColor: string | css color
- padding: string | "20px"
- components: FormField[] | children fields
Example:
{
id: 'personalPanel',
type: 'panel',
label: 'Personal Information',
collapsible: true,
variant: 'primary',
padding: '20px',
components: [
{ id: 'firstName', type: 'text', label: 'First Name' },
{ id: 'lastName', type: 'text', label: 'Last Name' },
{ id: 'email', type: 'email', label: 'Email' }
]
}
2. Columns
Type: 'columns'
Purpose: Multi-column layout with responsive grid
When to Use: Side-by-side fields, responsive layouts, complex forms
Parameters:
- columns: ColumnConfig[] | required (array of column configurations)
- gap: string | "20px" (spacing between columns)
- responsive: boolean | true (stack on mobile)
- components: FormField[] (populated in each ColumnConfig)
Example: 2-Column Layout
{
id: 'nameRow',
type: 'columns',
gap: '20px',
responsive: true,
columns: [
{
width: 6, // Bootstrap 12-unit grid
sm: 12, // Full width on small screens
components: [
{ id: 'firstName', type: 'text', label: 'First Name', required: true }
]
},
{
width: 6,
sm: 12,
components: [
{ id: 'lastName', type: 'text', label: 'Last Name', required: true }
]
}
]
}
Example: 3-Column Layout
{
id: 'contactRow',
type: 'columns',
gap: '15px',
columns: [
{
width: 4,
md: 6,
sm: 12,
components: [{ id: 'email', type: 'email', label: 'Email' }]
},
{
width: 4,
md: 6,
sm: 12,
components: [{ id: 'phone', type: 'phone', label: 'Phone' }]
},
{
width: 4,
md: 12,
components: [{ id: 'website', type: 'url', label: 'Website' }]
}
]
}
3. Grid
Type: 'grid'
Purpose: CSS Grid layout for complex arrangements
When to Use: Dashboard grids, complex form layouts, asymmetric designs
Parameters:
- templateColumns: string | "1fr 2fr 1fr" (CSS grid template)
- templateRows: string | "auto auto" (CSS grid rows)
- gap: string | "20px"
- responsive: boolean | true
- components: FormField[] (all children)
Example:
{
id: 'mainGrid',
type: 'grid',
templateColumns: '1fr 2fr',
gap: '20px',
responsive: true,
components: [
// Left sidebar
{ id: 'sidebar', type: 'panel', label: 'Filters' },
// Right content
{ id: 'content', type: 'panel', label: 'Form Content' }
]
}
Structured Containers
4. Tabs
Type: 'tabs'
Purpose: Tabbed interface for organizing content
When to Use: Multi-section forms, preferences pages, related information grouping
Parameters:
- tabs: TabConfig[] | required (array of tab definitions)
- activeTab: string | first tab
- vertical: boolean | false (vertical vs horizontal tabs)
Example:
{
id: 'infoTabs',
type: 'tabs',
tabs: [
{
label: 'Personal',
id: 'personal',
components: [
{ id: 'firstName', type: 'text', label: 'First Name' },
{ id: 'lastName', type: 'text', label: 'Last Name' }
]
},
{
label: 'Contact',
id: 'contact',
components: [
{ id: 'email', type: 'email', label: 'Email' },
{ id: 'phone', type: 'phone', label: 'Phone' }
]
},
{
label: 'Address',
id: 'address',
components: [
{ id: 'street', type: 'text', label: 'Street' },
{ id: 'city', type: 'text', label: 'City' }
]
}
]
}
5. Wizard (Multi-Step Form)
Type: 'wizard'
Purpose: Step-by-step form progression
When to Use: Complex forms, guided onboarding, registration flows, checkout
Parameters:
- steps: WizardStep[] | required
- linear: boolean | true (must complete steps in order)
- showStepHeaders: boolean | true
- stepLabels: string[] | ["Step", "of"] (localization)
Example:
{
id: 'registrationWizard',
type: 'wizard',
linear: true,
showStepHeaders: true,
steps: [
{
label: 'Account Details',
id: 'step1',
components: [
{ id: 'email', type: 'email', label: 'Email', required: true },
{ id: 'password', type: 'password', label: 'Password', required: true }
]
},
{
label: 'Personal Information',
id: 'step2',
components: [
{ id: 'firstName', type: 'text', label: 'First Name', required: true },
{ id: 'lastName', type: 'text', label: 'Last Name', required: true }
]
},
{
label: 'Preferences',
id: 'step3',
components: [
{
id: 'newsletter',
type: 'checkbox',
label: 'Subscribe to newsletter'
},
{
id: 'notifications',
type: 'switch',
label: 'Enable notifications'
}
]
},
{
label: 'Review',
id: 'review',
components: [
// Summary or review fields
]
}
]
}
6. Accordion
Type: 'accordion'
Purpose: Expandable sections for grouped content
When to Use: FAQ sections, collapsible form sections, expandable details
Parameters:
- items: AccordionItem[] | required
- multiple: boolean | false (multiple open at once)
- allowToggle: boolean | true
Example:
{
id: 'settingsAccordion',
type: 'accordion',
multiple: false,
items: [
{
title: 'Basic Settings',
id: 'basic',
components: [
{ id: 'siteName', type: 'text', label: 'Site Name' }
]
},
{
title: 'Email Settings',
id: 'email',
components: [
{ id: 'smtpServer', type: 'text', label: 'SMTP Server' }
]
},
{
title: 'Advanced Settings',
id: 'advanced',
components: [
{ id: 'apiKey', type: 'text', label: 'API Key' }
]
}
]
}
7. Fieldset
Type: 'fieldset'
Purpose: Grouped fields with border and legend
When to Use: Related field groups, form sections with borders
Parameters:
- label: string | "Group Title"
- legend: string | "Fieldset Legend"
- components: FormField[]
Example:
{
id: 'addressFieldset',
type: 'fieldset',
label: 'Address Information',
components: [
{ id: 'street', type: 'text', label: 'Street Address' },
{ id: 'city', type: 'text', label: 'City' },
{ id: 'state', type: 'text', label: 'State' },
{ id: 'zip', type: 'text', label: 'ZIP Code' }
]
}
8. Stepper
Type: 'stepper'
Purpose: Step indicator for workflow progression
When to Use: Order tracking, form progress, task completion
Parameters:
- steps: string[] | ["Start", "Process", "Complete"]
- activeStep: number | 0 (current step index)
- orientation: 'horizontal' | 'vertical'
- linear: boolean | false
Example:
{
id: 'orderStepper',
type: 'stepper',
steps: ['Order', 'Payment', 'Shipping', 'Delivered'],
activeStep: 0,
orientation: 'horizontal'
}
Advanced Containers
9. Repeater
Type: 'repeater'
Purpose: Dynamic field repetition (add/remove items)
When to Use: Multiple items, line items, dynamic arrays
Parameters:
- label: string | "Items"
- components: FormField[] | template fields to repeat
- minItems: number | 1
- maxItems: number | unlimited
- addButtonLabel: string | "Add Item"
- removeButtonLabel: string | "Remove"
- addButtonVariant: string | "outlined"
Example: Line Items Repeater
{
id: 'lineItems',
type: 'repeater',
label: 'Order Items',
minItems: 1,
maxItems: 100,
addButtonLabel: 'Add Item',
components: [
{
id: 'productId',
type: 'select',
label: 'Product',
dataSource: { type: 'api', url: '/api/products' },
required: true
},
{
id: 'quantity',
type: 'number',
label: 'Quantity',
min: 1,
required: true
},
{
id: 'unitPrice',
type: 'currency',
label: 'Unit Price',
disabled: true // Read-only
},
{
id: 'lineTotal',
type: 'currency',
label: 'Line Total',
disabled: true,
calculated: {
formula: 'quantity * unitPrice',
dependsOn: ['quantity', 'unitPrice'],
trigger: 'change'
}
}
]
}
10. DataGrid (Table)
Type: 'table' or 'datagrid'
Purpose: Structured data display with inline editing
When to Use: Data entry tables, result displays, tabular data
Parameters:
- label: string | "Data Table"
- columns: ColumnDef[] | required
- dataSource: DataSource | static or dynamic
- editable: boolean | false (allow inline editing)
- sortable: boolean | true
- filterable: boolean | true
- pageable: boolean | true
- pageSize: number | 10
Example:
{
id: 'inventoryTable',
type: 'datagrid',
label: 'Inventory',
editable: true,
sortable: true,
columns: [
{ key: 'productId', label: 'Product', type: 'text', width: '30%' },
{ key: 'quantity', label: 'Qty', type: 'number', width: '20%' },
{ key: 'price', label: 'Price', type: 'currency', width: '20%' },
{ key: 'status', label: 'Status', type: 'select', width: '30%' }
],
dataSource: {
type: 'api',
url: '/api/inventory'
}
}
11. Card
Type: 'card'
Purpose: Styled container with shadow and borders
When to Use: Highlight content, create visual sections
Parameters:
- label: string | "Card Title"
- elevation: number | 1 (shadow depth 0-24)
- variant: 'outlined' | 'filled' | 'elevation'
- components: FormField[]
Example:
{
id: 'summaryCard',
type: 'card',
label: 'Order Summary',
elevation: 2,
variant: 'elevated',
components: [
{ id: 'subtotal', type: 'currency', label: 'Subtotal', disabled: true },
{ id: 'tax', type: 'currency', label: 'Tax', disabled: true },
{ id: 'total', type: 'currency', label: 'Total', disabled: true }
]
}
Structural Elements
12. Section
Type: 'section'
Purpose: Simple semantic section wrapper
When to Use: Form organization, semantic HTML, content grouping
#### **13. Divider**
```yaml
Type: 'divider'
Purpose: Visual separator between content
When to Use: Visual organization, content separation
Parameters:
- variant: 'fullWidth' | 'inset' | 'middle'
- orientation: 'horizontal' | 'vertical'
#### **14. Spacer**
```yaml
Type: 'spacer'
Purpose: Add spacing between elements
When to Use: Vertical/horizontal spacing, layout control
Parameters:
- height: string | "20px" (for horizontal spacer)
- width: string | for vertical spacer
---
## Conditional Logic
Dynamically show/hide or enable/disable fields based on conditions.
```typescript
interface ConditionalLogic {
rules: ConditionalRule[];
conjunction?: 'AND' | 'OR';
}
interface ConditionalRule {
when: string; // Field ID to watch
operator: string; // equals, notEquals, greaterThan, etc.
value: any; // Value to compare
action: string; // show, hide, enable, disable, require, setValue
setToValue?: any; // For setValue action
}
Example: Conditional Field (Show address if country is US)
{
id: 'address',
type: 'text',
label: 'Address',
conditional: {
rules: [
{
when: 'country',
operator: 'equals',
value: 'US',
action: 'show'
}
]
}
}
Example: Multiple Conditions with OR
{
id: 'otherDetails',
type: 'textarea',
label: 'Other Details',
conditional: {
rules: [
{
when: 'category',
operator: 'equals',
value: 'other',
action: 'show'
},
{
when: 'needsDetails',
operator: 'equals',
value: true,
action: 'show'
}
],
conjunction: 'OR'
}
}
Validation
Client-side and server-side validation with custom rules.
interface ValidationRule {
type: 'required' | 'min' | 'max' | 'email' | 'pattern' | 'custom' | 'async';
value?: any;
message?: string;
customValidation?: string; // JavaScript function
asyncValidationUrl?: string; // API endpoint
compareWith?: string; // For cross-field validation
}
Common Validation Examples
// Email validation
{
id: 'email',
type: 'email',
validation: [
{ type: 'required', message: 'Email is required' },
{ type: 'email', message: 'Invalid email format' }
]
}
// Password confirmation
{
id: 'passwordConfirm',
type: 'password',
validation: [
{
type: 'compare',
compareWith: 'password',
compareOperator: 'equals',
message: 'Passwords do not match'
}
]
}
// Custom pattern
{
id: 'username',
type: 'text',
validation: [
{
type: 'pattern',
value: '^[a-zA-Z0-9_]{3,15}$',
message: 'Username must be 3-15 alphanumeric characters or underscore'
}
]
}
// Async validation (check if username is available)
{
id: 'username',
type: 'text',
validation: [
{
type: 'async',
asyncValidationUrl: '/api/users/check-username',
asyncMethod: 'POST',
debounceMs: 500,
message: 'Username is already taken'
}
]
}
Calculated Fields (Formulas)
Automatically compute field values based on other fields.
interface CalculatedValue {
formula: string; // JavaScript expression
dependsOn: string[]; // Field IDs it depends on
trigger?: 'change' | 'blur' | 'load';
}
Formula Examples
// Total = Quantity * Unit Price
{
id: 'lineTotal',
type: 'currency',
label: 'Total',
disabled: true,
calculated: {
formula: 'quantity * unitPrice',
dependsOn: ['quantity', 'unitPrice'],
trigger: 'change'
}
}
// Age = Current Year - Birth Year
{
id: 'age',
type: 'number',
label: 'Age',
disabled: true,
calculated: {
formula: `new Date().getFullYear() - new Date(birthDate).getFullYear()`,
dependsOn: ['birthDate'],
trigger: 'change'
}
}
// Full Name = First Name + Last Name
{
id: 'fullName',
type: 'text',
label: 'Full Name',
disabled: true,
calculated: {
formula: `(firstName || '') + ' ' + (lastName || '')`,
dependsOn: ['firstName', 'lastName'],
trigger: 'change'
}
}
// Discount = Price > 100 ? 10% : 0
{
id: 'discount',
type: 'currency',
label: 'Discount',
disabled: true,
calculated: {
formula: 'price > 100 ? price * 0.1 : 0',
dependsOn: ['price'],
trigger: 'change'
}
}
Workflow Integration
Trigger workflows after form submission.
interface WorkflowConfig {
workflowId: string;
workflowName: string;
triggerOn: 'submit' | 'save' | 'custom';
enabled: boolean;
parameters?: Record<string, any>;
}
Example: Post-Submission Workflow
{
id: 'myForm',
pageMode: 'form',
name: 'User Registration',
components: [...],
settings: {
submitAction: 'submit',
successMessage: 'Registration successful!',
triggerWorkflow: {
workflowId: 'SEND_WELCOME_EMAIL',
workflowName: 'Send Welcome Email',
triggerOn: 'submit',
enabled: true,
parameters: {
emailTemplate: 'welcome',
includeOnboarding: true
}
}
}
}
Form Settings
Configure form-level behavior.
interface FormSettings {
submitAction?: 'save' | 'submit' | 'draft';
confirmMessage?: string;
redirectUrl?: string;
successMessage?: string;
errorMessage?: string;
triggerWorkflow?: WorkflowConfig;
autoSave?: boolean;
autoSaveInterval?: number; // milliseconds
showProgress?: boolean;
requirePasswordConfirmation?: boolean;
}
Common Form Patterns
Contact Form
{
id: 'contactForm',
pageMode: 'form',
name: 'Contact Us',
components: [
{
id: 'contactPanel',
type: 'panel',
label: 'Contact Information',
components: [
{ id: 'name', type: 'text', label: 'Full Name', required: true },
{ id: 'email', type: 'email', label: 'Email', required: true },
{ id: 'phone', type: 'phone', label: 'Phone (optional)' },
{ id: 'subject', type: 'text', label: 'Subject', required: true },
{ id: 'message', type: 'textarea', label: 'Message', rows: 6, required: true }
]
},
{
id: 'submitRow',
type: 'columns',
columns: [
{
width: 6,
components: [
{ id: 'submit', type: 'button', label: 'Send Message', buttonConfig: { action: 'submit' } }
]
},
{
width: 6,
components: [
{ id: 'reset', type: 'button', label: 'Clear', buttonConfig: { action: 'reset' } }
]
}
]
}
]
}
Registration Form with Multi-Step
See Wizard example above.
Product Order Form
{
id: 'orderForm',
pageMode: 'form',
name: 'Product Order',
components: [
// Customer info
{ id: 'firstName', type: 'text', label: 'First Name' },
{ id: 'lastName', type: 'text', label: 'Last Name' },
{ id: 'email', type: 'email', label: 'Email' },
// Items repeater
{
id: 'lineItems',
type: 'repeater',
label: 'Order Items',
minItems: 1,
components: [
{ id: 'productId', type: 'select', label: 'Product' },
{ id: 'quantity', type: 'number', label: 'Quantity' },
{ id: 'unitPrice', type: 'currency', label: 'Price' },
{ id: 'lineTotal', type: 'currency', disabled: true, calculated: {} }
]
},
// Summary
{
id: 'summary',
type: 'card',
label: 'Order Summary',
components: [
{ id: 'subtotal', type: 'currency', disabled: true, calculated: {} },
{ id: 'tax', type: 'currency', disabled: true, calculated: {} },
{ id: 'total', type: 'currency', disabled: true, calculated: {} }
]
}
]
}
Best Practices
- Field Naming: Use descriptive IDs (e.g.,
firstNamenotfield1) - Validation: Add validation at the field level with clear error messages
- Conditional Logic: Use AND for strict requirements, OR for alternatives
- Performance: For large repeaters, limit maxItems
- User Experience: Group related fields in panels/sections
- Accessibility: Always provide labels and descriptions
- Mobile: Test forms on mobile and use responsive columns
- Validation Messages: Customize error messages for better UX
- Calculated Fields: Document formulas in help text
- Workflow Integration: Test workflows with actual data
Next: See PAGE_DESIGNER_DASHBOARDS.md for Dashboard page types.