Advanced Component Configuration

Take your component integration to the next level with field overrides, default children, and automatic variable bindings. These advanced techniques create polished, user-friendly editing experiences.

Field Overrides

Field overrides replace auto-generated form fields with specialized input controls. Instead of basic text inputs, users get rich editors, color pickers, icon selectors, and more.

Available Built-in Field Overrides

classNameFieldOverrides(layer)

Advanced Tailwind CSS class editor with:

  • Auto-complete for Tailwind classes
  • Responsive breakpoint controls (sm:, md:, lg:, xl:)
  • Visual class grouping and validation
  • Theme-aware suggestions
tsx
1fieldOverrides: { 2 className: (layer) => classNameFieldOverrides(layer) 3}

childrenFieldOverrides(layer)

Searchable component selector for child components:

  • Dropdown with available component types
  • Search and filter capabilities
  • Respects component hierarchy
tsx
1fieldOverrides: { 2 children: (layer) => childrenFieldOverrides(layer) 3}

childrenAsTextareaFieldOverrides(layer)

Multi-line text editor for simple text content:

  • Perfect for span, p, and heading elements
  • Multi-line editing support
tsx
1fieldOverrides: { 2 children: (layer) => childrenAsTextareaFieldOverrides(layer) 3}

childrenAsTipTapFieldOverrides(layer)

Rich text editor using TipTap:

  • WYSIWYG markdown editing
  • Formatting toolbar with bold, italic, links
  • Ideal for Markdown components
tsx
1fieldOverrides: { 2 children: (layer) => childrenAsTipTapFieldOverrides(layer) 3}

iconNameFieldOverrides(layer)

Visual icon picker:

  • Grid of available icons
  • Search functionality
  • Live preview
tsx
1fieldOverrides: { 2 iconName: (layer) => iconNameFieldOverrides(layer) 3}

textInputFieldOverrides(layer, allowVariableBinding, propName)

Enhanced text input with optional variable binding support:

  • Variable binding UI when allowVariableBinding is true
  • Automatic binding/unbinding controls
  • Immutable binding badges
tsx
1fieldOverrides: { 2 title: (layer) => textInputFieldOverrides(layer, true, 'title') 3}

commonFieldOverrides()

Convenience function that applies standard overrides for className and children:

tsx
1fieldOverrides: commonFieldOverrides() 2// Equivalent to: 3// { 4// className: (layer) => classNameFieldOverrides(layer), 5// children: (layer) => childrenFieldOverrides(layer) 6// }

Creating Custom Field Overrides

Create specialized input controls for unique data types:

tsx
1import { AutoFormInputComponentProps } from '@/components/ui/ui-builder/types'; 2import { FormItem, FormLabel, FormControl } from '@/components/ui/form'; 3 4const colorPickerFieldOverride = (layer) => ({ 5 fieldType: ({ label, field }: AutoFormInputComponentProps) => ( 6 <FormItem> 7 <FormLabel>{label}</FormLabel> 8 <FormControl> 9 <div className="flex gap-2 items-center"> 10 <input 11 type="color" 12 value={field.value || '#000000'} 13 onChange={(e) => field.onChange(e.target.value)} 14 className="w-12 h-8 rounded border cursor-pointer" 15 /> 16 <input 17 type="text" 18 value={field.value || ''} 19 onChange={(e) => field.onChange(e.target.value)} 20 placeholder="#000000" 21 className="flex-1 px-3 py-2 border rounded-md" 22 /> 23 </div> 24 </FormControl> 25 </FormItem> 26 ) 27}); 28 29// Use in component definition: 30fieldOverrides: { 31 brandColor: colorPickerFieldOverride, 32 className: (layer) => classNameFieldOverrides(layer) 33}

Conditional Field Overrides

Hide or show fields based on other prop values:

tsx
1const conditionalFieldOverride = (layer) => ({ 2 isHidden: (currentValues) => currentValues.mode === 'simple', 3 fieldType: ({ label, field }) => ( 4 <FormItem> 5 <FormLabel>{label}</FormLabel> 6 <FormControl> 7 <AdvancedEditor value={field.value} onChange={field.onChange} /> 8 </FormControl> 9 </FormItem> 10 ) 11});

Default Children

Provide sensible default child components when users add your component to the canvas.

Simple Text Defaults

For basic text components:

tsx
1span: { 2 schema: z.object({ 3 className: z.string().optional(), 4 children: z.string().optional(), 5 }), 6 fieldOverrides: { 7 className: (layer) => classNameFieldOverrides(layer), 8 children: (layer) => childrenAsTextareaFieldOverrides(layer) 9 }, 10 defaultChildren: "Default text content" 11}

Component Layer Defaults

For complex nested structures:

tsx
1Button: { 2 component: Button, 3 schema: z.object({ 4 className: z.string().optional(), 5 children: z.any().optional(), 6 variant: z.enum(['default', 'destructive']).default('default'), 7 }), 8 from: '@/components/ui/button', 9 defaultChildren: [ 10 { 11 id: "button-text", 12 type: "span", 13 name: "Button Text", 14 props: {}, 15 children: "Click me", 16 } 17 ], 18 fieldOverrides: commonFieldOverrides() 19}

Important: All component types referenced in defaultChildren must exist in your registry.

Rich Default Structures

Create sophisticated default layouts:

