Skip to content

Commit 71b5853

Browse files
committed
docs add jsx->js tab to live editors
1 parent a05cef4 commit 71b5853

File tree

4 files changed

+101
-46
lines changed

4 files changed

+101
-46
lines changed

Diff for: docs/_css/react.scss

+14-4
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,11 @@ div.CodeMirror-linenumber:after {
580580
border: none;
581581
}
582582

583+
/* hide the cursor. Mostly used when code's in plain JS */
584+
.CodeMirror-readonly div.CodeMirror-cursor {
585+
visibility: hidden;
586+
}
587+
583588
small code,
584589
li code,
585590
p code {
@@ -596,23 +601,28 @@ p code {
596601
@include clearfix;
597602
}
598603

599-
.playground::before {
604+
.playground-tab {
600605
border-bottom: none !important;
601606
border-radius: 3px 3px 0 0;
602-
padding: 3px 7px;
607+
padding: 6px 8px;
603608
font-size: 12px;
604609
font-weight: bold;
605610
color: #c2c0bc;
606611
background-color: #f1ede4;
607-
content: 'Live editor';
612+
display: inline-block;
613+
cursor: pointer;
608614
}
609615

610-
.playground::before,
611616
.playgroundCode,
617+
.playground-tab,
612618
.playgroundPreview {
613619
border: 1px solid rgba(16,16,16,0.1);
614620
}
615621

622+
.playground-tab-active {
623+
color: $darkestColor;
624+
}
625+
616626
.playgroundCode {
617627
border-radius: 0 3px 3px 3px;
618628
float: left;

Diff for: docs/_js/examples/timer.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
var TIMER_COMPONENT = "\
6+
/** @jsx React.DOM */\n\
67
var Timer = React.createClass({\n\
78
getInitialState: function() {\n\
89
return {secondsElapsed: 0};\n\
@@ -17,13 +18,13 @@ var Timer = React.createClass({\n\
1718
clearInterval(this.interval);\n\
1819
},\n\
1920
render: function() {\n\
20-
return React.DOM.div({},\n\
21-
'Seconds Elapsed: ', this.state.secondsElapsed\n\
21+
return (\n\
22+
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>\n\
2223
);\n\
2324
}\n\
2425
});\n\
2526
\n\
26-
React.renderComponent(Timer({}), mountNode);\
27+
React.renderComponent(<Timer />, mountNode);\
2728
";
2829

2930
React.renderComponent(

Diff for: docs/_js/live_editor.js

+82-38
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ var IS_MOBILE = (
1414
);
1515

1616
var CodeMirrorEditor = React.createClass({
17-
componentDidMount: function(root) {
18-
if (IS_MOBILE) {
19-
return;
20-
}
17+
componentDidMount: function() {
18+
if (IS_MOBILE) return;
19+
2120
this.editor = CodeMirror.fromTextArea(this.refs.editor.getDOMNode(), {
2221
mode: 'javascript',
2322
lineNumbers: false,
@@ -26,15 +25,21 @@ var CodeMirrorEditor = React.createClass({
2625
theme: 'solarized-light',
2726
readOnly: this.props.readOnly
2827
});
29-
this.editor.on('change', this.onChange);
30-
this.onChange();
28+
this.editor.on('change', this.handleChange);
29+
},
30+
31+
componentDidUpdate: function() {
32+
if (this.props.readOnly) {
33+
this.editor.setValue(this.props.codeText);
34+
}
3135
},
32-
onChange: function() {
33-
if (this.props.onChange) {
34-
var content = this.editor.getValue();
35-
this.props.onChange(content);
36+
37+
handleChange: function() {
38+
if (!this.props.readOnly) {
39+
this.props.onChange && this.props.onChange(this.editor.getValue());
3640
}
3741
},
42+
3843
render: function() {
3944
// wrap in a div to fully contain CodeMirror
4045
var editor;
@@ -46,7 +51,7 @@ var CodeMirrorEditor = React.createClass({
4651
}
4752

4853
return (
49-
<div className={this.props.className}>
54+
<div style={this.props.style} className={this.props.className}>
5055
{editor}
5156
</div>
5257
);
@@ -67,7 +72,7 @@ var selfCleaningTimeout = {
6772
var ReactPlayground = React.createClass({
6873
mixins: [selfCleaningTimeout],
6974

70-
MODES: {XJS: 'XJS', JS: 'JS'}, //keyMirror({XJS: true, JS: true}),
75+
MODES: {JSX: 'JSX', JS: 'JS'}, //keyMirror({JSX: true, JS: true}),
7176

7277
propTypes: {
7378
codeText: React.PropTypes.string.isRequired,
@@ -84,54 +89,93 @@ var ReactPlayground = React.createClass({
8489
},
8590

8691
getInitialState: function() {
87-
return {mode: this.MODES.XJS, code: this.props.codeText};
92+
return {
93+
mode: this.MODES.JSX,
94+
code: this.props.codeText,
95+
};
8896
},
8997

90-
bindState: function(name) {
91-
return function(value) {
92-
var newState = {};
93-
newState[name] = value;
94-
this.setState(newState);
95-
}.bind(this);
98+
handleCodeChange: function(value) {
99+
this.setState({code: value});
100+
this.executeCode();
101+
},
102+
103+
handleCodeModeSwitch: function(mode) {
104+
this.setState({mode: mode});
96105
},
97106

98107
compileCode: function() {
99108
return this.props.transformer(this.state.code);
100109
},
101110

102111
render: function() {
103-
var content;
104-
if (this.state.mode === this.MODES.XJS) {
105-
content =
106-
<CodeMirrorEditor
107-
onChange={this.bindState('code')}
108-
className="playgroundStage"
109-
codeText={this.state.code}
110-
/>;
111-
} else if (this.state.mode === this.MODES.JS) {
112-
content =
113-
<div className="playgroundJS playgroundStage">
114-
{this.compileCode()}
115-
</div>;
116-
}
112+
var isJS = this.state.mode === this.MODES.JS;
113+
var compiledCode = '';
114+
try {
115+
compiledCode = this.compileCode();
116+
} catch (err) {}
117+
118+
// we're creating both versions, to avoid the flicker when switching from
119+
// one view to another when CodeMirror recompiles
120+
var jsContent =
121+
<CodeMirrorEditor
122+
style={{display: isJS ? 'inherit' : 'none'}}
123+
className="playgroundStage CodeMirror-readonly"
124+
onChange={this.handleCodeChange}
125+
codeText={compiledCode}
126+
readOnly={true}
127+
/>;
128+
129+
var jsxContent =
130+
<CodeMirrorEditor
131+
style={{display: isJS ? 'none' : 'inherit'}}
132+
onChange={this.handleCodeChange}
133+
className="playgroundStage"
134+
codeText={this.state.code}
135+
/>;
136+
137+
var JSXTabClassName =
138+
'playground-tab' + (isJS ? '' : ' playground-tab-active');
139+
var JSTabClassName =
140+
'playground-tab' + (isJS ? ' playground-tab-active' : '');
117141

118142
return (
119143
<div className="playground">
144+
<div>
145+
<div
146+
className={JSXTabClassName}
147+
onClick={this.handleCodeModeSwitch.bind(this, this.MODES.JSX)}>
148+
Live JSX Editor
149+
</div>
150+
<div
151+
className={JSTabClassName}
152+
onClick={this.handleCodeModeSwitch.bind(this, this.MODES.JS)}>
153+
Compiled JS
154+
</div>
155+
</div>
120156
<div className="playgroundCode">
121-
{content}
157+
{jsxContent}
158+
{jsContent}
122159
</div>
123160
<div className="playgroundPreview">
124161
<div ref="mount" />
125162
</div>
126163
</div>
127164
);
128165
},
166+
129167
componentDidMount: function() {
130168
this.executeCode();
131169
},
132-
componentDidUpdate: function() {
133-
this.executeCode();
170+
171+
componentWillUpdate: function(nextProps, nextState) {
172+
// execute code only when the state's not being updated by switching tab
173+
// this avoids re-displaying the error, which comes after a certain delay
174+
if (this.state.mode === nextState.mode) {
175+
this.executeCode();
176+
};
134177
},
178+
135179
executeCode: function() {
136180
var mountNode = this.refs.mount.getDOMNode();
137181

@@ -149,10 +193,10 @@ var ReactPlayground = React.createClass({
149193
} else {
150194
eval(compiledCode);
151195
}
152-
} catch (e) {
196+
} catch (err) {
153197
this.setTimeout(function() {
154198
React.renderComponent(
155-
<div className="playgroundError">{e.toString()}</div>,
199+
<div className="playgroundError">{err.toString()}</div>,
156200
mountNode
157201
);
158202
}, 500);

Diff for: docs/_layouts/default.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
<link rel="shortcut icon" href="/react/favicon.ico">
1717
<link rel="alternate" type="application/rss+xml" title="{{ site.name }}" href="{{ site.url }}{{ site.baseurl }}/feed.xml">
1818

19-
<link rel="stylesheet" href="/react/css/react.css">
2019
<link rel="stylesheet" href="/react/css/syntax.css">
2120
<link rel="stylesheet" href="/react/css/codemirror.css">
21+
<link rel="stylesheet" href="/react/css/react.css">
2222

2323
<script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script>
2424
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>

0 commit comments

Comments
 (0)