Skip to content

Commit

Permalink
Merge pull request #226 from FormidableLabs/issue/220-no-component-wi…
Browse files Browse the repository at this point in the history
…ll-mount

Move LiveProvider to hooks, fixes #220
  • Loading branch information
jpdriver committed Jun 27, 2021
2 parents 1b93fc5 + b9385d9 commit edba11c
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 104 deletions.
2 changes: 2 additions & 0 deletions demo/next.config.js
Expand Up @@ -4,6 +4,8 @@ module.exports = {
reactStrictMode: true,
webpack: config => {
config.resolve.alias['react-live'] = path.resolve('../');
config.resolve.alias.react = path.resolve('./node_modules/react');
config.resolve.alias['react-dom'] = path.resolve('./node_modules/react-dom');

return config;
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -51,8 +51,8 @@
"eslint-plugin-react": "^7.7.0",
"jest": "^22.2.1",
"prettier": "^1.17.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react": "^16.8.0",
"react-dom": "^16.8.0",
"rollup": "^0.55.3",
"rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^8.3.0",
Expand Down
12 changes: 2 additions & 10 deletions src/components/Editor/index.js
Expand Up @@ -7,7 +7,7 @@ import { theme as liveTheme } from '../../constants/theme';
class CodeEditor extends Component {
static propTypes = {
code: PropTypes.string,
disabled: PropTypes.boolean,
disabled: PropTypes.bool,
language: PropTypes.string,
onChange: PropTypes.func,
style: PropTypes.object,
Expand Down Expand Up @@ -58,15 +58,7 @@ class CodeEditor extends Component {
);

render() {
// eslint-disable-next-line no-unused-vars
const {
style,
code: _code,
onChange,
language,
theme,
...rest
} = this.props;
const { style, theme, ...rest } = this.props;
const { code } = this.state;

const baseTheme =
Expand Down
5 changes: 5 additions & 0 deletions src/components/Live/LivePreview.js
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import LiveContext from './LiveContext';

function LivePreview({ Component, ...rest }) {
Expand All @@ -11,6 +12,10 @@ function LivePreview({ Component, ...rest }) {
);
}

LivePreview.propTypes = {
Component: PropTypes.node
};

LivePreview.defaultProps = {
Component: 'div'
};
Expand Down
145 changes: 65 additions & 80 deletions src/components/Live/LiveProvider.js
@@ -1,104 +1,89 @@
import React, { Component } from 'react';
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';

import LiveContext from './LiveContext';
import { generateElement, renderElementAsync } from '../../utils/transpile';

export default class LiveProvider extends Component {
static defaultProps = {
code: '',
noInline: false,
language: 'jsx',
disabled: false
};
function LiveProvider({
children,
code,
language,
theme,
disabled,
scope,
transformCode,
noInline = false
}) {
const [state, setState] = useState({
error: undefined,
element: undefined
});

static propTypes = {
children: PropTypes.children,
code: PropTypes.string,
disabled: PropTypes.bool,
language: PropTypes.string,
noInline: PropTypes.bool,
scope: PropTypes.object,
theme: PropTypes.object,
transformCode: PropTypes.node
};

// eslint-disable-next-line camelcase
UNSAFE_componentWillMount() {
const { code, scope, transformCode, noInline } = this.props;

this.transpile({ code, scope, transformCode, noInline });
}

componentDidUpdate({
code: prevCode,
scope: prevScope,
noInline: prevNoInline,
transformCode: prevTransformCode
}) {
const { code, scope, noInline, transformCode } = this.props;
if (
code !== prevCode ||
scope !== prevScope ||
noInline !== prevNoInline ||
transformCode !== prevTransformCode
) {
this.transpile({ code, scope, transformCode, noInline });
}
}

onChange = code => {
const { scope, transformCode, noInline } = this.props;
this.transpile({ code, scope, transformCode, noInline });
};

onError = error => {
this.setState({ error: error.toString() });
};

transpile = ({ code, scope, transformCode, noInline = false }) => {
function transpile(newCode) {
// Transpilation arguments
const input = {
code: transformCode ? transformCode(code) : code,
code: transformCode ? transformCode(newCode) : newCode,
scope
};

const errorCallback = err =>
this.setState({ element: undefined, error: err.toString() });
const renderElement = element => this.setState({ ...state, element });
const errorCallback = error =>
setState({ error: error.toString(), element: undefined });

// State reset object
const state = { unsafeWrapperError: undefined, error: undefined };
const renderElement = element => setState({ error: undefined, element });

try {
if (noInline) {
this.setState({ ...state, element: null }); // Reset output for async (no inline) evaluation
setState({ error: undefined, element: null }); // Reset output for async (no inline) evaluation
renderElementAsync(input, renderElement, errorCallback);
} else {
renderElement(generateElement(input, errorCallback));
}
} catch (error) {
this.setState({ ...state, error: error.toString() });
errorCallback(error);
}
};
}

render() {
const { children, code, language, theme, disabled } = this.props;
useEffect(() => {
transpile(code);
}, [code, scope, noInline, transformCode]);

return (
<LiveContext.Provider
value={{
...this.state,
code,
language,
theme,
disabled,
onError: this.onError,
onChange: this.onChange
}}
>
{children}
</LiveContext.Provider>
);
}
const onChange = newCode => transpile(newCode);

const onError = error => setState({ error: error.toString() });

return (
<LiveContext.Provider
value={{
...state,
code,
language,
theme,
disabled,
onError,
onChange
}}
>
{children}
</LiveContext.Provider>
);
}

LiveProvider.propTypes = {
children: PropTypes.node,
code: PropTypes.string,
disabled: PropTypes.bool,
language: PropTypes.string,
noInline: PropTypes.bool,
scope: PropTypes.object,
theme: PropTypes.object,
transformCode: PropTypes.func
};

LiveProvider.defaultProps = {
code: '',
noInline: false,
language: 'jsx',
disabled: false
};

export default LiveProvider;
6 changes: 3 additions & 3 deletions stories/Live.js
Expand Up @@ -62,9 +62,9 @@ function LikeButton() {
return (
<>
<p class="likes">{likes} likes</p>
<p className="likes">{likes} likes</p>
<button
class="button"
className="button"
onClick={() => increaseLikes(likes + 1)} />
</>
)
Expand Down Expand Up @@ -139,7 +139,7 @@ const TestComponent = ({ live }) => {
return (
<Container>
<StyledEditor />
<Result />
{Result && <Result />}
<pre>{live.error}</pre>
</Container>
);
Expand Down
26 changes: 17 additions & 9 deletions yarn.lock
Expand Up @@ -7875,15 +7875,15 @@ react-docgen@^3.0.0-beta11:
node-dir "^0.1.10"
recast "^0.16.0"

react-dom@^16.2.0:
version "16.9.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.9.0.tgz#5e65527a5e26f22ae3701131bcccaee9fb0d3962"
integrity sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==
react-dom@^16.8.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.15.0"
scheduler "^0.19.1"

react-error-overlay@^4.0.1:
version "4.0.1"
Expand Down Expand Up @@ -8013,10 +8013,10 @@ react-treebeard@^2.1.0:
shallowequal "^0.2.2"
velocity-react "^1.3.1"

react@^16.2.0:
version "16.9.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa"
integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==
react@^16.8.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
Expand Down Expand Up @@ -8647,6 +8647,14 @@ scheduler@^0.15.0:
loose-envify "^1.1.0"
object-assign "^4.1.1"

scheduler@^0.19.1:
version "0.19.1"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"

schema-utils@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
Expand Down

0 comments on commit edba11c

Please sign in to comment.