UNPKG

string-to-react-component

Version:

Dynamically create and render React components from strings at runtime, converting strings to React components for flexible UI generation.

183 lines (175 loc) 7.15 kB
/** * string-to-react-component - Dynamically create and render React components from strings at runtime, converting strings to React components for flexible UI generation. * * @version v4.0.1 * @homepage https://github.com/dev-javascript/string-to-react-component/ * @author dev-javascript javascript.code.dev@gmail.com * @license MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react'), require('@babel/standalone')) : typeof define === 'function' && define.amd ? define(['react', '@babel/standalone'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.StringToReactComponent = factory(global.React, global.Babel)); })(this, (function (React, Babel) { 'use strict'; function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var Babel__namespace = /*#__PURE__*/_interopNamespaceDefault(Babel); var Ctx = /*#__PURE__*/function () { function Ctx(React, Babel, rerender) { this._temp = ''; this._blob = undefined; this._rerender = function () {}; this._com = function () { return null; }; this._rerender = rerender; this._getReact = function () { return React; }; if (!Babel) { throw new Error("Package \"string-to-react-component\" has a missing peer dependency of \"@babel/standalone\" ( requires \">=7.15.8\" )"); } this._getBabel = function () { return Babel; }; } var _proto = Ctx.prototype; _proto._checkBabelOptions = function _checkBabelOptions(babelOptions) { if (Object.prototype.toString.call(babelOptions) !== '[object Object]') { throw new Error("babelOptions prop of string-to-react-component element should be an object."); } if (Object.prototype.hasOwnProperty.call(babelOptions, 'sourceMaps') === false) { babelOptions.sourceMaps = 'inline'; } if (Object.prototype.hasOwnProperty.call(babelOptions, 'presets') === false) { babelOptions.presets = ['react']; } else { var _babelOptions$presets; //check if babelOptions.presets is not type of Array if (!(typeof babelOptions.presets === 'object' && ((_babelOptions$presets = babelOptions.presets) == null ? void 0 : _babelOptions$presets.constructor) == Array)) { throw new Error("string-to-react-component Error : presets property of babelOptions prop should be an array"); } if (babelOptions.presets.indexOf('react') === -1) { babelOptions.presets.push('react'); } } }; _proto._prependCode = function _prependCode(template) { this._temp = "import React from \"react\";\nexport default " + template; return this; }; _proto._postpendCode = function _postpendCode() { return this._temp.replace('export default', 'export default (React)=>').replace('import React from "react";', '//import React from "react";'); }; _proto._getBlob = function _getBlob(temp) { return new Blob([temp], { type: 'application/javascript' }); }; _proto._import = function _import(url) { return import( /* webpackIgnore: true */url); }; _proto._getModule = function _getModule(blob) { var _this = this; var moduleUrl = URL.createObjectURL(blob); return this._import(moduleUrl).then(function (module) { URL.revokeObjectURL(moduleUrl); return Promise.resolve(((module == null ? void 0 : module["default"]) || module)(_this._getReact())); })["catch"](function (error) { URL.revokeObjectURL(moduleUrl); var errorTitle = 'string-to-react-component loading module is failed:'; console.error(errorTitle, error); throw new Error(errorTitle); }); }; _proto._transpile = function _transpile(babelOptions) { this._checkBabelOptions(babelOptions); var resultObj = this._getBabel().transform(this._temp, babelOptions); var code = resultObj.code; // if (babelOptions.filename) { // code = resultObj.code + `\n//# sourceURL=${babelOptions.filename}`; // } this._temp = code || 'null'; return this; }; _proto._validateCodeInsideTheTemp = function _validateCodeInsideTheTemp(com) { if (typeof com !== 'function') { throw new Error("code inside the passed string into string-to-react-component, should be a function"); } }; _proto._validateTemplate = function _validateTemplate(temp) { if (typeof temp !== 'string') { throw new Error("passed child into string-to-react-component element should b a string"); } if (temp === '') { throw new Error("passed string into string-to-react-component element can not be empty"); } } /** update transpiled code */; _proto._updateTemplate = function _updateTemplate(template, babelOptions) { this._validateTemplate(template); return this._prependCode(template)._transpile(babelOptions)._postpendCode(); }; _proto.update = function update(template, babelOptions) { this._update(template, babelOptions); }; _proto._update = function _update(template, babelOptions) { this._updateComponent(this._updateTemplate(template, babelOptions)); }; _proto._onChangeComponent = function _onChangeComponent() { this._rerender({}); }; _proto._updateComponent = function _updateComponent(template) { var _this2 = this; this._getModule(this._getBlob(template)).then(function (com) { _this2._validateCodeInsideTheTemp(com); _this2._com = com; _this2._onChangeComponent(); }); }; _proto.getComponent = function getComponent() { return this._com; }; return Ctx; }(); function StringToReactComponent(deps, props) { var getCtx = deps.getCtx, Babel = deps.Babel, react = deps.react; var _useState = React.useState({}), rerender = _useState[1]; var ref = React.useRef(null); ref.current = ref.current || getCtx(react, Babel, rerender); var api = ref.current; var data = props.data || {}; React.useEffect(function () { api.update(props.children || '()=>null', props.babelOptions || {}); }, [props.children, props.babelOptions]); var Com = api.getComponent(); return /*#__PURE__*/React.createElement(Com, data); } var getCtx = function getCtx(React, Babel, rerender) { return new Ctx(React, Babel, rerender); }; var index = StringToReactComponent.bind(null, { getCtx: getCtx, Babel: Babel__namespace, react: React }); return index; })); //# sourceMappingURL=stringToReactComponent.umd.js.map