rn-dynamic-ui-render
v1.0.8
Published
A dynamic UI rendering engine for React Native
Downloads
15
Maintainers
Readme
📦 rn-dynamic-ui-render
A powerful JSON-driven dynamic UI renderer for React Native. Define your UI using JSON schemas and let the renderer handle component rendering, theming, dynamic data binding, conditionals, formatting, and event handling.
✨ Features
- 🛠 Schema-driven rendering → Build UIs from JSON instead of hardcoding.
- 🎨 Theme integration → Use centralized design tokens (colors, fonts, weights).
- ⚡ Dynamic props & expressions → Bind values from data or handlers.
- 🖼 Conditional logic → Show/hide or style components dynamically.
- 📅 Date & number formatting → Format inline with props.
- 🌍 Translation-ready → Works with
react-i18next. - 📋 List rendering → FlatList support with
itemandindex. - 🛡 Error boundaries → Prevent schema issues from crashing your app.
📦 Installation
npm install rn-dynamic-ui-render
# or
yarn add rn-dynamic-ui-render🚀 Usage
1. Register Components & Theme
import RNDynamicUIRender from "rn-dynamic-ui-render";
import { Text, View, Button, Image } from "react-native";
const components = {
View,
Text,
Button,
Image,
};
const theme = {
colors: {
primary: "#007bff",
secondary: "#6c757d",
white: "#ffffff",
},
font: {
h1: 32,
h2: 24,
h3: 18,
},
fontWeight: {
normal: "400",
bold: "700",
},
};2. Define JSON Schema
[
{
"name": "View",
"props": { "style": { "padding": 16 } },
"content": [
{
"name": "Text",
"props": {
"textContent": "Hello Dynamic UI",
"style": { "fontSize": "h2", "color": "primary" }
}
},
{
"name": "Button",
"props": {
"title": "Click Me",
"onPress": "handlePress"
}
}
]
}
]3. Render
const handlers = {
handlePress: () => alert("Button Pressed!"),
};
<RNDynamicUIRender
data={schema}
handlers={handlers}
theme={theme}
components={components}
/>;🔑 Core Component
RNDynamicUIRender
| Prop | Type | Description |
| ------------ | --------- | ----------------------------------------------------------------- |
| data | array | JSON schema for rendering UI. |
| handlers | object | Functions + data context used for expressions and event handlers. |
| theme | object | Theme object with colors, font sizes, font weights. |
| components | object | Registry of component names → actual React components. |
| translate | boolean | If true, integrates with react-i18next. |
📋 Props Reference
| Prop | Type | Description | Supports Expressions | Example |
| --------------------- | -------------------- | ------------------------------------------------------------------------------- | ------------------------ | ------------------------------------------------ |
| expression | boolean | Marks that this prop’s value should be resolved dynamically. | ✅ Yes (true) | "textContent": "item.text", "expression": true |
| textContent | string / object | Sets the text of a Text component. Can bind dynamic values. | ✅ Yes | "textContent": "item.text" |
| source.uri | string / object | Image URI. Supports ternary expression. | ✅ Yes | "uri": { "expression": "ternary", ... } |
| style | object | Style object. Keys can be static or ternary expressions. Resolves theme values. | ✅ Yes | "color": "primary" |
| color props | string | Props ending with color resolve from theme.colors. | ✅ Yes | "backgroundColor": "primary" |
| fontSize | string (theme key) | Maps to theme.font. | ✅ Yes | "fontSize": "h3" |
| fontWeight | string (theme key) | Maps to theme.fontWeight. | ✅ Yes | "fontWeight": "bold" |
| visible | boolean / object | Controls visibility without removing from render tree. Supports ternary. | ✅ Yes | "visible": { "expression": "ternary", ... } |
| visibleExpression | boolean | If true, visible is evaluated as a path/expression. | ✅ Yes | "visibleExpression": true |
| type | string | Special types: "dateTime". | ✅ Yes | "type": "dateTime", "format": "DD-MM-YYYY" |
| format | string | Format string for dateTime type (uses moment). | ❌ No | "format": "DD-MM-YYYY hh:mm a" |
| fixedLength | number | Converts numeric/string values to fixed decimal places. | ❌ No | "fixedLength": 2 |
| onPress (etc.) | string | Event handler name resolved from handlers. | ❌ No | "onPress": "handleSubmit" |
| passData | boolean | If true, passes (item, index) into event handler. | ❌ No | "passData": true |
| passName | boolean | If true, passes the prop name as an extra argument to handler. | ❌ No | "passName": true |
| data (lists) | array / string | Used in FlatList. Can be bound via expression: true. | ✅ Yes | "data": "messages" |
| listHeaderComponent | array | Schema for FlatList header. | ❌ No | JSON schema array |
| listFooterComponent | array | Schema for FlatList footer. | ❌ No | JSON schema array |
| listEmptyComponent | array | Schema for empty state in FlatList. | ❌ No | JSON schema array |
⚡ Expressions & Conditionals
1. Expression Mode
{
"name": "Text",
"props": { "textContent": "item.text", "expression": true }
}2. Ternary Expressions
{
"name": "Image",
"props": {
"expression": true,
"source": {
"uri": {
"expression": "ternary",
"condition": "{{item.type === 'CUSTOMER'}}",
"trueValue": "item.customerImage",
"falseValue": "https://cdn-icons-png.flaticon.com/128/3135/3135715.png"
}
}
}
}3. Conditional Styles
{
"name": "Text",
"props": {
"style": {
"backgroundColor": {
"expression": "ternary",
"condition": "{{item.type === 'CUSTOMER'}}",
"trueValue": "primary",
"falseValue": "secondary"
}
},
"textContent": "item.text",
"expression": true
}
}4. Date Formatting
{
"name": "Text",
"props": {
"textContent": "item.timestamp",
"expression": true,
"type": "dateTime",
"format": "DD-MM-YYYY hh:mm a"
}
}5. Fixed Length
{
"name": "Text",
"props": { "textContent": "item.price", "expression": true, "fixedLength": 2 }
}🖇 Event Handling
Attach event handlers by string key:
{
"name": "Button",
"props": { "title": "Submit", "onPress": "submitForm" }
}const handlers = {
submitForm: () => console.log("Form submitted"),
};Options:
passData: true→ Pass(item, index)automatically.passName: true→ Pass prop name to the handler.
🎨 Styling & Theme
Props ending in
styleresolve as style objects.Theme tokens supported:
"color": "primary"→theme.colors.primary"fontSize": "h3"→theme.font.h3"fontWeight": "bold"→theme.fontWeight.bold
📋 FlatList Support
{
"name": "FlatList",
"props": { "data": "messages" },
"content": [
{
"name": "Text",
"props": {
"textContent": "item.text",
"expression": true,
"style": { "backgroundColor": "primary", "color": "white" }
}
}
]
}👉 item and index are auto-injected.
👉 Supports listHeaderComponent, listFooterComponent, listEmptyComponent.
⚠️ Best Practices
- Always pass
theme+components. - Use
expression: truefor data binding. - Use ternary expressions for conditional logic.
- Prefer theme tokens over hardcoded colors/fonts.
- Wrap logic inside
{{ ... }}for expressions.
🛠 Example: Chat UI
{
"content": [
{
"name": "FlatList",
"props": {
"data": "messages",
"style": { "padding": 16, "marginTop": 40 }
},
"content": [
{
"name": "Image",
"props": {
"expression": true,
"source": {
"uri": {
"expression": "ternary",
"condition": "{{item.type === 'CUSTOMER'}}",
"trueValue": "item.customerImage",
"falseValue": "https://cdn-icons-png.flaticon.com/128/3135/3135715.png"
}
},
"style": {
"height": 40,
"width": 40,
"alignSelf": {
"expression": "ternary",
"condition": "{{item.type === 'CUSTOMER'}}",
"trueValue": "flex-start",
"falseValue": "flex-end"
}
}
}
},
{
"name": "Text",
"props": {
"expression": true,
"textContent": "item.text",
"style": {
"alignSelf": {
"expression": "ternary",
"condition": "{{item.type === 'CUSTOMER'}}",
"trueValue": "flex-start",
"falseValue": "flex-end"
},
"backgroundColor": {
"expression": "ternary",
"condition": "{{item.type === 'CUSTOMER'}}",
"trueValue": "primary",
"falseValue": "secondary"
},
"color": "white",
"padding": 8,
"borderRadius": 8,
"maxWidth": "80%",
"marginTop": 8
}
}
},
{
"name": "Text",
"props": {
"textContent": "item.timestamp",
"expression": true,
"type": "dateTime",
"format": "DD-MM-YYYY hh:mm a"
}
},
{
"name": "Text",
"props": {
"textContent": "item.label",
"expression": true,
"fixedLength": 2,
"style": {
"fontSize": "h3",
"fontWeight": "bold",
"marginTop": 16
}
}
}
]
}
]
}