Skip to content

The Rendering Engine

System that controls how each component type is rendered — the "bridge" between React/Vue components and presentation logic.

Renderer

Renderer System decides which wrapper to use for each component type:

🔧 What Renderers Are:

Renderer TypeFunctionUsed ForExample
fieldRenders form fieldsInputText, Select, etc.Adds automatic validation
containerRenders form containersFormGroup, SectionOrganizes layout
menu-itemRenders menu itemsMenuLink, MenuButtonAdds navigation
menu-containerRenders menu containersMenuContainerOrganizes hierarchy
contentRenders static contentText, ImageSimple display

📊 How They Work:

Component → Renderer → DOM

text
InputText Component → FieldRenderer → <input> + validation + props

Renderer Adds:

  • Automatic middleware pipeline
  • Context injection (form, menu)
  • Type-specific props transformation
  • Integrated error boundaries

💡 Result: Components focus on UI, Renderers focus on presentation logic!

🚀 Renderer Types

Each renderer type has specific responsibilities:

📝 Field Renderer - Form Fields:

ResponsibilityImplementationBenefit
Form IntegrationAutomatic useFormContext()Form props injected
Validation PipelinewithCpfValidation, withRulesAutomatic validation
Dynamic PropsuseReactions()Props change based on state
Debug IntegrationuseDebug()Automatic visual debug

🏗️ Container Renderer - Layout and Organization:

ResponsibilityImplementationBenefit
Child Orderingx-ui.order sortingAutomatic layout
Props FilteringRemove container propsClean props
Layout LogicResponsive layoutAdaptive UI
Section ManagementGroup related itemsVisual organization

🧭 Menu Renderers - Navigation:

RendererFunctionFeatures
menu-itemIndividual menu itemsLink handling, active states
menu-containerMenu organizationHierarchy, ordering, responsive

📄 Content Renderer - Display:

FunctionUsageCharacteristics
Static ContentText, images, etc.No form integration
Minimal ProcessingDirect renderingOptimized performance

⚙️ How the System Works

Conceptual flow of how renderers process components:

🔄 Resolution Pipeline:

Schema JSON

Detect Type (Which renderer to use?)

Fetch Renderer (In priority hierarchy)

Prepare Props (Merge + context)

Apply Middleware (Transform + validate)

Render (Component + wrapper)

Final React/Vue Element

🎯 Resolution Hierarchy:

How the system chooses which renderer to use:

PrioritySourceWhen to UseExample
1st - LocalFactory propsSpecific customization<FormFactory renderers=\{\{field: CustomField\}\} />
2nd - GlobalscheptaProviderApplication default<scheptaProvider renderers=\{\{field: AppField\}\} />
3rd - RegistryregisterRenderer()Global extensionsregisterRenderer('field', LibField)
4th - DefaultBuilt-in systemDefault behaviorInternal FieldRenderer

⚡ Central Orchestrator:

The "maestro" that coordinates the entire process:

Responsibilities:

  • Detects which component type to render
  • Chooses the appropriate renderer from the hierarchy
  • Prepares props by merging contexts
  • Applies type-specific middleware pipeline
  • Renders the final component with its wrapper

🤝 Why Renderers Exist

The problems that the renderer system solves:

🎯 Separation of Concerns:

Without renderers, each component needs to:

  • Mix UI logic with business logic
  • Manually and inconsistently manage context
  • Implement type-specific validation in each field
  • Transform props in an ad-hoc and non-standardized way

With renderers, components become:

  • Cleaner: exclusive focus on visual presentation
  • More consistent: automatic and standardized context injection
  • More reusable: validation and logic encapsulated in the renderer
  • More predictable: props transformation follows established patterns

🔄 System Flexibility:

The same component can have different behaviors:

  • Form Field: FieldRenderer adds validation + form integration
  • Read-only Display: ContentRenderer maintains simple display, without form logic
  • Menu Item: ItemRenderer adds navigation + active state
  • Custom App: CustomRenderer implements application-specific behavior

This enables: multi-tenant apps, A/B testing, integration with different UI libraries, and custom extensions without modifying base components.

Renderers are the "engine" that connects other concepts: