Skip to content

Commit

Permalink
feat(components): fix for makeFunctionComponent to allow for more fle…
Browse files Browse the repository at this point in the history
…xible components
  • Loading branch information
yawetse committed Mar 23, 2021
1 parent 0eab0ac commit 3e15f00
Show file tree
Hide file tree
Showing 26 changed files with 696 additions and 246 deletions.
22 changes: 22 additions & 0 deletions build/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,29 @@ export declare function DynamicComponent(this: defs.Context, props?: defs.dynami
const MyCustomFunctionComponent = jsonx._jsonxComponents.getReactFunctionComponent({jsonxRender, functionBody, options});
*/
export declare function getReactFunctionComponent(this: defs.Context, reactComponent?: {}, functionBody?: string | defs.functionParam, options?: any): any;
/**
* Returns the string of a function, the difference between calling .toString() on a function definition is, the toString method will return the entire function definition (with paramaters and the name, etc)
* @param {Function} - The function you want the body string for
* @returns {String}
* @example
function myFunc(){
const a = 1;
const b = 3;
return a + b;
}
getFunctionBody(myFunc) => `
const a = 1;
const b = 3;
return a + b;
`
*/
export declare function getFunctionBody(func: () => any): string;
/**
* A helpful function that lets you write a regular JavaScript function and passes the appropriate arguments to getReactFunctionComponent
* @param {Function} func - function definition to turn into React Component Function
* @property {object} this - options for getReactElementFromJSONX
* @returns {Function} - React Component Function
*/
export declare function makeFunctionComponent(this: defs.Context, func: () => any, options: any): any;
/**
*
Expand Down
28 changes: 26 additions & 2 deletions build/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,16 +492,40 @@ export function getReactFunctionComponent(reactComponent = {}, functionBody = ""
? functionComponent.call(this, ...functionArgs)
: functionComponent(...functionArgs);
}
/**
* Returns the string of a function, the difference between calling .toString() on a function definition is, the toString method will return the entire function definition (with paramaters and the name, etc)
* @param {Function} - The function you want the body string for
* @returns {String}
* @example
function myFunc(){
const a = 1;
const b = 3;
return a + b;
}
getFunctionBody(myFunc) => `
const a = 1;
const b = 3;
return a + b;
`
*/
export function getFunctionBody(func) {
const functionString = func.toString();
if (functionString.includes('return') === false)
throw new EvalError('JSONX Function Components can not use implicit returns');
return functionString.substring(functionString.indexOf("{") + 1, functionString.lastIndexOf("}"));
}
/**
* A helpful function that lets you write a regular JavaScript function and passes the appropriate arguments to getReactFunctionComponent
* @param {Function} func - function definition to turn into React Component Function
* @property {object} this - options for getReactElementFromJSONX
* @returns {Function} - React Component Function
*/
export function makeFunctionComponent(func, options) {
const scopedEval = eval;
const [functionBody, reactComponentString] = getFunctionBody(func).split('return');
const reactComponent = scopedEval(`(${reactComponentString})`);
const fullFunctionBody = getFunctionBody(func);
const [functionBody,] = fullFunctionBody.split('return');
let reactComponentString = fullFunctionBody.replace(functionBody, '').trim();
const reactComponent = scopedEval(`(()=>{${reactComponentString}})()`);
const functionOptions = { name: func.name, ...options };
return getReactFunctionComponent.call(this, reactComponent, functionBody, functionOptions);
}
Expand Down
3 changes: 0 additions & 3 deletions build/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/**
* [[include:getting-started]]
*/
import React from "react";
import ReactDOM from "react-dom";
import * as defs from "./types/jsonx/index";
Expand Down
3 changes: 0 additions & 3 deletions build/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/**
* [[include:getting-started]]
*/
// import React, { createElement, } from 'react';
import React from "react";
import ReactDOM from "react-dom";
Expand Down
13 changes: 6 additions & 7 deletions dist/example-simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8">
<title>JSONX TEST</title>
<!-- <script type="text/javascript" src="jsonx.web.js"></script> -->
<script type="text/javascript" src="index.web.min.js"></script>
<script type="text/javascript" src="index.web.js"></script>
<script type="text/javascript">
window.React = jsonx.__getReact();
window.ReactDOM = jsonx.__getReactDOM();
Expand All @@ -17,9 +17,6 @@
<body>
<div id="root"></div>
<script type="text/javascript">
function someExternalCall(count){
console.log('current count is at',count)
}
function IntroHook(){
const [count, setCount] = useState(0);

Expand All @@ -32,8 +29,6 @@
props:{
extra:'ok'
},
// debug:true,

passprops:true,
children:[
{
Expand All @@ -46,6 +41,11 @@
children:[
{
component:'span',
__dangerouslyEvalAllProps:function(){
return {
style:{color:'red'}
}
},
children:'You clicked ',
},
{
Expand All @@ -67,7 +67,6 @@
component:'button',
__dangerouslyBindEvalProps:{
onClick(count,setCount){
// someExternalCall(count+1)
setCount(count+1);
},
},
Expand Down
32 changes: 27 additions & 5 deletions dist/index.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.cjs.js.map

Large diffs are not rendered by default.

32 changes: 27 additions & 5 deletions dist/index.cjs.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2622,16 +2622,40 @@ function getReactFunctionComponent(reactComponent = {}, functionBody = "", optio
? functionComponent.call(this, ...functionArgs)
: functionComponent(...functionArgs);
}
/**
* Returns the string of a function, the difference between calling .toString() on a function definition is, the toString method will return the entire function definition (with paramaters and the name, etc)
* @param {Function} - The function you want the body string for
* @returns {String}
* @example
function myFunc(){
const a = 1;
const b = 3;
return a + b;
}
getFunctionBody(myFunc) => `
const a = 1;
const b = 3;
return a + b;
`
*/
function getFunctionBody(func) {
const functionString = func.toString();
if (functionString.includes('return') === false)
throw new EvalError('JSONX Function Components can not use implicit returns');
return functionString.substring(functionString.indexOf("{") + 1, functionString.lastIndexOf("}"));
}
/**
* A helpful function that lets you write a regular JavaScript function and passes the appropriate arguments to getReactFunctionComponent
* @param {Function} func - function definition to turn into React Component Function
* @property {object} this - options for getReactElementFromJSONX
* @returns {Function} - React Component Function
*/
function makeFunctionComponent(func, options) {
const scopedEval = eval;
const [functionBody, reactComponentString] = getFunctionBody(func).split('return');
const reactComponent = scopedEval(`(${reactComponentString})`);
const fullFunctionBody = getFunctionBody(func);
const [functionBody,] = fullFunctionBody.split('return');
let reactComponentString = fullFunctionBody.replace(functionBody, '').trim();
const reactComponent = scopedEval(`(()=>{${reactComponentString}})()`);
const functionOptions = { name: func.name, ...options };
return getReactFunctionComponent.call(this, reactComponent, functionBody, functionOptions);
}
Expand Down Expand Up @@ -11731,9 +11755,7 @@ ${jsonxRenderedString}`;
}
}

/**
* [[include:getting-started]]
*/
// import React, { createElement, } from 'react';
const createElement = React__default['default'].createElement;
const { componentMap, getComponentFromMap, getBoundedComponents, DynamicComponent, FormComponent, } = jsonxComponents;
const { getComputedProps } = jsonxProps;
Expand Down
32 changes: 27 additions & 5 deletions dist/index.esm.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.esm.js.map

Large diffs are not rendered by default.

32 changes: 27 additions & 5 deletions dist/index.esm.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2587,16 +2587,40 @@ function getReactFunctionComponent(reactComponent = {}, functionBody = "", optio
? functionComponent.call(this, ...functionArgs)
: functionComponent(...functionArgs);
}
/**
* Returns the string of a function, the difference between calling .toString() on a function definition is, the toString method will return the entire function definition (with paramaters and the name, etc)
* @param {Function} - The function you want the body string for
* @returns {String}
* @example
function myFunc(){
const a = 1;
const b = 3;
return a + b;
}
getFunctionBody(myFunc) => `
const a = 1;
const b = 3;
return a + b;
`
*/
function getFunctionBody(func) {
const functionString = func.toString();
if (functionString.includes('return') === false)
throw new EvalError('JSONX Function Components can not use implicit returns');
return functionString.substring(functionString.indexOf("{") + 1, functionString.lastIndexOf("}"));
}
/**
* A helpful function that lets you write a regular JavaScript function and passes the appropriate arguments to getReactFunctionComponent
* @param {Function} func - function definition to turn into React Component Function
* @property {object} this - options for getReactElementFromJSONX
* @returns {Function} - React Component Function
*/
function makeFunctionComponent(func, options) {
const scopedEval = eval;
const [functionBody, reactComponentString] = getFunctionBody(func).split('return');
const reactComponent = scopedEval(`(${reactComponentString})`);
const fullFunctionBody = getFunctionBody(func);
const [functionBody,] = fullFunctionBody.split('return');
let reactComponentString = fullFunctionBody.replace(functionBody, '').trim();
const reactComponent = scopedEval(`(()=>{${reactComponentString}})()`);
const functionOptions = { name: func.name, ...options };
return getReactFunctionComponent.call(this, reactComponent, functionBody, functionOptions);
}
Expand Down Expand Up @@ -11696,9 +11720,7 @@ ${jsonxRenderedString}`;
}
}

/**
* [[include:getting-started]]
*/
// import React, { createElement, } from 'react';
const createElement = React.createElement;
const { componentMap, getComponentFromMap, getBoundedComponents, DynamicComponent, FormComponent, } = jsonxComponents;
const { getComputedProps } = jsonxProps;
Expand Down
Loading

0 comments on commit 3e15f00

Please sign in to comment.