React Native Support
Treege 3.0+ includes full React Native support with a dedicated renderer implementation optimized for mobile platforms.
Installation
First, install Treege and its peer dependencies:
npm install treege react-nativeOptional Dependencies
For file input support, install the optional document picker:
npm install react-native-document-pickerNote: If react-native-document-picker is not installed, the file input will gracefully degrade and show a message to the user.
Basic Usage
Import the React Native renderer:
import { TreegeRenderer } from "treege/renderer-native";
import type { Flow, FormValues } from "treege";
function App() {
const flow: Flow = {
id: "flow-1",
nodes: [
{
id: "name",
type: "input",
data: {
type: "text",
name: "fullName",
label: "Full Name",
required: true
}
},
{
id: "email",
type: "input",
data: {
type: "text",
name: "email",
label: "Email",
required: true,
pattern: "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"
}
}
],
edges: []
};
const handleSubmit = (values: FormValues) => {
console.log("Form submitted:", values);
};
return (
<TreegeRenderer
flows={flow}
onSubmit={handleSubmit}
/>
);
}Styling
Container Styling
Customize the ScrollView and content container styles:
<TreegeRenderer
flows={flow}
onSubmit={handleSubmit}
contentContainerStyle={{
flex: 1,
justifyContent: "center",
paddingHorizontal: 16,
}}
/>Custom Components
Override default components with your own React Native implementations:
import { Text, TextInput, View } from "react-native";
import { TreegeRenderer } from "treege/renderer-native";
const CustomTextInput = ({ value, setValue, label, error }) => {
return (
<View style={{ marginBottom: 16 }}>
<Text style={{ fontSize: 14, marginBottom: 4, fontWeight: "500" }}>
{label}
</Text>
<TextInput
value={value}
onChangeText={setValue}
style={{
borderWidth: 1,
borderColor: error ? "#ef4444" : "#d1d5db",
padding: 12,
borderRadius: 8,
fontSize: 16,
backgroundColor: "#fff"
}}
/>
{error && (
<Text style={{ color: "#ef4444", fontSize: 12, marginTop: 4 }}>
{error}
</Text>
)}
</View>
);
};
<TreegeRenderer
flows={flow}
components={{
inputs: {
text: CustomTextInput
}
}}
/>Supported Input Types
Fully Implemented (Vanilla React Native)
These inputs work out of the box with no additional dependencies:
- Text inputs:
text,number,textarea,password - Boolean inputs:
checkbox,switch,hidden
With Optional Dependencies
These inputs require additional packages but degrade gracefully if not installed:
file- Requiresreact-native-document-picker
Requires Custom Implementation
These inputs require you to provide custom implementations using popular React Native libraries:
-
Selection:
select,radio,autocomplete- Recommended: @react-native-picker/picker
-
Date/Time:
date,daterange,time,timerange- Recommended: react-native-date-picker
-
Location:
address- Recommended: @react-native-community/google-places-autocomplete
-
HTTP:
http- Implement using your preferred HTTP client
Example: Custom Date Picker
Here's how to implement a custom date input using react-native-date-picker:
import DatePicker from "react-native-date-picker";
import { useState } from "react";
import { View, Text, Pressable } from "react-native";
const CustomDateInput = ({ value, setValue, label, error }) => {
const [open, setOpen] = useState(false);
const date = value ? new Date(value) : new Date();
return (
<View style={{ marginBottom: 16 }}>
<Text style={{ fontSize: 14, marginBottom: 4, fontWeight: "500" }}>
{label}
</Text>
<Pressable
onPress={() => setOpen(true)}
style={{
borderWidth: 1,
borderColor: error ? "#ef4444" : "#d1d5db",
padding: 12,
borderRadius: 8,
backgroundColor: "#fff"
}}
>
<Text>{value || "Select a date"}</Text>
</Pressable>
<DatePicker
modal
open={open}
date={date}
onConfirm={(date) => {
setOpen(false);
setValue(date.toISOString());
}}
onCancel={() => setOpen(false)}
/>
{error && (
<Text style={{ color: "#ef4444", fontSize: 12, marginTop: 4 }}>
{error}
</Text>
)}
</View>
);
};
<TreegeRenderer
flows={flow}
components={{
inputs: {
date: CustomDateInput
}
}}
/>API Reference
The React Native renderer shares the same API as the web renderer, with some platform-specific additions:
Props
| Prop | Type | Default | Description |
|-------------------------|---------------------------------------------|--------------|------------------------------------------------------------|
| flows | Flow \| Flow[] \| null | - | Decision tree to render (single Flow or array of Flows) |
| onSubmit | (values: FormValues, meta?: Meta) => void | - | Form submission handler (meta includes HTTP response data) |
| onChange | (values: FormValues) => void | - | Form change handler |
| validate | (values, nodes) => Record<string, string> | - | Custom validation function |
| initialValues | FormValues | {} | Initial form values |
| components | TreegeRendererComponents | - | Custom component overrides |
| language | string | "en" | UI language |
| validationMode | "onSubmit" \| "onChange" | "onSubmit" | When to validate |
| googleApiKey | string | - | API key for address input |
| style | ViewStyle | - | ScrollView style (RN only) |
| contentContainerStyle | ViewStyle | - | Content container style (RN only) |
Platform-Specific Props
style: Applied to the outerScrollViewcontainercontentContainerStyle: Applied to thecontentContainerStyleof theScrollView
Best Practices
1. Provide Custom Components for Complex Inputs
For the best user experience, implement custom components for select, date, and other complex inputs using well-maintained React Native libraries.
2. Handle Keyboard Properly
Use KeyboardAvoidingView or react-native-keyboard-aware-scroll-view to ensure inputs aren't hidden by the keyboard:
import { KeyboardAvoidingView, Platform } from "react-native";
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{ flex: 1 }}
>
<TreegeRenderer flows={flow} onSubmit={handleSubmit} />
</KeyboardAvoidingView>3. Test on Both iOS and Android
Some inputs behave differently on iOS and Android. Always test on both platforms.
4. Consider Screen Sizes
Mobile screens are smaller than desktop. Design your forms with mobile-first principles:
- Keep labels concise
- Use appropriate input types (e.g.,
numberfor numeric keyboards) - Test on different screen sizes
Differences from Web Renderer
The React Native renderer has some differences from the web version:
- Styling: Uses React Native's
StyleSheetinstead of CSS/Tailwind - Input Components: Uses React Native primitives (
TextInput,Switch, etc.) - Optional Dependencies: More dependencies are optional to keep bundle size small
- Custom Components: More inputs require custom implementations
Example Project
For a complete example, check out the React Native example in the Treege repository.
Troubleshooting
File Input Not Working
Make sure you've installed react-native-document-picker:
npm install react-native-document-picker
cd ios && pod installType Errors with Custom Components
Ensure you're importing types from the main package:
import type { TreegeRendererComponents } from "treege";Styling Issues
Remember that React Native doesn't support all CSS properties. Use React Native's StyleSheet API and refer to the React Native documentation for supported styles.