├── .babelrc
├── .editorconfig
├── .gitignore
├── .npmignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── _config.yml
├── example
├── package.json
├── public
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.js
│ ├── components
│ │ ├── ForLoop.js
│ │ ├── Helper
│ │ │ └── MySomeComponent.js
│ │ ├── IfElse.js
│ │ └── SwitchCase.js
│ ├── index.css
│ └── index.js
└── yarn.lock
├── package.json
├── rollup.config.js
├── src
├── __test__
│ └── .gitkeep
├── index.js
└── lib
│ ├── Elements
│ ├── DOMElements.js
│ ├── Fragment.js
│ └── index.js
│ ├── helperFns
│ ├── doForLoopOperation.js
│ ├── doIfElseOperation.js
│ ├── doSwitchCaseOperation.js
│ └── index.js
│ ├── utils
│ ├── html-tags.js
│ └── index.js
│ └── withTemplating.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false
5 | }],
6 | "stage-0",
7 | "react"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # See https://help.github.com/ignore-files/ for more about ignoring files.
3 |
4 | # dependencies
5 | node_modules
6 |
7 | # builds
8 | build
9 | dist
10 | .rpt2_cache
11 |
12 | # misc
13 | .DS_Store
14 | .env
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 |
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
24 | *.tgz
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | example
3 | node_modules
4 | *.tgz
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": true,
7 | "trailingComma": "none",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false,
10 | "fluid": false
11 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: 10.15.1
3 |
4 | cache:
5 | directories:
6 | - node_modules
7 |
8 | install:
9 | - npm install
10 |
11 | script:
12 | - npm run build
13 |
14 | deploy:
15 | provider: npm
16 | skip_cleanup: true
17 | email: ritwickdey@outlook.com
18 | api_key: $NPM_TOKEN
19 | name: Ritwick Dey
20 | on:
21 | tags: true
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ritwick Dey
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 Jsx Templating
2 |
3 | > React Jsx Templating is a simple library, inspired by Angular :)
4 |
5 | [](https://www.npmjs.com/package/react-jsx-templating) [](https://standardjs.com) [](https://travis-ci.com/ritwickdey/react-jsx-templating)
6 |
7 | `React Jsx Templating` will give you templating syntax like Angular `*ngIf`
8 |
9 | **_Live Example: [Open in Codesandbox](https://codesandbox.io/s/j312l1m2x9)_**
10 |
11 | ## Install
12 |
13 | ```bash
14 | npm install --save react-jsx-templating
15 | ```
16 |
17 | ## Usage
18 |
19 | - **Use HOC**
20 |
21 | ```jsx
22 | import withTemplating from 'react-jsx-templating'; //Note: default import
23 | class MyComponent extends Component {
24 | render()
25 | return "foo";
26 | }
27 | }
28 |
29 | export default withTemplating(MyComponent);
30 | ```
31 |
32 | - Use Wrapper HTML tags
33 |
34 | ```jsx
35 | // Note: named import. There are total 118 Elements
36 | import { Fragment, Div, P, Button, Br, Span } from 'react-jsx-templating';
37 | ```
38 |
39 | ## Syntax
40 |
41 | - If-else
42 |
43 | ```diff
44 | let isEnglish = false;
45 | +
46 | ```
47 |
48 | - switch-case
49 |
50 | ```diff
51 | let testValue = 'c';
52 | +
person.id}>
65 | + {person =>
{person.name}
}
66 | +
67 | ```
68 |
69 | ## Examples
70 |
71 | - **Switch-Case Templating**
72 |
73 | ```jsx
74 | import React, { useState } from 'react';
75 | import { Div } from 'react-jsx-templating';
76 |
77 | function ExampleSwitchCase() {
78 | const [animal, setAnimal] = useState('');
79 | return (
80 |
81 |
setAnimal(e.target.value)}
85 | />
86 |
Please type!!
}>
87 |
88 |
woof-woof 🐕
89 |
meows meows 🐈
90 |
Ops!! No Match!
91 |
92 |
93 |
94 | );
95 | }
96 | ```
97 |
98 | - **If-Else Templating**
99 |
100 | ```jsx
101 | import React, { Component } from 'react';
102 | import { Div, Fragment, Button, Br } from 'react-jsx-templating';
103 | import { EnglishNewsPaper, SpanishNewsPaper } from './Components';
104 |
105 | class ExampleIfElse extends Component {
106 | state = {
107 | isEngLang: true
108 | };
109 |
110 | toogleLanguage = () => {
111 | this.setState(oldState => ({ isEngLang: !oldState.isEngLang }));
112 | };
113 |
114 | render() {
115 | const { isEngLang } = this.state;
116 | return (
117 |
118 | Hola!>}>
119 | Hello!
120 |
121 |
122 |
123 |
124 | );
125 | }
126 | }
127 | ```
128 |
129 | - **For Loop**
130 |
131 | ```jsx
132 | import React from 'react';
133 | import { Div } from 'react-jsx-templating';
134 | import { Article } from './Components';
135 |
136 | function ExampleForLoop() {
137 | return (
138 |
id}>
139 | {article =>
}
140 |
141 | );
142 | }
143 | ```
144 |
145 | ## What's next ?
146 |
147 | - ~~Switch Case~~ (added)
148 | - ~~Loop~~ (added)
149 | - ~~Fragment~~ (added)
150 |
151 | ## License
152 |
153 | MIT © [ritwickdey](https://github.com/ritwickdey)
154 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
2 |
3 | repository: ritwickdey/react-jsx-templating
4 |
5 | gems:
6 | - jekyll-seo-tag
7 |
8 | title: React Jsx Templating
9 | description : React Jsx Templating will give you templating syntax like Angular *ngIf
10 | author : Ritwick Dey
11 | twitter:username: Dey_Ritwick
12 | social:
13 | name: React Jsx Templating
14 | links:
15 | - https://github.com/ritwickdey/react-jsx-templating
16 | lang: en_IN
17 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-jsx-templating-example",
3 | "homepage": "https://ritwickdey.github.io/react-jsx-templating",
4 | "version": "0.0.0",
5 | "license": "MIT",
6 | "private": true,
7 | "dependencies": {
8 | "prop-types": "^15.6.2",
9 | "react": "^16.4.1",
10 | "react-dom": "^16.4.1",
11 | "react-jsx-templating": "link:..",
12 | "react-scripts": "^2.1.8"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test --env=jsdom",
18 | "eject": "react-scripts eject"
19 | },
20 | "browserslist": [
21 | ">0.2%",
22 | "not dead",
23 | "not ie <= 11",
24 | "not op_mini all"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
react-jsx-templating
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/example/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "react-jsx-templating",
3 | "name": "react-jsx-templating",
4 | "start_url": "./index.html",
5 | "display": "standalone",
6 | "theme_color": "#000000",
7 | "background_color": "#ffffff"
8 | }
9 |
--------------------------------------------------------------------------------
/example/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import IfElse from './components/IfElse';
3 | import SwitchCase from './components/SwitchCase';
4 | import ForLoop from './components/ForLoop';
5 |
6 | function App() {
7 | return (
8 |
9 |
10 | If-Else Example
11 |
12 |
13 |
14 |
15 |
16 | Switch-Case Example
17 |
18 |
19 |
20 |
21 |
22 | For Loop Example
23 |
24 |
25 |
26 | );
27 | }
28 |
29 | export default App;
30 |
--------------------------------------------------------------------------------
/example/src/components/ForLoop.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { Div } from 'react-jsx-templating';
4 |
5 | const Articles = [
6 | {
7 | id: 1,
8 | head: 'Article 1',
9 | body: 'This is body of Article 1'
10 | },
11 | {
12 | id: 2,
13 | head: 'Article 2',
14 | body: 'This is body of Article 2'
15 | },
16 | {
17 | id: 3,
18 | head: 'Article 3',
19 | body: 'This is body of Article 3'
20 | }
21 | ];
22 |
23 | function Article(props) {
24 | const { article } = props;
25 | return (
26 |
27 |
28 |
{article.body}
29 |
30 | );
31 | }
32 |
33 | function ForLoop() {
34 | return (
35 |
article.id}>
36 | {article =>
}
37 |
38 | );
39 | }
40 |
41 | export default ForLoop;
42 |
--------------------------------------------------------------------------------
/example/src/components/Helper/MySomeComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import withTemplating from 'react-jsx-templating';
3 |
4 | function MySomeComponent(props) {
5 | return
{props.title || props.children}
;
6 | }
7 |
8 | export default withTemplating(MySomeComponent);
9 |
--------------------------------------------------------------------------------
/example/src/components/IfElse.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 |
3 | import { Div, P, Button, Br, Fragment } from 'react-jsx-templating';
4 | import MySomeComponent from './Helper/MySomeComponent';
5 |
6 | function IfElse() {
7 | const [show, setShow] = useState(true);
8 | const [showToggler, setShowToggler] = useState(true);
9 | return (
10 |
11 |
Hola ^_^
}>
12 | Hello! :D
13 |
14 |
Yay! It works
}>
15 | Welcome here
16 |
17 |
22 |
23 |
26 |
27 | );
28 | }
29 |
30 | export default IfElse;
31 |
--------------------------------------------------------------------------------
/example/src/components/SwitchCase.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Div } from 'react-jsx-templating';
3 |
4 | function SwitchCase() {
5 | const [animal, setAnimal] = useState('');
6 | return (
7 |
8 |
setAnimal(e.target.value)}
12 | />
13 |
14 |
15 |
Please type!!
}>
16 |
17 |
woof-woof 🐕
18 |
meows meows 🐈
19 |
Ops!! No Match with `{`${animal}`} `
20 |
21 |
22 |
23 | );
24 | }
25 |
26 | export default SwitchCase;
27 |
--------------------------------------------------------------------------------
/example/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 18px;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
7 | .App {
8 | margin-top: 18px;
9 | font-family: sans-serif;
10 | /* text-align: center; */
11 | }
12 |
--------------------------------------------------------------------------------
/example/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 |
4 | import './index.css'
5 | import App from './App'
6 |
7 | ReactDOM.render(
, document.getElementById('root'))
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-jsx-templating",
3 | "version": "0.0.7",
4 | "description": "React Jsx Templating, inspired by Angular :)",
5 | "author": "ritwickdey",
6 | "license": "MIT",
7 | "repository": "ritwickdey/react-jsx-templating",
8 | "main": "dist/index.js",
9 | "module": "dist/index.es.js",
10 | "jsnext:main": "dist/index.es.js",
11 | "engines": {
12 | "node": ">=8",
13 | "npm": ">=5"
14 | },
15 | "scripts": {
16 | "test": "cross-env CI=1 react-scripts test --env=jsdom",
17 | "test:watch": "react-scripts test --env=jsdom",
18 | "build": "rollup -c",
19 | "start": "rollup -c -w",
20 | "prepare": "yarn run build",
21 | "predeploy": "cd example && yarn install && yarn run build",
22 | "deploy": "gh-pages -d example/build"
23 | },
24 | "peerDependencies": {
25 | "prop-types": "^15.5.4",
26 | "react": "^15.0.0 || ^16.0.0",
27 | "react-dom": "^15.0.0 || ^16.0.0"
28 | },
29 | "devDependencies": {
30 | "@svgr/rollup": "^2.4.1",
31 | "babel-core": "^6.26.3",
32 | "babel-eslint": "^8.2.5",
33 | "babel-plugin-external-helpers": "^6.22.0",
34 | "babel-preset-env": "^1.7.0",
35 | "babel-preset-react": "^6.24.1",
36 | "babel-preset-stage-0": "^6.24.1",
37 | "cross-env": "^5.1.4",
38 | "eslint": "^5.0.1",
39 | "eslint-config-standard": "^11.0.0",
40 | "eslint-config-standard-react": "^6.0.0",
41 | "eslint-plugin-import": "^2.13.0",
42 | "eslint-plugin-node": "^7.0.1",
43 | "eslint-plugin-promise": "^4.0.0",
44 | "eslint-plugin-react": "^7.10.0",
45 | "eslint-plugin-standard": "^3.1.0",
46 | "gh-pages": "^1.2.0",
47 | "react": "^16.4.1",
48 | "react-dom": "^16.4.1",
49 | "react-scripts": "^1.1.4",
50 | "rollup": "^0.64.1",
51 | "rollup-plugin-babel": "^3.0.7",
52 | "rollup-plugin-commonjs": "^9.1.3",
53 | "rollup-plugin-node-resolve": "^3.3.0",
54 | "rollup-plugin-peer-deps-external": "^2.2.0",
55 | "rollup-plugin-postcss": "^1.6.2",
56 | "rollup-plugin-url": "^1.4.0"
57 | },
58 | "files": [
59 | "dist"
60 | ]
61 | }
62 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import commonjs from 'rollup-plugin-commonjs'
3 | import external from 'rollup-plugin-peer-deps-external'
4 | import postcss from 'rollup-plugin-postcss'
5 | import resolve from 'rollup-plugin-node-resolve'
6 | import url from 'rollup-plugin-url'
7 | import svgr from '@svgr/rollup'
8 |
9 | import pkg from './package.json'
10 |
11 | export default {
12 | input: 'src/index.js',
13 | output: [
14 | {
15 | file: pkg.main,
16 | format: 'cjs',
17 | sourcemap: true,
18 | exports: 'named',
19 | },
20 | {
21 | file: pkg.module,
22 | format: 'es',
23 | sourcemap: true,
24 | exports: 'named',
25 | }
26 | ],
27 | plugins: [
28 | external(),
29 | postcss({
30 | modules: true
31 | }),
32 | url(),
33 | svgr(),
34 | babel({
35 | exclude: 'node_modules/**',
36 | plugins: [ 'external-helpers' ]
37 | }),
38 | resolve(),
39 | commonjs()
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/src/__test__/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ritwickdey/react-jsx-templating/72329a16670043b75ecdea5ce01c54ef6bd47283/src/__test__/.gitkeep
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import withTemplating from './lib/withTemplating';
2 | export * from './lib/Elements';
3 |
4 | export default withTemplating;
5 |
--------------------------------------------------------------------------------
/src/lib/Elements/DOMElements.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { HTML_TAGS } from '../utils/html-tags';
3 | import withTemplating from '../withTemplating';
4 |
5 | const DOMElements = {};
6 |
7 | HTML_TAGS.forEach(tag => {
8 | const Fn = props => {
9 | const { $if, $switch, $case, $default, $else, $key, $for, ...rest } = props;
10 | return React.createElement(tag, rest);
11 | };
12 | const Tag = capitalCase(tag);
13 | Fn.displayName = Tag;
14 | DOMElements[Tag] = withTemplating(Fn);
15 | });
16 |
17 | function capitalCase(str) {
18 | return str.charAt(0).toUpperCase() + str.slice(1);
19 | }
20 |
21 | export default DOMElements;
22 |
--------------------------------------------------------------------------------
/src/lib/Elements/Fragment.js:
--------------------------------------------------------------------------------
1 | import withTemplating from "../withTemplating";
2 |
3 | const Fragment = ({ children }) => {
4 | return children;
5 | };
6 |
7 | export default withTemplating(Fragment);
8 |
--------------------------------------------------------------------------------
/src/lib/Elements/index.js:
--------------------------------------------------------------------------------
1 | import DOMElements from './DOMElements';
2 | export { default as Fragment } from './Fragment';
3 |
4 | export const {
5 | A,
6 | Abbr,
7 | Address,
8 | Area,
9 | Article,
10 | Aside,
11 | Audio,
12 | B,
13 | Base,
14 | Bdi,
15 | Bdo,
16 | Blockquote,
17 | Body,
18 | Br,
19 | Button,
20 | Canvas,
21 | Caption,
22 | Cite,
23 | Code,
24 | Col,
25 | Colgroup,
26 | Data,
27 | Datalist,
28 | Dd,
29 | Del,
30 | Details,
31 | Dfn,
32 | Dialog,
33 | Div,
34 | Dl,
35 | Dt,
36 | Em,
37 | Embed,
38 | Fieldset,
39 | Figcaption,
40 | Figure,
41 | Footer,
42 | Form,
43 | H1,
44 | H2,
45 | H3,
46 | H4,
47 | H5,
48 | H6,
49 | Head,
50 | Header,
51 | Hgroup,
52 | Hr,
53 | Html,
54 | I,
55 | Iframe,
56 | Img,
57 | Input,
58 | Ins,
59 | Kbd,
60 | Keygen,
61 | Label,
62 | Legend,
63 | Li,
64 | Link,
65 | Main,
66 | Map,
67 | Mark,
68 | Math,
69 | Menu,
70 | Menuitem,
71 | Meta,
72 | Meter,
73 | Nav,
74 | Noscript,
75 | Object,
76 | Ol,
77 | Optgroup,
78 | Option,
79 | Output,
80 | P,
81 | Param,
82 | Picture,
83 | Pre,
84 | Progress,
85 | Q,
86 | Rb,
87 | Rp,
88 | Rt,
89 | Rtc,
90 | Ruby,
91 | S,
92 | Samp,
93 | Script,
94 | Section,
95 | Select,
96 | Slot,
97 | Small,
98 | Source,
99 | Span,
100 | Strong,
101 | Style,
102 | Sub,
103 | Summary,
104 | Sup,
105 | Svg,
106 | Table,
107 | Tbody,
108 | Td,
109 | Template,
110 | Textarea,
111 | Tfoot,
112 | Th,
113 | Thead,
114 | Time,
115 | Title,
116 | Tr,
117 | Track,
118 | U,
119 | Ul,
120 | Var,
121 | Video,
122 | wbr
123 | } = DOMElements;
124 |
--------------------------------------------------------------------------------
/src/lib/helperFns/doForLoopOperation.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export function doForLoopOperation(props, Component) {
4 | const { $for: items, $key: keyFn, ...restProps } = props;
5 |
6 | const children = items.map((item, index, array) => {
7 | const child = props.children(item, index, array);
8 | const key = keyFn ? keyFn(item) : child.key;
9 | return React.cloneElement(child, { key, ...child.props });
10 | });
11 |
12 | return React.createElement(Component, restProps, children);
13 | }
14 |
--------------------------------------------------------------------------------
/src/lib/helperFns/doIfElseOperation.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isTrusy } from '../utils';
3 |
4 | export function doIfElseOperation(props, Component) {
5 | const { $if: condition, $else: elseBlock, ...restProps } = props;
6 |
7 | if (isTrusy(condition)) {
8 | return React.createElement(Component, restProps);
9 | }
10 |
11 | if (typeof elseBlock === 'function') {
12 | return React.createElement(elseBlock, restProps);
13 | }
14 | return elseBlock || null;
15 | }
16 |
--------------------------------------------------------------------------------
/src/lib/helperFns/doSwitchCaseOperation.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isTrusy, isUndefined } from '../utils';
3 |
4 | export function doSwitchCaseOperation(props, Component) {
5 | const { $switch: switchValue, children, ...restProps } = props;
6 |
7 | let targetChildNode = null;
8 |
9 | const totalNoOfNode = React.Children.count(children);
10 | for (let i = 0; i < totalNoOfNode; i++) {
11 | const child = totalNoOfNode === 1 ? children : children[i];
12 |
13 | if (!React.isValidElement(child)) continue;
14 |
15 | const { $case: caseValue, $default: defaultValue } = child.props;
16 |
17 | if (isUndefined(caseValue) && isUndefined(defaultValue)) {
18 | throw new Error('$case or $default is missing', child);
19 | }
20 |
21 | if (isTrusy(defaultValue) || caseValue === switchValue) {
22 | targetChildNode = child;
23 | break;
24 | }
25 | }
26 |
27 | if (targetChildNode) {
28 | const { $case, $default, ...childProps } = targetChildNode.props;
29 | targetChildNode = React.cloneElement(targetChildNode, childProps);
30 | }
31 |
32 | return React.createElement(Component, restProps, targetChildNode);
33 | }
34 |
--------------------------------------------------------------------------------
/src/lib/helperFns/index.js:
--------------------------------------------------------------------------------
1 | export { doIfElseOperation } from './doIfElseOperation';
2 | export { doSwitchCaseOperation } from './doSwitchCaseOperation';
3 | export { doForLoopOperation } from './doForLoopOperation';
4 |
--------------------------------------------------------------------------------
/src/lib/utils/html-tags.js:
--------------------------------------------------------------------------------
1 | // Thanks @sindresorhus
2 | // https://raw.githubusercontent.com/sindresorhus/html-tags/master/html-tags.json
3 |
4 | export const HTML_TAGS = [
5 | 'a',
6 | 'abbr',
7 | 'address',
8 | 'area',
9 | 'article',
10 | 'aside',
11 | 'audio',
12 | 'b',
13 | 'base',
14 | 'bdi',
15 | 'bdo',
16 | 'blockquote',
17 | 'body',
18 | 'br',
19 | 'button',
20 | 'canvas',
21 | 'caption',
22 | 'cite',
23 | 'code',
24 | 'col',
25 | 'colgroup',
26 | 'data',
27 | 'datalist',
28 | 'dd',
29 | 'del',
30 | 'details',
31 | 'dfn',
32 | 'dialog',
33 | 'div',
34 | 'dl',
35 | 'dt',
36 | 'em',
37 | 'embed',
38 | 'fieldset',
39 | 'figcaption',
40 | 'figure',
41 | 'footer',
42 | 'form',
43 | 'h1',
44 | 'h2',
45 | 'h3',
46 | 'h4',
47 | 'h5',
48 | 'h6',
49 | 'head',
50 | 'header',
51 | 'hgroup',
52 | 'hr',
53 | 'html',
54 | 'i',
55 | 'iframe',
56 | 'img',
57 | 'input',
58 | 'ins',
59 | 'kbd',
60 | 'keygen',
61 | 'label',
62 | 'legend',
63 | 'li',
64 | 'link',
65 | 'main',
66 | 'map',
67 | 'mark',
68 | 'math',
69 | 'menu',
70 | 'menuitem',
71 | 'meta',
72 | 'meter',
73 | 'nav',
74 | 'noscript',
75 | 'object',
76 | 'ol',
77 | 'optgroup',
78 | 'option',
79 | 'output',
80 | 'p',
81 | 'param',
82 | 'picture',
83 | 'pre',
84 | 'progress',
85 | 'q',
86 | 'rb',
87 | 'rp',
88 | 'rt',
89 | 'rtc',
90 | 'ruby',
91 | 's',
92 | 'samp',
93 | 'script',
94 | 'section',
95 | 'select',
96 | 'slot',
97 | 'small',
98 | 'source',
99 | 'span',
100 | 'strong',
101 | 'style',
102 | 'sub',
103 | 'summary',
104 | 'sup',
105 | 'svg',
106 | 'table',
107 | 'tbody',
108 | 'td',
109 | 'template',
110 | 'textarea',
111 | 'tfoot',
112 | 'th',
113 | 'thead',
114 | 'time',
115 | 'title',
116 | 'tr',
117 | 'track',
118 | 'u',
119 | 'ul',
120 | 'var',
121 | 'video',
122 | 'wbr'
123 | ];
124 |
--------------------------------------------------------------------------------
/src/lib/utils/index.js:
--------------------------------------------------------------------------------
1 | export function isTrusy(obj) {
2 | return !!obj;
3 | }
4 |
5 | export function isUndefined(obj) {
6 | return typeof obj === 'undefined';
7 | }
8 |
--------------------------------------------------------------------------------
/src/lib/withTemplating.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isUndefined } from './utils';
3 | import { doIfElseOperation, doForLoopOperation, doSwitchCaseOperation } from './helperFns';
4 |
5 | const withTemplating = Component => {
6 | const Templating = props => {
7 | const { $if, $switch, $for, ...restProps } = props;
8 |
9 | if (!isUndefined($if)) {
10 | return doIfElseOperation(props, Component);
11 | }
12 |
13 | if (!isUndefined($switch)) {
14 | return doSwitchCaseOperation(props, Component);
15 | }
16 |
17 | if (!isUndefined($for)) {
18 | return doForLoopOperation(props, Component);
19 | }
20 |
21 | return React.createElement(Component, restProps);
22 | };
23 |
24 | Templating.displayName = `withTemplating(${Component.displayName || Component.name})`;
25 | return Templating;
26 | };
27 |
28 | export default withTemplating;
29 |
--------------------------------------------------------------------------------