Product EngineeringFeaturesLab FormsFrontendcrelio-app

Form Rendering Engine

Component hierarchy, field type mapping, and architectural patterns for the patient UI form renderer.

👤 Ritu Kataria📅 Updated: Mar 13, 2026🏷️ feature

Form Rendering Engine

The patient UI form renderer turns a backend JSON config into a fully interactive multi-section form. The same engine is reused for both Consent and AOE form types.


10.1 Component Hierarchy

Navigation state machine: The ConsentNavigation class (PatientConsentNavigation.ts) manages multi-process navigation via the useConsentNavigation() hook. It tracks the current process/subprocess, navigation history, process order (including dynamically inserted child processes), and start/end process detection.


10.2 Field Type Mapping

Defined in ControlMapper.tsx — each backend field_type maps to a lazy-loaded React component:

Backend field_typeFrontend ComponentNotes
TextInputAlso handles Email, Number, TextArea via HTML type prop
DateDatePickerUses react-datetime; format from dateformat attribute
DateTimeDatePickerSplit date/time formats; type detected in calculateFormConfig()
TimeDatePickerTime-only picker
ImageImageDisplay-only image
SignatureCustomSignaturereact-signature-canvas; uploads to S3
Upload / Camera / FileUploadFile input + webcam; validates count/size; uploads to S3
ContactNumberPhoneNumberInternational phone number input
CheckBoxCheckBoxGroupMulti-select; totalColumns = 1 default
RadioButtonRadioButtonGroupSingle-select; totalColumns = 1 default
SelectableButtonSelectableButtonGroupButton-style selector
AddressGoogleAddressGoogle Places autocomplete; singleLineAddress = true
SelectSelectDropdown
CalendarDateSelectionCalendarFull calendar widget
ButtonButtonAction button

Type transformation in calculateFormConfig(): Text fields with type: "datetime-local" are promoted to DateTime; type: "date" to Date; type: "time" to Time. Upload-type fields get presigned URL config and S3 path prepared.

Fallback: In prepareFieldConfig(), if field_type is not in the VALID_TYPES array, it falls back to "Text".


10.8 Key Architectural Patterns

PatternDescription
Config-driven renderingEntire form structure determined by JSON config — no hard-coded fields
Generic reducer factoryAll Redux slices use createNamedReducer with action type conventions
Component method bridgetriggerFormAction(name, params) bridges parent-child — parent registers ALLOWED_COMPONENT_METHODS, any child invokes by name
Lazy loadingAll field controls are React.lazy() imported in ControlMapper.tsx
Iteration modelFor repeatable processes, iteration counter tracks fill count; previous values stacked in iterationValues
Navigation state machineConsentNavigation class manages multi-process flows — branching, backtracking, dynamic child process insertion, abort/restart
CSS Modules + BootstrapCSS Modules for scoped styles; Reactstrap for grid layout; var(--crmPrimary) for lab branding

On this page