@question-forms/react-native
v0.4.10
Published
React Native renderer for Question Forms SDK
Downloads
1,380
Maintainers
Readme
@question-forms/react-native
React Native renderer for the Question Forms SDK — render schema-driven forms natively on iOS and Android, build forms visually, and customize everything.
Installation
npm install @question-forms/core @question-forms/react-nativePeer Dependencies
npm install react react-native react-native-vector-icons \
react-native-image-picker react-native-signature-canvas \
@react-native-community/datetimepickeriOS
cd ios && pod installAndroid
Follow the react-native-vector-icons setup guide to configure fonts.
Quick Start
import { useState } from 'react';
import { QuestionForm } from '@question-forms/react-native';
import type { FormSchema, FormValues } from '@question-forms/core';
const schema: FormSchema = {
id: 'my-form',
sections: [
{
id: 'section-1',
questions: [
{
id: 'q1',
key: 'name',
type: 'TEXT',
subtype: 'short',
label: 'Your Name',
required: true,
},
],
},
],
};
const MyForm = () => {
const [values, setValues] = useState<FormValues>({});
return (
<QuestionForm
schema={schema}
value={values}
onChange={setValues}
onSubmit={(v) => console.log('Submitted:', v)}
/>
);
};Features
- 10 question types — text, date, time, select, rating, image, handwriting, radio grid, checkbox grid
- Visual form builder — mobile-optimized form designer
- 11 locales — en, es, pt, fr, de, ar, ja, ko, zh, it, uk
- Custom renderers — override any question type with your own component
- Theming — customize colors, spacing, typography, and border radius using numeric values
- Three form modes —
edit,readonly,preview - Action bar — built-in submit/reset buttons (can be hidden)
- Native controls — platform date/time pickers, native alerts, image picker
- Conditional logic — visibility and enabled state driven by
@question-forms/core - Validation — required, min/max, pattern, custom — with per-question error display
Components
QuestionForm
The main form renderer.
import { QuestionForm } from '@question-forms/react-native';
<QuestionForm
schema={schema}
value={values}
onChange={setValues}
onSubmit={handleSubmit}
onReset={handleReset}
mode="edit"
locale="en"
theme={{ primaryColor: '#6366f1' }}
showActionBar={true}
rendererOverrides={{ TEXT: MyCustomTextRenderer }}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| schema | FormSchema | required | Form definition object |
| value | FormValues | required | Current form values |
| onChange | (values: FormValues) => void | required | Called when any value changes |
| onSubmit | (values: FormValues) => void | — | Called on valid submit |
| onReset | () => void | — | Called on reset |
| mode | 'edit' \| 'readonly' \| 'preview' | 'edit' | Form interaction mode |
| locale | Locale | 'en' | UI translation locale |
| theme | Partial<IFormTheme> | — | Theme token overrides |
| showActionBar | boolean | true | Show submit/reset buttons |
| rendererOverrides | Partial<Record<QuestionType, Component>> | — | Custom renderers per type |
| licenseKey | string | — | Required for production use |
FormBuilder
Mobile-optimized visual form designer.
import { useState, useCallback } from 'react';
import { FormBuilder } from '@question-forms/react-native';
import type { FormSchema } from '@question-forms/core';
const MyBuilder = () => {
const [schema, setSchema] = useState<FormSchema | null>(null);
const handleChange = useCallback((s: FormSchema) => {
setSchema(s);
}, []);
return (
<FormBuilder
initialSchema={schema ?? undefined}
onChange={handleChange}
locale="en"
licenseKey="your-license-key"
/>
);
};| Prop | Type | Default | Description |
|------|------|---------|-------------|
| initialSchema | FormSchema | — | Pre-populate the builder |
| onChange | (schema: FormSchema) => void | — | Called on every schema change |
| allowedTypes | string[] | all types | Restrict available question types |
| colors | IBuilderColors | DEFAULT_COLORS | Builder canvas colors |
| locale | Locale | 'en' | Builder UI locale |
| licenseKey | string | — | Required for production use |
Custom Renderers
Override any question type with your own component:
import { View, TextInput, Text } from 'react-native';
import type { IQuestionRendererProps } from '@question-forms/react-native';
const MyTextRenderer = ({ question, value, onChange, disabled, errors, theme }: IQuestionRendererProps) => (
<View>
<Text style={{ color: theme.labelColor }}>{question.label}</Text>
<TextInput
value={(value as string) ?? ''}
onChangeText={onChange}
editable={!disabled}
style={{
borderWidth: 1,
borderColor: errors.length > 0 ? theme.errorColor : theme.borderColor,
borderRadius: theme.borderRadius,
padding: theme.inputPadding,
}}
/>
{errors.map((err, i) => (
<Text key={i} style={{ color: theme.errorColor }}>{err}</Text>
))}
</View>
);
<QuestionForm
schema={schema}
value={values}
onChange={setValues}
rendererOverrides={{ TEXT: MyTextRenderer }}
/>IQuestionRendererProps
| Prop | Type | Description |
|------|------|-------------|
| question | QuestionSchema | The question definition |
| value | unknown | Current value for this question |
| onChange | (value: unknown) => void | Update the value |
| disabled | boolean | Whether the input is disabled |
| mode | 'edit' \| 'readonly' \| 'preview' | Current form mode |
| errors | string[] | Validation error messages |
| theme | IFormTheme | Resolved theme object |
Theme Customization
Theme values use numbers (not strings) for spacing and sizing — consistent with React Native's style system.
<QuestionForm
schema={schema}
value={values}
onChange={setValues}
theme={{
fontFamily: 'System',
fontSize: 14,
primaryColor: '#6366f1',
errorColor: '#ef4444',
borderColor: '#e5e7eb',
borderRadius: 8,
inputPadding: 14,
sectionGap: 32,
questionGap: 20,
labelColor: '#111827',
disabledOpacity: 0.5,
}}
/>Default Theme
{
fontFamily: 'System',
fontSize: 14,
primaryColor: '#2563eb',
errorColor: '#dc2626',
borderColor: '#d1d5db',
borderRadius: 6,
inputPadding: 12,
sectionGap: 24,
questionGap: 16,
labelColor: '#1f2937',
disabledOpacity: 0.6,
}Key Difference from @question-forms/react
| Aspect | React (Web) | React Native |
|--------|-------------|--------------|
| Theme values | Strings ('14px', '8px 12px') | Numbers (14, 12) |
| Theme delivery | Context-based | Passed as prop to renderers |
| UI framework | Material UI | Native components |
| Icons | @mui/icons-material | react-native-vector-icons |
| Date/time pickers | @mui/x-date-pickers | @react-native-community/datetimepicker |
| Image picker | HTML file input | react-native-image-picker |
| Handwriting | HTML Canvas | react-native-signature-canvas |
Internationalization
11 built-in locales with 70+ translation strings.
import { QuestionForm, LOCALE_LABELS } from '@question-forms/react-native';
<QuestionForm
schema={schema}
value={values}
onChange={setValues}
locale="es"
/>Supported locales: en, es, pt, fr, de, ar, ja, ko, zh, it, uk
Icons
Built-in icon components wrapping react-native-vector-icons:
import { MaterialIcon, MaterialCommunityIcon } from '@question-forms/react-native';
<MaterialIcon name="check" size={24} color="#000" />
<MaterialCommunityIcon name="heart" size={24} color="red" />Builder Utilities
import {
useBuilderState,
DEFAULT_COLORS,
QUESTION_TYPE_LABELS,
QUESTION_TYPE_GROUPS,
createDefaultQuestion,
createDefaultSection,
createDefaultSubSection,
generateId,
} from '@question-forms/react-native';Exports Summary
| Export | Description |
|--------|-------------|
| QuestionForm | Main form renderer component |
| FormBuilder | Visual form designer component |
| defaultTheme | Default theme values (numeric) |
| TranslationProvider | i18n context provider |
| useTranslation | Hook — access translation strings |
| getTranslations | Get translations for a locale |
| fmt | String formatter with {0}, {1} placeholders |
| LOCALE_LABELS | Map of locale codes to display names |
| MaterialIcon | Material Design icon component |
| MaterialCommunityIcon | Material Community icon component |
| useBuilderState | Hook — builder state management |
| DEFAULT_COLORS | Builder canvas colors |
| QUESTION_TYPE_LABELS | Question type display names |
| QUESTION_TYPE_GROUPS | Grouped question type menu config |
| createDefaultQuestion | Factory — new question with defaults |
| createDefaultSection | Factory — new section with defaults |
| createDefaultSubSection | Factory — new subsection with defaults |
| generateId | Generate unique IDs |
| getTypeOptionKey | Get composite type key |
| getLocalizedGroups | Localized question type groups |
| getLocalizedTypeLabels | Localized question type labels |
License
MIT — Question Forms SDK
