CentercodeDitto
DittoPorygonAPI

Form Helpers

Utility functions for declarative form field definitions with reduced boilerplate

Overview

Form helpers reduce boilerplate in form definitions by providing common field configurations. They work with FormBlock's declarative sections API for consistent, type-safe form construction.

Key Features

  • 18 pre-built form helpers covering all common input types
  • Consistent configuration patterns across all field types
  • Full TypeScript support with proper type inference
  • Support for conditional visibility with 'when' prop
  • Seamless integration with FormBlock sections API
  • Custom field escape hatch for special cases

Text Input Fields

Text Input Fields

Basic text inputs with variants for email, password, and URL. All include proper inputType and autoComplete attributes.

formHelpers.text('name', 'Name', { placeholder: 'Enter name...' })
formHelpers.email('email', 'Email')
formHelpers.password('password', 'Password')
formHelpers.url('website', 'Website')

Textarea

Multi-line text input with rows, maxLength, and character count options.

0/500
formHelpers.textarea('bio', 'Biography', {
  rows: 4,
  maxLength: 500,
  showCharacterCount: true,
  placeholder: 'Tell us about yourself...',
})

Selection Fields

Single Select

Fields for selecting from predefined options.

const roleOptions = [
  { value: 'participant', label: 'Participant' },
  { value: 'builder', label: 'Builder' },
  { value: 'owner', label: 'Owner' },
];

formHelpers.select('role', 'Role', roleOptions, { placeholder: 'Select a role...' })

Ditto Single Select

Enhanced single-select with optional grouping, search, icons, and clearable. Uses DittoSingleSelect under the hood.

formHelpers.singleSelect('category', 'Category', [
  { value: 'survey', label: 'Survey', icon: faSliders, groupId: 'feedback' },
  { value: 'article', label: 'Article', icon: faCode, groupId: 'content' },
], {
  groups: [
    { id: 'feedback', label: 'Feedback Types', icon: faSliders },
    { id: 'content', label: 'Content Types', icon: faCode },
  ],
  searchable: true,
  clearable: true,
  placeholder: 'Select a category...',
})

Rich Select Options

Select options can include icons and descriptions for richer display

import { faSliders, faTerminal, faWandMagicSparkles } from '@fortawesome/duotone-regular-svg-icons';

const templateOptions = [
  {
    value: 'beta',
    label: 'Beta Program',
    description: 'For beta testing with early adopters',
    icon: faSliders,
  },
  {
    value: 'alpha',
    label: 'Alpha Program',
    description: 'Internal testing before beta release',
    icon: faTerminal,
  },
  {
    value: 'pilot',
    label: 'Pilot Program',
    description: 'Limited rollout with selected customers',
    icon: faWandMagicSparkles,
  },
];

formHelpers.select('template', 'Program Template', templateOptions)

Ditto Multi Select

Enhanced multi-select with optional grouping, search, badges, and maxItems. Uses DittoMultiSelect under the hood.

formHelpers.multiSelect('traits', 'Traits', [
  { value: 'windows', label: 'Windows', icon: faSliders, groupId: 'os' },
  { value: 'macos', label: 'macOS', icon: faSliders, groupId: 'os' },
  { value: 'mobile', label: 'Mobile', icon: faCode, groupId: 'device' },
], {
  groups: [
    { id: 'os', label: 'Operating System', icon: faSliders },
    { id: 'device', label: 'Device Type', icon: faCode },
  ],
  searchable: true,
  clearable: true,
  placeholder: 'Select traits...',
})

Radio Group

Radio button group with horizontal or vertical orientation.

formHelpers.radio('priority', 'Priority', priorityOptions, { orientation: 'horizontal' })

Boolean Fields

Switch, Toggle & Checkbox

Card switch, inline toggle, and checkbox inputs for boolean values.

Email Notifications

Receive updates via email

formHelpers.switch('notifications', 'Email Notifications', faToggleOn, { description: '...' })
formHelpers.toggle('autoplay', 'Autoplay', { description: 'Start playing automatically' })
formHelpers.checkbox('terms', 'I agree to the terms and conditions')

Date Fields

Date & Date Range

Date picker and date range picker with min/max constraints.

formHelpers.date('startDate', 'Start Date', { minDate: new Date() })
formHelpers.dateRange('availability', 'Availability', { startPlaceholder: 'From', endPlaceholder: 'To' })

Specialty Fields

Color Picker

Advanced input types for specific use cases.

#3B82F6
formHelpers.color('brandColor', 'Brand Color', {
  presets: ['#EF4444', '#F59E0B', '#10B981', '#3B82F6', '#8B5CF6'],
})

Tag Input

Free-form tag entry with maxTags limit.

react
typescript
formHelpers.tag('keywords', 'Keywords', { maxTags: 5, placeholder: 'Add keyword...' })

Token Picker

Token Picker