tsx
1Card: { 2 component: Card, 3 schema: z.object({ 4 className: z.string().optional(), 5 children: z.any().optional(), 6 }), 7 from: '@/components/ui/card', 8 defaultChildren: [ 9 { 10 id: "card-header", 11 type: "div", 12 name: "Header", 13 props: { className: "p-6 pb-0" }, 14 children: [ 15 { 16 id: "card-title", 17 type: "span", 18 name: "Title", 19 props: { className: "text-2xl font-semibold" }, 20 children: "Card Title" 21 } 22 ] 23 }, 24 { 25 id: "card-content", 26 type: "div", 27 name: "Content", 28 props: { className: "p-6" }, 29 children: "Card content goes here." 30 } 31 ], 32 fieldOverrides: commonFieldOverrides() 33}

Default Variable Bindings

Automatically bind component properties to variables when components are added to the canvas. Perfect for system data, branding, and user information.

Basic Variable Bindings

tsx
1UserProfile: { 2 component: UserProfile, 3 schema: z.object({ 4 userId: z.string().default(''), 5 displayName: z.string().default('Anonymous'), 6 email: z.string().optional(), 7 }), 8 from: '@/components/ui/user-profile', 9 defaultVariableBindings: [ 10 { 11 propName: 'userId', 12 variableId: 'current_user_id', 13 immutable: true // System data - cannot be unbound 14 }, 15 { 16 propName: 'displayName', 17 variableId: 'current_user_name', 18 immutable: false // Can be customized 19 } 20 ], 21 fieldOverrides: { 22 userId: (layer) => textInputFieldOverrides(layer, true, 'userId'), 23 displayName: (layer) => textInputFieldOverrides(layer, true, 'displayName'), 24 email: (layer) => textInputFieldOverrides(layer, true, 'email'), 25 } 26}

Immutable Bindings for Critical Data

Use immutable: true to prevent users from unbinding critical data:

tsx
1BrandedButton: { 2 component: BrandedButton, 3 schema: z.object({ 4 text: z.string().default('Click me'), 5 brandColor: z.string().default('#000000'), 6 companyName: z.string().default('Company'), 7 }), 8 from: '@/components/ui/branded-button', 9 defaultVariableBindings: [ 10 { 11 propName: 'brandColor', 12 variableId: 'primary_brand_color', 13 immutable: true // Prevents breaking brand guidelines 14 }, 15 { 16 propName: 'companyName', 17 variableId: 'company_name', 18 immutable: true // Consistent branding 19 } 20 // 'text' is not bound, allowing content customization 21 ], 22 fieldOverrides: { 23 text: (layer) => textInputFieldOverrides(layer, true, 'text'), 24 brandColor: (layer) => textInputFieldOverrides(layer, true, 'brandColor'), 25 companyName: (layer) => textInputFieldOverrides(layer, true, 'companyName'), 26 } 27}

When to Use Immutable Bindings:

  • System data: User IDs, tenant IDs, system versions
  • Brand consistency: Colors, logos, company names
  • Security: Roles, permissions, access levels
  • Template integrity: Critical variables in white-label scenarios

Variable Binding UI

When using textInputFieldOverrides with variable binding enabled, users see:

  • ๐Ÿ”— Bind Variable button for unbound properties
  • Variable name, type, and default value for bound properties
  • ๐Ÿ”’ Immutable badge for protected bindings
  • Unbind button for mutable bindings only

Live Example

See these advanced configuration techniques in action:

Live Demo: Immutable Bindings

Best Practices

Field Overrides

  • Always override className with classNameFieldOverrides() for consistent Tailwind editing
  • Choose appropriate children overrides based on content type:
    • childrenAsTextareaFieldOverrides() for simple text (span, p, headings)
    • childrenFieldOverrides() for nested components (div, containers)
    • childrenAsTipTapFieldOverrides() for rich text (Markdown components)
  • Create domain-specific overrides for complex data types (colors, dates, files)
  • Use conditional overrides to hide advanced options in simple mode

Default Children

  • Provide meaningful defaults that demonstrate proper component usage
  • Keep structures shallow initially to avoid overwhelming new users
  • Use descriptive names for child layers to help with navigation
  • Include all dependencies - ensure referenced component types are in your registry
  • Use unique IDs to prevent conflicts when components are duplicated

Variable Bindings

  • Use immutable bindings for:
    • System data (user IDs, system versions)
    • Brand elements (colors, logos, company names)
    • Security-sensitive data (roles, permissions)
    • Template integrity variables
  • Leave content variables mutable so editors can customize text and messaging
  • Combine with field overrides using textInputFieldOverrides() for the best UX
  • Test binding scenarios to ensure the editing experience is smooth

Performance Tips

  • Use commonFieldOverrides() when you need standard className/children handling
  • Memoize expensive overrides if they perform complex calculations
  • Keep default children reasonable to avoid slow initial renders
  • Cache field override functions to prevent unnecessary re-renders

Integration with Other Features

These advanced configuration techniques work seamlessly with:

  • Variables Panel - Manage variables that power your bindings
  • Props Panel - Enhanced forms with your custom field overrides
  • Code Generation - Exported code respects your component definitions
  • LayerRenderer - Variable values are resolved at render time

What's Next?

With advanced configuration mastered, explore:

  • Variables - Create dynamic, data-driven interfaces
  • Panel Configuration - Customize the editor panels themselves
  • Persistence - Save and load your enhanced component configurations

These advanced techniques transform UI Builder from a simple visual editor into a powerful, domain-specific design tool tailored to your exact needs.