jcod-react-parser
React Component for parsing JSON/JCOD object recursively and produce an React Components tree.
Getting Started
Prerequisites
JCOD (JSON as Component Object Description) is an object syntax. It is a JSON subtree for the description of components. See more details on JCOD.org
(Also, for more information you will soon be able to read an article about it on Medium.)
Below, you can view a sample of JCOD structure.
const sampleOf_JCOD = [
{
key: 'sample-1',
component: 'div',
children: 'My test',
},
{
key: 'sample-2',
component: 'smart-section',
children: [
'A simple smart section',
{
key: 'sample-1',
component: 'div',
children: 'Foo inside !',
props: {
class: 'sample-class',
id: 'sample-id',
},
},
{
key: 'sample-2',
component: 'SampleBloc',
children: 'A sample bloc',
},
],
props: {
element: 'i',
},
},
]
How to use
import the JcodParser and use like any other React component:
import JcodParser from 'jcod-react-parser'
const myFunctionalComponent = () => (
<JcodParser
components={availableComponent}
data={jcodTree}
options={parserOptions}
spreader={spreaderObject}
/>
)
About The React Extended JCOD
The jcod-react-parser use an extended version of JCOD node, with some specifical keys:
- key: (
String
) The value of key attribute. If some nodes do not have key
, the parser will try to set with a unique automatic value for each of these node. - renderProps: (
Object
of Key/value) Like the children
key. Each value of this object will be parse.
Also,
- If a key name
key
is specified in the props
or renderProps
object, it will be ignored by the parser. - If a key name
children
is specified in the props
object, it will be use as children of react component BUT will not be parse. - If a
children
key name is specified in the renderProps
object, it will be use as children of react component AND will be parse. It is an alias to the ROOT children
key name. - If multiple
children
key name are specified, (in the root, props
and/or renderProps
) only one will be used. It will be selected in this order of priority: ROOT, renderProps
and props
.
React JCOD definition
{
component: /REQUIRED/
STRING
key: /OPTIONAL/ (react-parser-key)
STRING
children: /OPTIONAL/
STRING
(or) JCOD-OBJECT
(or) ARRAY-OF-STRING-OR-JCOD-OBJECT
props: /OPTIONAL/
JCOD-PROPS-OBJECT
renderProps: /OPTIONAL/ (react-parser-key)
OBJECT-OF-JCOD-TREE
},
Sample of Extended JCOD
{
"key": "sample-of-key",
"component": "Switch",
"children": "Enable Option ?",
"props": {
"className": "sample-class",
"id": "sample-id",
"name": "option",
},
"renderProps": {
"onLabel": "Yes !",
"offLabel": {
"component": "BoldItem",
"children": "Off",
"props": {
"className": "warning-red",
},
},
},
},
Simple Sample
Here a sample of very lite React application:
import React from 'react'
import ReactDOM from 'react-dom'
import JcodParser from 'jcod-react-parser'
import { MyComponent, MyOtherComponent } from './myTemplatesComponentsFolder'
const availableComponent = { MyComponent, MyOtherComponent }
const jcodData = [
'Sample Of App',
{
key: 'comp-1',
component: 'MyComponent',
children: 'A simple test',
},
{
key: 'comp-2',
component: 'MyOtherComponent',
children: 'A simple other test',
},
]
ReactDOM.render(
<JcodParser components={availableComponent} data={jcodData} />,
document.getElementById('App'),
)
You can see an integration sample on Code Sandbox
Props description
The JcodReactParser require these props:
-
components
: an object containing a list of available React Component. The components of this list could be use in the JCOD object.
Here a sample of available components:
import AnyComponent from 'anyFolder'
import {
LittleComponent,
OtherComponent,
} from './myTemplatesComponentsFolder'
import * as myComponents from './anyOtherFolder'
const availableComponents = {
AnyComponent,
LittleComponent,
OtherComponent,
...myComponents,
}
or a very simple import:
import * as availableComponents from './anyOtherFolder'
[...]
ReactDOM.render(
<JcodParser
components={availableComponents}
data={jcodData}
/>,
document.getElementById('App')
)
-
data
: Any JCOD object
The JcodReactParser can also receive these optional props:
-
options
: An object of options.
Before, it should be noted that,
To identify the type of component who has been set as the component
key, the parser inspect the case and the syntax of the component name :
- React Component: First letter of the component name is Uparcase.
- Custome Element: Name in lowercase and 2 or more words, each seprate by an hyphen. (See valid custom element name documentation)
- HTML element: Name in lowercase and in only one word.
{
"allowUnsecureElements": [boolean || Array (default to false)],
"allowUnsecureHtmlElement": [boolean (default to false)],
"allowUnsecureCustomElement": [boolean (default to false)],
"displayErrorMessage": [boolean (default to true)],
"__DEPRECATED__renderAllChildren": [boolean (default to false)],
}
-
If allowUnsecureCustomElement
is true
, you can use any Custom Element tag as component in you JCOD object. The names of the custom elements must respect the naming convention. (If allowUnsecureElements
is true
, this value is override and is also true
)
-
If allowUnsecureHtmlElement
is true
, you can use any valid HTML tag as component in you JCOD object. (If allowUnsecureElements
is true
, this value is override and is also true
)
-
If allowUnsecureElements
:
-
is true
, so allowUnsecureCustomElement
and allowUnsecureHtmlElement
are also true
.
-
is Array
of string
, each value of this array can be use as valid tag of allowUnsecureCustomElement
or allowUnsecureHtmlElement
.
import { MyComponent, MyOtherComponent } from './myTemplatesComponentsFolder'
const availableComponent = { MyComponent, MyOtherComponent }
const parserOption = {
allowUnsecureElements: ['section', 'my-custom-element']
}
const jcodData = [
{
{
key: 'comp-1',
component: 'myComponent',
props: {
children: 'Any test 1',
}
},
{
key: 'comp-2',
component: 'myOtherComponent',
props: {
children: 'Any test 2',
},
},
{
key: 'comp-3',
component: 'my-custom-element',
props: {
children: 'It is a custom element',
},
},
{
key: 'comp-4',
component: 'section',
props: {
children: 'It is an element',
},
},
{
key: 'comp-4',
component: 'div',
props: {
children: 'It is a not display element',
},
},
},
]
const jcodContent = (
<JcodParser
components={availableComponents}
data={jcodData}
options={parserOption}
/>
)
-
If displayErrorMessage
is false
the error or helping messages will be not display in the navigator DevTools console. Usually, this option should be disabled for the production build.
-
the __DEPRECATED__renderAllChildren
option offer the possibilities to support the legacy and depracated version of the JCOD specification. If it's true
, the value of children
key name in the props
object will be parsed like the ROOT or renderProps
value of children
key name. This option is present to help you to migrate your codebase of JCOD to the official version of JCOD specification.
-
spreader
: An object of utilities to convert or overload the JCOD tree or extend the possibilities of the Parser. The Spreader can be use for debug or any clever use you could imagine.
{
"formater": [function (default to (child, metadata) => child)],
"nodeDecorator": [function (default to (node, metadata) => node)],
"treeDecorator": [function (default to (tree, metadata) => tree)],
}
Sample of Spreader
const sampleOfSpreader = {
formater: (child, metadata) => child,
nodeDecorator: (node, metadata) => (
<div
style={{ border: '1px solid red', margin: '2px' }}
title={JSON.stringify(metadata)}
>
{node}
</div>
),
treeDecorator: (tree, metadata) => (
<div
style={{ border: '1px solid blue', margin: '2px' }}
title={JSON.stringify(metadata)}
>
{node}
</div>
),
}
Sample of usage of all props:
[...]
ReactDOM.render(
<JcodParser
components={templates}
data={jcodData}
options={parserOption}
spreader={AnySpreaderComponent}
/>,
document.getElementById('App')
)
Versioning
This project use SemVer for versioning.
Authors
- Nicolas KOKLA - Initial work
See also the list of contributors who participated in this project.
License
This project is licensed under the MIT License - see the LICENSE file for details