src/children.js
import { getReactElementFromJSONX, } from './main';
/**
* returns a valid jsonx.children property
* @param {Object} options
* @param {Object} [options.jsonx ={}]- Valid JSONX JSON
* @param {Object} [options.props=options.jsonx.children] - Props to pull children Object.assign(jsonx.props,jsonx.asyncprops,jsonx.thisprops,jsonx.windowprops)
* @returns {Object[]|String} returns a valid jsonx.children property that's either an array of JSONX objects or a string
* @example
* const sampleJSONX = {
component: 'div',
props: {
id: 'generatedJSONX',
className:'jsonx',
},
children: [
{
component: 'p',
props: {
style: {
color: 'red',
},
},
children:'hello world',
},
{
component: 'div',
children: [
{
component: 'ul',
children: [
{
component: 'li',
children:'list',
},
],
},
],
},
],
};
const JSONXChildren = getChildrenProperty({ jsonx: sampleJSONX, }); //=> [ [jsonx Object],[jsonx Object]]
const JSONXChildrenPTag = getChildrenProperty({ jsonx: sampleJSONX.children[ 0 ], }); //=>hello world
*/
export function getChildrenProperty(options = {}) {
const { jsonx = {}, } = options;
const props = options.props || jsonx.props || {};
if (typeof props._children!=='undefined' /* && !jsonx.children */) {
if (Array.isArray(props._children) || typeof props._children === 'string' || typeof props._children === 'number'){
return props._children;
} else {
return jsonx.children;
}
} else if (typeof jsonx.children === 'undefined'){
if (props && props.children && (typeof props.children !== 'undefined' || Array.isArray(props.children))) {
return props.children;
} else {
return null;
}
} else {
return jsonx.children;
}
}
/**
* Used to pass properties down to child components if passprops is set to true
* @param {Object} options
* @param {Object} [options.jsonx ={}] - Valid JSONX JSON
* @param {Object} [options.childjsonx ={}] - Valid JSONX JSON
* @param {Number} options.renderIndex - React key property
* @param {Object} [options.props=options.jsonx.props] - Props to pull children Object.assign(jsonx.props,jsonx.asyncprops,jsonx.thisprops,jsonx.windowprops)
* @returns {Object|String} returns a valid Valid JSONX Child object or a string
*/
export function getChildrenProps(options = {}) {
const { jsonx = {}, childjsonx, renderIndex, } = options;
const props = options.props || jsonx.props || {};
return (jsonx.passprops && typeof childjsonx==='object')
? Object.assign({},
childjsonx, {
props: Object.assign({},
props,
((childjsonx.thisprops && childjsonx.thisprops.style) // this is to make sure when you bind props, if you've defined props in a dynamic property, to not use bind props to remove passing down styles
|| (childjsonx.asyncprops && childjsonx.asyncprops.style)
|| (childjsonx.windowprops && childjsonx.windowprops.style))
? {}
: {
style: {},
},
childjsonx.props,
{ key: renderIndex + Math.random(), }),
})
: childjsonx;
}
/**
* returns React Child Elements via JSONX
* @param {*} options
* @property {object} this - options for getReactElementFromJSONX
* @property {Object} [this.componentLibraries] - react components to render with JSONX
* @property {boolean} [this.debug=false] - use debug messages
* @property {function} [this.logError=console.error] - error logging function
* @property {string[]} [this.boundedComponents=[]] - list of components that require a bound this context (usefult for redux router)
*/
export function getJSONXChildren(options = {}) {
// eslint-disable-next-line
const { jsonx, resources, renderIndex, logError = console.error, } = options;
try {
const props = options.props || jsonx.props || {};
jsonx.children = getChildrenProperty({ jsonx, props, });
props._children = undefined;
delete props._children;
return (jsonx.children && Array.isArray(jsonx.children) && typeof jsonx.children !== 'string')
? jsonx.children.map(childjsonx => getReactElementFromJSONX.call(this, getChildrenProps({ jsonx, childjsonx, props, renderIndex, }), resources))
: jsonx.children;
} catch (e) {
logError(e);
return null;
}
}