├── .eslintignore ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── codeql-analysis.yml │ └── continuous-integration.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── __tests__ ├── __snapshots__ │ └── index.test.tsx.snap └── index.test.tsx ├── images └── cover.png ├── index.ts ├── jest.config.json ├── package-lock.json ├── package.json ├── src ├── ComponentMap.tsx ├── propsMap.ts └── types.ts ├── tsconfig.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | babel.config.js 2 | node_modules/* 3 | README.md 4 | jest.config.json 5 | dist/ -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | commonjs: false, 5 | es6: true, 6 | node: true, 7 | jest: true 8 | }, 9 | extends: [ 10 | "plugin:react/recommended", 11 | "eslint:recommended", 12 | "plugin:@typescript-eslint/recommended" 13 | ], 14 | parser: '@typescript-eslint/parser', 15 | parserOptions: { 16 | ecmaVersion: 2018, 17 | sourceType: 'module' 18 | }, 19 | plugins: [ 20 | 'react', 21 | '@typescript-eslint' 22 | ], 23 | rules: { 24 | "arrow-body-style": 2, 25 | "semi": ["error", "always"], 26 | "quotes": ["error", "double"], 27 | "prefer-const": 1, 28 | "@typescript-eslint/ban-ts-ignore": 0 29 | } 30 | }; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## What you did: 2 | 3 | ## What happened: 4 | 5 | 6 | 7 | ## Problem description: 8 | 9 | 10 | 11 | ## Suggested solution: 12 | 13 | 17 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | **What**: 11 | 12 | 13 | 14 | **Why**: 15 | 16 | 17 | 18 | **How**: 19 | 20 | 21 | 22 | **Checklist**: 23 | 24 | 25 | 26 | 27 | 28 | - [ ] Tests 29 | - [ ] Ready to be merged 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [master] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [master] 14 | schedule: 15 | - cron: '0 17 * * 1' 16 | 17 | jobs: 18 | analyze: 19 | name: Analyze 20 | runs-on: ubuntu-latest 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | # Override automatic language detection by changing the below list 26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 27 | language: ['javascript'] 28 | # Learn more... 29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 30 | 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@v2 34 | 35 | # Initializes the CodeQL tools for scanning. 36 | - name: Initialize CodeQL 37 | uses: github/codeql-action/init@v1 38 | with: 39 | languages: ${{ matrix.language }} 40 | # If you wish to specify custom queries, you can do so here or in a config file. 41 | # By default, queries listed here will override any specified in a config file. 42 | # Prefix the list here with "+" to use these queries and those in the config file. 43 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 44 | 45 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 46 | # If this step fails, then you should remove it and run the build manually (see below) 47 | - name: Autobuild 48 | uses: github/codeql-action/autobuild@v1 49 | 50 | # ℹ️ Command-line programs to run using the OS shell. 51 | # 📚 https://git.io/JvXDl 52 | 53 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 54 | # and modify them (or add more) to build your code if your project 55 | # uses a compiled language 56 | 57 | #- run: | 58 | # make bootstrap 59 | # make release 60 | 61 | - name: Perform CodeQL Analysis 62 | uses: github/codeql-action/analyze@v1 63 | -------------------------------------------------------------------------------- /.github/workflows/continuous-integration.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [12.x] 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v2 21 | 22 | - name: Set up Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v1 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | 27 | - name: Cache dependencies 28 | uses: actions/cache@v2 29 | with: 30 | path: | 31 | **/node_modules 32 | key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} 33 | 34 | - name: Install dependencies 35 | run: npm install 36 | 37 | - name: Run the lints 38 | run: npm run lint 39 | 40 | - name: Run Prettier 41 | run: npm run prettier-check 42 | 43 | - name: Run the tests 44 | run: npm run test 45 | 46 | - name: Upload coverage to Codecov 47 | uses: codecov/codecov-action@v1 48 | 49 | - name: Build 50 | run: npm run build 51 | 52 | - name: Archive production 53 | uses: actions/upload-artifact@v2 54 | with: 55 | name: dist 56 | path: | 57 | dist 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Bower dependency directory (https://bower.io/) 28 | bower_components 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (https://nodejs.org/api/addons.html) 34 | builds/ 35 | 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | dist/ 41 | coverage/ 42 | 43 | # TypeScript v1 declaration files 44 | typings/ 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # dotenv environment variables file 62 | .env 63 | 64 | # next.js build output 65 | .next 66 | 67 | # mac store 68 | .DS_Store 69 | 70 | # CI/CD 71 | 72 | 73 | # VS Code 74 | .vscode 75 | 76 | # IDEA 77 | build/ 78 | .idea 79 | *.iml 80 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | jest.config.json 2 | __tests__/ -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | babel.config.js 2 | node_modules/* 3 | README.md 4 | jest.config.json 5 | dist/ 6 | .* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "trailingComma": "all", 4 | "semi": true 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Mohsen Madani 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-dynamic-render · ![CI/CD](https://github.com/moh3n9595/react-native-dynamic-render/workflows/Continuous%20Integration/badge.svg) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/moh3n9595/react-native-dynamic-render/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-orange.svg)](https://github.com/moh3n9595/react-native-dynamic-render/compare) [![codecov](https://codecov.io/gh/moh3n9595/react-native-dynamic-render/branch/master/graph/badge.svg)](https://codecov.io/gh/moh3n9595/react-native-dynamic-render) 2 | 3 | 4 | 5 |

6 | 7 |
8 |

9 | Render from Json object 10 |

11 |

12 | 13 | ## Examples 14 | 15 | - Online simple example: https://snack.expo.io/@moh3n95/react-native-dynamic-render 16 | 17 | - Online advanced example: https://snack.expo.io/@moh3n95/react-navigation-dynamic-render 18 | 19 | ## Installation 20 | ``` 21 | yarn add react-native-dynamic-render 22 | ``` 23 | or 24 | ``` 25 | npm i react-native-dynamic-render 26 | ``` 27 | 28 | ## Usage 29 | 30 | ```jsx 31 | import DynamicComponent from "react-native-dynamic-render"; 32 | import { Text, View } from "react-native"; 33 | 34 | export default function App() { 35 | 36 | const mapComponents = { 37 | text: Text, /* Or Your custom component */ 38 | view: View 39 | }; 40 | 41 | const props = { 42 | name: "view", 43 | _uid: "123", 44 | children: [ 45 | { 46 | name: "text", 47 | _uid: "1234" 48 | }, 49 | { 50 | name: "text", 51 | _uid: "12345", 52 | props: null 53 | }, 54 | { 55 | name: "view", 56 | _uid: "123456", 57 | children: [ 58 | { 59 | name: "text", 60 | _uid: "1234567", 61 | children: "some foo bar", 62 | props: { 63 | first: "text foo", 64 | second: "text bar" 65 | } 66 | }, 67 | { 68 | name: "text", 69 | _uid: "12345678" 70 | }, 71 | 72 | ], 73 | props: { 74 | first: "view foo", 75 | second: "view bar" 76 | } 77 | } 78 | ] 79 | }; 80 | 81 | return ( 82 | 86 | ); 87 | } 88 | ``` 89 | 90 | ### Expected output 91 | 92 | ```tsx 93 | 94 | 95 | 96 | 100 | 104 | some foo bar 105 | 106 | 107 | 108 | 109 | ``` 110 | 111 | 112 | ## Contributing 113 | 114 | Thank you for your interest in contributing! Please feel free to put up a PR for any issue or feature request. 115 | 116 | ## Give me a Star 117 | 118 | If you think this project is helpful just give me a ⭐️ Star is enough because i don't drink coffee 😃 119 | 120 | ## License 121 | 122 | This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/moh3n9595/react-native-dynamic-render/blob/master/LICENSE) file for details 123 | 124 | ## Author 125 | 126 | Made with ❤️ by [Mohsen Madani](https://github.com/moh3n9595). 127 | 128 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/index.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`1-depth map props renders correctly 1`] = ` 4 | 5 | some tests 6 | 7 | `; 8 | 9 | exports[`1-depth not found component renders correctly 1`] = ` 10 | 11 | The component foo has not been created yet. 12 | 13 | `; 14 | 15 | exports[`1-depth renders correctly 1`] = ``; 16 | 17 | exports[`1-depth without _uid renders correctly 1`] = ``; 18 | 19 | exports[`n-depth map props renders correctly 1`] = ` 20 | 21 | 22 | some tests 23 | 24 | 25 | `; 26 | 27 | exports[`n-depth not found component renders correctly 1`] = ` 28 | 29 | 30 | 31 | 32 | 33 | The component foo has not been created yet. 34 | 35 | 36 | 37 | 38 | `; 39 | 40 | exports[`n-depth renders correctly 1`] = ` 41 | 42 | 43 | 44 | 48 | 52 | some foo bar 53 | 54 | 55 | 56 | 57 | `; 58 | -------------------------------------------------------------------------------- /__tests__/index.test.tsx: -------------------------------------------------------------------------------- 1 | import React, { PropsWithChildren } from "react"; 2 | import DynamicComponent from "../index"; 3 | import renderer from "react-test-renderer"; 4 | import { Text, View } from "react-native"; 5 | 6 | const ComponentViewer = (props: PropsWithChildren<{ component: React.ComponentType }>): React.ReactElement => { 7 | const CustomComponent = props.component; 8 | return ( 9 | 10 | {props.children} 11 | 12 | ); 13 | }; 14 | 15 | const mapComponents = { 16 | componentViewer: ComponentViewer, 17 | text: Text, 18 | view: View, 19 | }; 20 | 21 | test("1-depth map props renders correctly", () => { 22 | 23 | const props = { 24 | name: "componentViewer", 25 | props: { 26 | component: "text", 27 | }, 28 | mappableProps: ["component"], 29 | children: "some tests" 30 | }; 31 | 32 | const tree = renderer.create( 33 | <> 34 | 38 | 39 | ).toJSON(); 40 | 41 | expect(tree).toMatchSnapshot(); 42 | }); 43 | 44 | test("n-depth map props renders correctly", () => { 45 | 46 | const props = { 47 | name: "componentViewer", 48 | props: { 49 | component: "view", 50 | }, 51 | mappableProps: ["component"], 52 | children: [ 53 | { 54 | name: "componentViewer", 55 | props: { 56 | component: "text" 57 | }, 58 | mappableProps: ["component"], 59 | children: "some tests" 60 | } 61 | ] 62 | }; 63 | 64 | const tree = renderer.create( 65 | <> 66 | 70 | 71 | ).toJSON(); 72 | 73 | expect(tree).toMatchSnapshot(); 74 | }); 75 | 76 | test("1-depth renders correctly", () => { 77 | 78 | const props = { 79 | name: "view", 80 | _uid: "123" 81 | }; 82 | 83 | const tree = renderer.create( 84 | 88 | ).toJSON(); 89 | 90 | expect(tree).toMatchSnapshot(); 91 | }); 92 | 93 | test("n-depth renders correctly", () => { 94 | 95 | const props = { 96 | name: "view", 97 | _uid: "123", 98 | children: [ 99 | { 100 | name: "text", 101 | _uid: "1234" 102 | }, 103 | { 104 | name: "text", 105 | _uid: "12345", 106 | props: null 107 | }, 108 | { 109 | name: "view", 110 | _uid: "123456", 111 | children: [ 112 | { 113 | name: "text", 114 | _uid: "1234567", 115 | children: "some foo bar", 116 | props: { 117 | first: "text foo", 118 | second: "text bar" 119 | } 120 | }, 121 | { 122 | name: "text", 123 | _uid: "12345678" 124 | }, 125 | 126 | ], 127 | props: { 128 | first: "view foo", 129 | second: "view bar" 130 | } 131 | } 132 | ] 133 | }; 134 | 135 | const tree = renderer.create( 136 | 140 | ).toJSON(); 141 | 142 | expect(tree).toMatchSnapshot(); 143 | }); 144 | 145 | test("1-depth not found component renders correctly", () => { 146 | 147 | const props = { 148 | name: "foo", 149 | _uid: "123" 150 | }; 151 | 152 | const tree = renderer.create( 153 | 157 | ).toJSON(); 158 | 159 | expect(tree).toMatchSnapshot(); 160 | }); 161 | 162 | test("n-depth not found component renders correctly", () => { 163 | 164 | const props = { 165 | name: "view", 166 | _uid: "123", 167 | children: [ 168 | { 169 | name: "text", 170 | _uid: "1234" 171 | }, 172 | { 173 | name: "text", 174 | _uid: "12345" 175 | }, 176 | { 177 | name: "view", 178 | _uid: "123456", 179 | children: [ 180 | { 181 | name: "foo", 182 | _uid: "1234567" 183 | }, 184 | { 185 | name: "text", 186 | _uid: "12345678" 187 | }, 188 | 189 | ] 190 | } 191 | ] 192 | }; 193 | 194 | const tree = renderer.create( 195 | 199 | ).toJSON(); 200 | 201 | expect(tree).toMatchSnapshot(); 202 | }); 203 | 204 | test("1-depth without _uid renders correctly", () => { 205 | 206 | const props = { 207 | name: "view" 208 | }; 209 | 210 | const tree = renderer.create( 211 | 215 | ).toJSON(); 216 | expect(tree).toMatchSnapshot(); 217 | }); 218 | -------------------------------------------------------------------------------- /images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moh3n9595/react-native-dynamic-render/49f1bcd30943ee26051d53d65696c9b531983716/images/cover.png -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import ComponentMap from "./src/ComponentMap"; 2 | import { ComponentDataInterface, MapComponentsInterface } from "./src/types"; 3 | 4 | export default function DynamicComponent( 5 | componentData: ComponentDataInterface & { 6 | mapComponents: MapComponentsInterface; 7 | }, 8 | ): React.ReactElement { 9 | return ComponentMap(componentData); 10 | } 11 | -------------------------------------------------------------------------------- /jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(js|ts|tsx)$": "/node_modules/react-native/jest/preprocessor.js" 4 | }, 5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": [ 7 | "ts", 8 | "js", 9 | "tsx" 10 | ], 11 | "collectCoverage": true, 12 | "preset": "react-native" 13 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-dynamic-render", 3 | "version": "1.1.3", 4 | "description": "Render from Json object", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "test": "jest --config=jest.config.json", 9 | "build": "tsc", 10 | "lint": "./node_modules/.bin/eslint *.ts", 11 | "prettier-write": "./node_modules/.bin/prettier --write \"*.ts\"", 12 | "prettier-check": "./node_modules/.bin/prettier --check \"*.ts\"", 13 | "codecov": "./node_modules/.bin/codecov -t 2aa603f2-8a1d-4358-b86c-5411412a8242" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/moh3n9595/react-native-dynamic-render.git" 18 | }, 19 | "homepage": "https://github.com/moh3n9595/react-native-dynamic-render#readme", 20 | "keywords": [ 21 | "js", 22 | "react-native", 23 | "render", 24 | "json", 25 | "dynamic" 26 | ], 27 | "author": { 28 | "name": "Mohsen Madani", 29 | "email": "mohsenando@gmail.com" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "react-uuid": "^1.0.2" 34 | }, 35 | "devDependencies": { 36 | "@types/jest": "^25.1.0", 37 | "@types/node": "^9.4.6", 38 | "@types/react": "^16.9.25", 39 | "@types/react-native": "^0.61.23", 40 | "@typescript-eslint/eslint-plugin": "^2.13.0", 41 | "@typescript-eslint/parser": "^2.18.0", 42 | "codecov": "^3.6.5", 43 | "eslint": "^6.7.2", 44 | "eslint-plugin-import": "^2.19.1", 45 | "eslint-plugin-react": "^7.17.0", 46 | "jest": "^25.1.0", 47 | "prettier": "1.19.1", 48 | "react": "^16.13.1", 49 | "react-native": "^0.61.5", 50 | "react-test-renderer": "^16.13.1", 51 | "ts-jest": "^22.4.1", 52 | "typescript": "^3.7.5" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/ComponentMap.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Text } from "react-native"; 3 | import { ComponentDataInterface, MapComponentsInterface } from "./types"; 4 | import propsMap from "./propsMap"; 5 | 6 | // @ts-ignore 7 | import uuid from "react-uuid"; 8 | 9 | export default function ComponentMap(componentData: ComponentDataInterface & { mapComponents: MapComponentsInterface }): React.ReactElement { 10 | if (typeof componentData.mapComponents[componentData.name] !== "undefined") { 11 | const CustomComponent: React.ComponentType = componentData.mapComponents[componentData.name]; 12 | 13 | const mappedProps = propsMap(componentData.props, componentData.mappableProps, componentData.mapComponents); 14 | 15 | return ( 16 | 20 | {typeof componentData.children === "string" && componentData.children} 21 | {(componentData.children && Array.isArray(componentData.children)) && componentData.children.map((child: ComponentDataInterface) => ComponentMap({ ...child, mapComponents: componentData.mapComponents }))} 22 | 23 | ); 24 | 25 | } 26 | 27 | const notFoundTxt = `The component ${componentData.name} has not been created yet.`; 28 | console.warn(notFoundTxt); 29 | return React.createElement( 30 | () => {notFoundTxt}, 31 | { key: componentData._uid } 32 | ); 33 | 34 | } -------------------------------------------------------------------------------- /src/propsMap.ts: -------------------------------------------------------------------------------- 1 | import { ComponentDataInterface, MapComponentsInterface } from "./types"; 2 | 3 | export default function propsMap( 4 | props: ComponentDataInterface["props"], 5 | mappableProps: ComponentDataInterface["mappableProps"], 6 | mapComponents: MapComponentsInterface, 7 | ): ComponentDataInterface["props"] { 8 | if (!mappableProps || mappableProps.length === 0) { 9 | return props; 10 | } 11 | if (mappableProps) { 12 | mappableProps.forEach((mappableProp: string) => { 13 | if (props) { 14 | props[mappableProp] = mapComponents[props[mappableProp]]; 15 | } 16 | }); 17 | } 18 | 19 | return props; 20 | } 21 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface ComponentDataInterface { 2 | props?: Record; 3 | mappableProps?: Array; 4 | _uid?: string; 5 | name: string; 6 | children?: Array | string; 7 | } 8 | 9 | export type MapComponentsInterface = Record; 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "typeRoots": ["node_modules/@types"], 5 | "types": ["react", "react-native", "jest"], 6 | "skipLibCheck": true, 7 | // "incremental": true, /* Enable incremental compilation */ 8 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 9 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 10 | "lib": ["es2017", "es7", "es6", "dom"], /* Specify library files to be included in the compilation. */ 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 16 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 17 | // "outFile": "./", /* Concatenate and emit output to single file. */ 18 | "outDir": "./dist", /* Redirect output structure to the directory. */ 19 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 20 | // "composite": true, /* Enable project compilation */ 21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 22 | // "removeComments": true, /* Do not emit comments to output. */ 23 | // "noEmit": true, /* Do not emit outputs. */ 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 55 | 56 | /* Source Map Options */ 57 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 60 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 61 | 62 | /* Experimental Options */ 63 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 64 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 65 | 66 | /* Advanced Options */ 67 | //"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 68 | }, 69 | "exclude": [ 70 | "node_modules", 71 | "dist", 72 | "__tests__" 73 | ] 74 | } 75 | --------------------------------------------------------------------------------