Browse Source

docs add jsx->js tab to live editors

main
Cheng Lou 11 years ago
parent
commit
353981f384
  1. 18
      _css/react.scss
  2. 7
      _js/examples/timer.js
  3. 120
      _js/live_editor.js
  4. 2
      _layouts/default.html

18
_css/react.scss

@ -580,6 +580,11 @@ div.CodeMirror-linenumber:after {
border: none;
}
/* hide the cursor. Mostly used when code's in plain JS */
.CodeMirror-readonly div.CodeMirror-cursor {
visibility: hidden;
}
small code,
li code,
p code {
@ -596,23 +601,28 @@ p code {
@include clearfix;
}
.playground::before {
.playground-tab {
border-bottom: none !important;
border-radius: 3px 3px 0 0;
padding: 3px 7px;
padding: 6px 8px;
font-size: 12px;
font-weight: bold;
color: #c2c0bc;
background-color: #f1ede4;
content: 'Live editor';
display: inline-block;
cursor: pointer;
}
.playground::before,
.playgroundCode,
.playground-tab,
.playgroundPreview {
border: 1px solid rgba(16,16,16,0.1);
}
.playground-tab-active {
color: $darkestColor;
}
.playgroundCode {
border-radius: 0 3px 3px 3px;
float: left;

7
_js/examples/timer.js

@ -3,6 +3,7 @@
*/
var TIMER_COMPONENT = "\
/** @jsx React.DOM */\n\
var Timer = React.createClass({\n\
getInitialState: function() {\n\
return {secondsElapsed: 0};\n\
@ -17,13 +18,13 @@ var Timer = React.createClass({\n\
clearInterval(this.interval);\n\
},\n\
render: function() {\n\
return React.DOM.div({},\n\
'Seconds Elapsed: ', this.state.secondsElapsed\n\
return (\n\
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>\n\
);\n\
}\n\
});\n\
\n\
React.renderComponent(Timer({}), mountNode);\
React.renderComponent(<Timer />, mountNode);\
";
React.renderComponent(

120
_js/live_editor.js

@ -14,10 +14,9 @@ var IS_MOBILE = (
);
var CodeMirrorEditor = React.createClass({
componentDidMount: function(root) {
if (IS_MOBILE) {
return;
}
componentDidMount: function() {
if (IS_MOBILE) return;
this.editor = CodeMirror.fromTextArea(this.refs.editor.getDOMNode(), {
mode: 'javascript',
lineNumbers: false,
@ -26,15 +25,21 @@ var CodeMirrorEditor = React.createClass({
theme: 'solarized-light',
readOnly: this.props.readOnly
});
this.editor.on('change', this.onChange);
this.onChange();
this.editor.on('change', this.handleChange);
},
componentDidUpdate: function() {
if (this.props.readOnly) {
this.editor.setValue(this.props.codeText);
}
},
onChange: function() {
if (this.props.onChange) {
var content = this.editor.getValue();
this.props.onChange(content);
handleChange: function() {
if (!this.props.readOnly) {
this.props.onChange && this.props.onChange(this.editor.getValue());
}
},
render: function() {
// wrap in a div to fully contain CodeMirror
var editor;
@ -46,7 +51,7 @@ var CodeMirrorEditor = React.createClass({
}
return (
<div className={this.props.className}>
<div style={this.props.style} className={this.props.className}>
{editor}
</div>
);
@ -67,7 +72,7 @@ var selfCleaningTimeout = {
var ReactPlayground = React.createClass({
mixins: [selfCleaningTimeout],
MODES: {XJS: 'XJS', JS: 'JS'}, //keyMirror({XJS: true, JS: true}),
MODES: {JSX: 'JSX', JS: 'JS'}, //keyMirror({JSX: true, JS: true}),
propTypes: {
codeText: React.PropTypes.string.isRequired,
@ -84,15 +89,19 @@ var ReactPlayground = React.createClass({
},
getInitialState: function() {
return {mode: this.MODES.XJS, code: this.props.codeText};
return {
mode: this.MODES.JSX,
code: this.props.codeText,
};
},
bindState: function(name) {
return function(value) {
var newState = {};
newState[name] = value;
this.setState(newState);
}.bind(this);
handleCodeChange: function(value) {
this.setState({code: value});
this.executeCode();
},
handleCodeModeSwitch: function(mode) {
this.setState({mode: mode});
},
compileCode: function() {
@ -100,25 +109,53 @@ var ReactPlayground = React.createClass({
},
render: function() {
var content;
if (this.state.mode === this.MODES.XJS) {
content =
<CodeMirrorEditor
onChange={this.bindState('code')}
className="playgroundStage"
codeText={this.state.code}
/>;
} else if (this.state.mode === this.MODES.JS) {
content =
<div className="playgroundJS playgroundStage">
{this.compileCode()}
</div>;
}
var isJS = this.state.mode === this.MODES.JS;
var compiledCode = '';
try {
compiledCode = this.compileCode();
} catch (err) {}
// we're creating both versions, to avoid the flicker when switching from
// one view to another when CodeMirror recompiles
var jsContent =
<CodeMirrorEditor
style={{display: isJS ? 'inherit' : 'none'}}
className="playgroundStage CodeMirror-readonly"
onChange={this.handleCodeChange}
codeText={compiledCode}
readOnly={true}
/>;
var jsxContent =
<CodeMirrorEditor
style={{display: isJS ? 'none' : 'inherit'}}
onChange={this.handleCodeChange}
className="playgroundStage"
codeText={this.state.code}
/>;
var JSXTabClassName =
'playground-tab' + (isJS ? '' : ' playground-tab-active');
var JSTabClassName =
'playground-tab' + (isJS ? ' playground-tab-active' : '');
return (
<div className="playground">
<div>
<div
className={JSXTabClassName}
onClick={this.handleCodeModeSwitch.bind(this, this.MODES.JSX)}>
Live JSX Editor
</div>
<div
className={JSTabClassName}
onClick={this.handleCodeModeSwitch.bind(this, this.MODES.JS)}>
Compiled JS
</div>
</div>
<div className="playgroundCode">
{content}
{jsxContent}
{jsContent}
</div>
<div className="playgroundPreview">
<div ref="mount" />
@ -126,12 +163,19 @@ var ReactPlayground = React.createClass({
</div>
);
},
componentDidMount: function() {
this.executeCode();
},
componentDidUpdate: function() {
this.executeCode();
componentWillUpdate: function(nextProps, nextState) {
// execute code only when the state's not being updated by switching tab
// this avoids re-displaying the error, which comes after a certain delay
if (this.state.mode === nextState.mode) {
this.executeCode();
};
},
executeCode: function() {
var mountNode = this.refs.mount.getDOMNode();
@ -149,10 +193,10 @@ var ReactPlayground = React.createClass({
} else {
eval(compiledCode);
}
} catch (e) {
} catch (err) {
this.setTimeout(function() {
React.renderComponent(
<div className="playgroundError">{e.toString()}</div>,
<div className="playgroundError">{err.toString()}</div>,
mountNode
);
}, 500);

2
_layouts/default.html

@ -16,9 +16,9 @@
<link rel="shortcut icon" href="/react/favicon.ico">
<link rel="alternate" type="application/rss+xml" title="{{ site.name }}" href="{{ site.url }}{{ site.baseurl }}/feed.xml">
<link rel="stylesheet" href="/react/css/react.css">
<link rel="stylesheet" href="/react/css/syntax.css">
<link rel="stylesheet" href="/react/css/codemirror.css">
<link rel="stylesheet" href="/react/css/react.css">
<script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>

Loading…
Cancel
Save