A comprehensive React SDK for building dynamic questionnaires with conditional fields, file uploads, and form validation.
npm install @onflow/react-sdkThe SDK requires React 17+ and optionally Google Maps API for geo-location fields:
npm install @react-google-maps/apiimport React from "react";
import { OnFlowProvider, Questionnaire } from "@onflow/react-sdk";
import "@onflow/react-sdk/dist/questionnaire.css";
function App() {
const config = {
baseUrl: "https://api.yourtenant.com",
tenantId: "your-tenant-id",
apiKey: "your-api-key",
apiSecret: "your-api-secret",
};
return (
<OnFlowProvider config={config}>
<Questionnaire
moduleVersionId="your-module-version-id"
onSuccess={(data) => {
console.log("Submission successful:", data);
// data.residentId and data.submissionId
}}
onError={(error) => {
console.error("Submission failed:", error);
}}
/>
</OnFlowProvider>
);
}The provider component that wraps your application and provides API configuration.
config: SdkConfig- SDK configuration objectchildren: React.ReactNode- Child components
type SdkConfig = {
baseUrl: string; // API base URL (e.g., https://api.example.com)
tenantId: string; // Your tenant ID
apiKey: string; // Your API key
apiSecret: string; // Your API secret
accessToken?: string; // Optional bearer token for OIDC
};The main component that renders the questionnaire form.
moduleVersionId: string- The questionnaire/module version IDonSuccess?: (data: { residentId: string; submissionId: string }) => void- Success callbackonError?: (error: Error) => void- Error callbackclassName?: string- Additional CSS classesdisabled?: boolean- Disable the entire form
<Questionnaire
moduleVersionId="123e4567-e89b-12d3-a456-426614174000"
onSuccess={(data) => {
// Handle successful submission
console.log("Resident ID:", data.residentId);
console.log("Submission ID:", data.submissionId);
}}
onError={(error) => {
// Handle submission error
console.error("Error:", error.message);
}}
className="my-custom-class"
disabled={false}
/>The SDK supports the following field types:
Single-line text input with validation.
Multi-line textarea for longer content.
Numeric input with min/max validation.
Checkbox for boolean values.
Select dropdown with predefined options.
Multiple checkboxes for selecting multiple options.
Date picker input.
File upload with progress tracking and validation.
Latitude/longitude inputs (map component not included).
Import the default stylesheet for basic styling:
import "@onflow/react-sdk/dist/questionnaire.css";The SDK uses CSS classes that you can override:
/* Main container */
.onflow-questionnaire {
}
/* Resident information section */
.onflow-resident-section {
}
/* Field groups */
.onflow-field-group {
}
/* Individual fields */
.onflow-field {
}
/* Field labels */
.onflow-field-label {
}
/* Input elements */
.onflow-field-input {
}
/* Error messages */
.onflow-field-error {
}
/* Submit button */
.onflow-submit-button {
}
/* Multiple row containers */
.onflow-multiple-row {
}The default styles are responsive and work on mobile devices. Key breakpoints:
- 768px and below: Single column layout
- 480px and below: Full-width submit button
File uploads are handled automatically with a 3-step process:
- Request signed upload URL from API
- Upload file directly to S3
- Update file status to "uploaded"
Files are validated against field constraints:
- File size: Maximum size in MB
- File types: Allowed MIME types or extensions
- Multiple files: Support for single or multiple file uploads
{
type: "file",
label: "Upload Document",
config: {
fileTypes: ["pdf", "doc", "docx"],
maxSize: 10, // 10MB
multiple: false,
isSensitive: true
}
}Fields and groups can be conditionally shown based on other field values.
equals- Field value equals specified valuenot_equals- Field value does not equal specified valuegt- Field value is greater than specified valuegte- Field value is greater than or equal to specified valuelt- Field value is less than specified valuelte- Field value is less than or equal to specified valueis_true- Field value is trueis_false- Field value is falsecontains- Field value contains specified valuenot_contains- Field value does not contain specified value
{
id: "follow_up_question",
label: "Follow-up Question",
type: "text",
condition: {
and: [{
fieldId: "main_question",
operator: "equals",
value: "yes"
}]
}
}The SDK provides comprehensive error handling:
- Required field validation
- Type-specific validation (email, number ranges)
- File upload validation
- Custom validation rules
- Network errors
- Authentication errors
- Server errors
- File upload errors
Errors are displayed inline with fields and at the form level:
<Questionnaire
onError={(error) => {
// Log error for debugging
console.error("Form error:", error);
// Show user-friendly message
showNotification("Submission failed. Please try again.");
}}
/>The SDK is fully typed with TypeScript definitions included.
import type {
SdkConfig,
QuestionnaireFormState,
ValidationErrors,
FileUploadProgress,
} from "@onflow/react-sdk";
// Form state structure
type QuestionnaireFormState = {
[groupId: string]: {
[rowIndex: number]: {
[fieldId: string]: unknown;
};
};
};
// Validation errors
type ValidationErrors = {
[groupId: string]: {
[rowIndex: number]: {
[fieldId: string]: string;
};
};
};You can extend the SDK by creating custom field components:
import { FieldComponentProps } from "@onflow/react-sdk";
function CustomField({ field, value, onChange, error }: FieldComponentProps) {
return (
<div className="onflow-field">
<label className="onflow-field-label">
{field.label}
{field.isRequired && <span className="onflow-field-required">*</span>}
</label>
{/* Your custom input */}
{error && <div className="onflow-field-error">{error}</div>}
</div>
);
}Access form state using the useQuestionnaireForm hook:
import { useQuestionnaireForm } from "@onflow/react-sdk";
function CustomForm({ questionnaire }) {
const form = useQuestionnaireForm(questionnaire);
// Access form state
const values = form.values;
const errors = form.errors;
const hasErrors = form.hasErrors;
// Form actions
form.setValue(groupId, rowIndex, fieldId, value);
form.validateAll();
form.reset();
}- File uploads failing: Check API credentials and file size limits
- Conditional fields not showing: Verify condition syntax and field IDs
- Styling issues: Ensure CSS is imported and not overridden
- TypeScript errors: Update to latest SDK version
Enable debug logging by setting the environment variable:
REACT_APP_ONFLOW_DEBUG=trueThe SDK has been completely rewritten with a new API:
Before:
import { QuestionnaireFields, ResidentFields } from "@onflow/react-sdk";After:
import { Questionnaire } from "@onflow/react-sdk";The new Questionnaire component handles both resident fields and questionnaire fields automatically.
For support and questions:
- Check the documentation
- Open an issue on GitHub
- Contact support at support@onflow.com
MIT License - see LICENSE file for details.