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. 110
      _js/live_editor.js
  4. 2
      _layouts/default.html

18
_css/react.scss

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

7
_js/examples/timer.js

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

110
_js/live_editor.js

@ -14,10 +14,9 @@ var IS_MOBILE = (
); );
var CodeMirrorEditor = React.createClass({ var CodeMirrorEditor = React.createClass({
componentDidMount: function(root) { componentDidMount: function() {
if (IS_MOBILE) { if (IS_MOBILE) return;
return;
}
this.editor = CodeMirror.fromTextArea(this.refs.editor.getDOMNode(), { this.editor = CodeMirror.fromTextArea(this.refs.editor.getDOMNode(), {
mode: 'javascript', mode: 'javascript',
lineNumbers: false, lineNumbers: false,
@ -26,15 +25,21 @@ var CodeMirrorEditor = React.createClass({
theme: 'solarized-light', theme: 'solarized-light',
readOnly: this.props.readOnly readOnly: this.props.readOnly
}); });
this.editor.on('change', this.onChange); this.editor.on('change', this.handleChange);
this.onChange();
}, },
onChange: function() {
if (this.props.onChange) { componentDidUpdate: function() {
var content = this.editor.getValue(); if (this.props.readOnly) {
this.props.onChange(content); this.editor.setValue(this.props.codeText);
} }
}, },
handleChange: function() {
if (!this.props.readOnly) {
this.props.onChange && this.props.onChange(this.editor.getValue());
}
},
render: function() { render: function() {
// wrap in a div to fully contain CodeMirror // wrap in a div to fully contain CodeMirror
var editor; var editor;
@ -46,7 +51,7 @@ var CodeMirrorEditor = React.createClass({
} }
return ( return (
<div className={this.props.className}> <div style={this.props.style} className={this.props.className}>
{editor} {editor}
</div> </div>
); );
@ -67,7 +72,7 @@ var selfCleaningTimeout = {
var ReactPlayground = React.createClass({ var ReactPlayground = React.createClass({
mixins: [selfCleaningTimeout], mixins: [selfCleaningTimeout],
MODES: {XJS: 'XJS', JS: 'JS'}, //keyMirror({XJS: true, JS: true}), MODES: {JSX: 'JSX', JS: 'JS'}, //keyMirror({JSX: true, JS: true}),
propTypes: { propTypes: {
codeText: React.PropTypes.string.isRequired, codeText: React.PropTypes.string.isRequired,
@ -84,15 +89,19 @@ var ReactPlayground = React.createClass({
}, },
getInitialState: function() { getInitialState: function() {
return {mode: this.MODES.XJS, code: this.props.codeText}; return {
mode: this.MODES.JSX,
code: this.props.codeText,
};
},
handleCodeChange: function(value) {
this.setState({code: value});
this.executeCode();
}, },
bindState: function(name) { handleCodeModeSwitch: function(mode) {
return function(value) { this.setState({mode: mode});
var newState = {};
newState[name] = value;
this.setState(newState);
}.bind(this);
}, },
compileCode: function() { compileCode: function() {
@ -100,25 +109,53 @@ var ReactPlayground = React.createClass({
}, },
render: function() { render: function() {
var content; var isJS = this.state.mode === this.MODES.JS;
if (this.state.mode === this.MODES.XJS) { var compiledCode = '';
content = 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 <CodeMirrorEditor
onChange={this.bindState('code')} style={{display: isJS ? 'none' : 'inherit'}}
onChange={this.handleCodeChange}
className="playgroundStage" className="playgroundStage"
codeText={this.state.code} codeText={this.state.code}
/>; />;
} else if (this.state.mode === this.MODES.JS) {
content = var JSXTabClassName =
<div className="playgroundJS playgroundStage"> 'playground-tab' + (isJS ? '' : ' playground-tab-active');
{this.compileCode()} var JSTabClassName =
</div>; 'playground-tab' + (isJS ? ' playground-tab-active' : '');
}
return ( return (
<div className="playground"> <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"> <div className="playgroundCode">
{content} {jsxContent}
{jsContent}
</div> </div>
<div className="playgroundPreview"> <div className="playgroundPreview">
<div ref="mount" /> <div ref="mount" />
@ -126,12 +163,19 @@ var ReactPlayground = React.createClass({
</div> </div>
); );
}, },
componentDidMount: function() { componentDidMount: function() {
this.executeCode(); this.executeCode();
}, },
componentDidUpdate: function() {
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(); this.executeCode();
};
}, },
executeCode: function() { executeCode: function() {
var mountNode = this.refs.mount.getDOMNode(); var mountNode = this.refs.mount.getDOMNode();
@ -149,10 +193,10 @@ var ReactPlayground = React.createClass({
} else { } else {
eval(compiledCode); eval(compiledCode);
} }
} catch (e) { } catch (err) {
this.setTimeout(function() { this.setTimeout(function() {
React.renderComponent( React.renderComponent(
<div className="playgroundError">{e.toString()}</div>, <div className="playgroundError">{err.toString()}</div>,
mountNode mountNode
); );
}, 500); }, 500);

2
_layouts/default.html

@ -16,9 +16,9 @@
<link rel="shortcut icon" href="/react/favicon.ico"> <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="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/syntax.css">
<link rel="stylesheet" href="/react/css/codemirror.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" src="//use.typekit.net/vqa1hcx.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script> <script type="text/javascript">try{Typekit.load();}catch(e){}</script>

Loading…
Cancel
Save