Insert dynamic tokens into text templates. Combines textarea with token picker button.

const tokenGroups = [
  {
    id: 'user',
    name: 'User',
    items: [
      { path: 'user.name', label: 'Name', category: 'user', isPII: true },
      { path: 'user.email', label: 'Email', category: 'user', isPII: true },
    ],
  },
  {
    id: 'program',
    name: 'Program',
    items: [
      { path: 'program.name', label: 'Program Name', category: 'program' },
    ],
  },
];

formHelpers.tokenPicker('template', 'Message Template', tokenGroups, {
  placeholder: 'Type your message with {{tokens}}...',
  description: 'Use tokens to personalize messages',
})

Custom Field

Custom Field

Escape hatch for custom rendering when built-in fields don't fit.

The custom field helper provides full control over rendering while still integrating with FormBlock's validation and state management. Use it when you need special UI or third-party components.

formHelpers.custom('custom', 'Custom Field', ({ field, fieldState }) => (
  <MyCustomInput
    value={field.value}
    onChange={field.onChange}
    error={fieldState.error?.message}
  />
))

Available Helpers

PropTypeDefaultDescription
text(name, label, options?)function-Text input with configurable inputType (text, email, password, url, tel)
number(name, label, options?)function-Numeric input with optional min, max, and step constraints
title(name, label, options?)function-Text input with auto-title-case on blur
email(name, label, options?)function-Email input with email autoComplete and validation hint
password(name, label, options?)function-Password input with masked display and autoComplete
url(name, label, options?)function-URL input with https:// placeholder
textarea(name, label, options?)function-Multi-line text with rows, maxLength, and character count
select(name, label, options, fieldOptions?)function-Basic single-select dropdown with options array
singleSelect(name, label, options, fieldOptions?)function-Enhanced single-select with optional grouping, search, icons, and clearable
multiSelect(name, label, options, fieldOptions?)function-Multi-select with optional grouping, search, badges, and maxItems
switch(name, label, options?)function-Boolean toggle switch with optional description
checkbox(name, label, options?)function-Single checkbox for confirmations and opt-ins
radio(name, label, options, fieldOptions?)function-Radio button group with horizontal/vertical orientation
date(name, label, options?)function-Date picker with minDate/maxDate constraints
dateRange(name, label, options?)function-Date range picker with start/end dates
color(name, label, options?)function-Color picker with preset colors
icon(name, label, options?)function-Icon picker with Font Awesome library
image(name, label, options?)function-Image upload/picker with aspect ratio options
richText(name, label, options?)function-Rich text editor with formatting toolbar
tag(name, label, options?)function-Free-form tag input with maxTags limit
cardPicker(name, label, options, fieldOptions?)function-Visual card selection with icons and categories
audience(name, label, options?)function-Audience access level picker with segmentation
prettyDesigner(name, label, targetType, targetName, options?)function-Visual identity editor for icon, color, images, and templates. Supports inline or launcher variant.
aiContext(name, label, entityType, entityId, options?)function-AI context editor with markdown support, attachments, and version history. Supports inline or launcher variant.
fileUpload(name, label, preset, purpose, accessLevel, options?)function-File upload field with preview, replace, and remove functionality. Supports default, compact, or inline variant.
tokenPicker(name, label, groups, options?)function-Token picker field for inserting dynamic tokens into text templates. Combines textarea with token picker button.
custom(name, label, render, options?)function-Custom render function for special field types

Complete Example

import { FormBlock, FormSection, FormGrid, formHelpers } from '@/ui/blocks';
import { z } from 'zod';

const schema = z.object({
  name: z.string().min(1, 'Required'),
  email: z.string().email(),
  role: z.string().min(1, 'Select a role'),
  bio: z.string().max(500).optional(),
  notifications: z.boolean(),
  startDate: z.date(),
});

// Declarative section definitions with formHelpers
const sections = [
  {
    id: 'basic',
    title: 'Basic Information',
    columns: 2,
    fields: [
      formHelpers.text('name', 'Name', { placeholder: 'Enter name...' }),
      formHelpers.email('email', 'Email'),
      formHelpers.select('role', 'Role', roleOptions),
      formHelpers.date('startDate', 'Start Date'),
    ],
  },
  {
    id: 'profile',
    title: 'Profile',
    fields: [
      formHelpers.textarea('bio', 'Biography', { rows: 4, maxLength: 500 }),
      formHelpers.switch('notifications', 'Email Notifications'),
    ],
  },
];

<FormBlock schema={schema} sections={sections} onSubmit={handleSubmit} />

When to Use

Use formHelpers when:

  • Building forms with FormBlock's declarative sections API
  • Generating forms dynamically from configuration
  • Wanting consistent field configuration across forms
  • Reducing boilerplate in form definitions

Use JSX field components when:

  • Need complex conditional rendering logic
  • Building wizard forms with step-specific layouts
  • Requiring custom wrappers or layout compositions