diff --git a/docs/api.md b/docs/api.md
index 74ce082..10c8c8e 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -85,3 +85,19 @@ Annotation map for the docClass. They key is the prop to annotate, the value is
scope={{React}}
/>
```
+
+### `onUpdate`
+*PropTypes.func*
+
+A function which gets called whenever the code updates after the initial render. The callback is fired with a single hash argument which looks like:
+
+```js
+{
+ code,
+ evalError
+}
+```
+
+`code` is the new code text.
+
+`evalError` will either be `null` (if there was no error) or the error object caught during attempted compilation and execution of the new code.
diff --git a/src/components/es6-preview.jsx b/src/components/es6-preview.jsx
index 37c20dc..280f4e4 100644
--- a/src/components/es6-preview.jsx
+++ b/src/components/es6-preview.jsx
@@ -84,7 +84,8 @@ class EsPreview extends Component {
static propTypes = {
code: PropTypes.string.isRequired,
- scope: PropTypes.object.isRequired
+ scope: PropTypes.object.isRequired,
+ onError: PropTypes.func.isRequired
};
_compileCode = () => {
@@ -152,7 +153,9 @@ class EsPreview extends Component {
}
}
render(, mountNode);
+ this.props.onError(null);
} catch (err) {
+ this.props.onError(err);
this._setTimeout(() => {
render(
{err.toString()}
,
diff --git a/src/components/playground.jsx b/src/components/playground.jsx
index 438761f..29a2b0f 100644
--- a/src/components/playground.jsx
+++ b/src/components/playground.jsx
@@ -30,7 +30,8 @@ class ReactPlayground extends Component {
es6Console: PropTypes.bool,
context: PropTypes.object,
initiallyExpanded: PropTypes.bool,
- previewComponent: PropTypes.node
+ previewComponent: PropTypes.node,
+ onUpdate: PropTypes.func
};
state = {
@@ -46,6 +47,15 @@ class ReactPlayground extends Component {
});
};
+ componentDidUpdate = (prevProps, prevState) => {
+ if (this.state.code !== prevState.code && this.props.onUpdate) {
+ this.props.onUpdate({
+ code: this.state.code,
+ evalError: this.previewError
+ });
+ }
+ };
+
_handleCodeChange = (code) => {
this.setState({
code,
@@ -53,6 +63,12 @@ class ReactPlayground extends Component {
});
};
+ _handlePreviewError = (error) => {
+ // error may be an error object, or null (if there was no problem).
+ // this callback is expected to run before componentDidUpdate.
+ this.previewError = error;
+ };
+
_toggleCode = () => {
this.setState({
expandedCode: !this.state.expandedCode
@@ -107,6 +123,7 @@ class ReactPlayground extends Component {
:
}
diff --git a/src/components/preview.jsx b/src/components/preview.jsx
index ffbb1ea..6ff6c0e 100644
--- a/src/components/preview.jsx
+++ b/src/components/preview.jsx
@@ -16,6 +16,7 @@ class Preview extends Component {
scope: PropTypes.object.isRequired,
previewComponent: PropTypes.node,
noRender: PropTypes.bool,
+ onError: PropTypes.func.isRequired,
context: PropTypes.object
};
@@ -90,10 +91,12 @@ class Preview extends Component {
}
/* eslint-enable no-eval, max-len */
clearTimeout(this.timeoutID);
+ this.props.onError(null);
this.setState({ error: null });
} catch (err) {
const error = err.toString();
clearTimeout(this.timeoutID); //eslint-disable-line no-undef
+ this.props.onError(err);
this.timeoutID = setTimeout(() => {
this.setState({ error });
}, 500);