add tabs to playground
This commit is contained in:
parent
e646677554
commit
a62b54c520
14
index.html
14
index.html
|
@ -3,12 +3,24 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>React templates - Image Search Sample</title>
|
||||
|
||||
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
|
||||
<!-- Optional theme -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
|
||||
|
||||
<link rel="stylesheet" href="playground/playground.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="playground">
|
||||
</div>
|
||||
<script src="playground/main.browser.js"></script>
|
||||
<!--<script src="playground/bundle/reactTemplates.bundle.js"></script>-->
|
||||
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
|
||||
<script src="playground/bundle/main.browser.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Created by avim on 11/25/2014.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var brace = require('brace');
|
||||
|
@ -11,29 +11,29 @@ require('brace/mode/html');
|
|||
require('brace/theme/monokai');
|
||||
|
||||
var editor = React.createClass({
|
||||
diplayName:"BraceEditor",
|
||||
displayName: 'BraceEditor',
|
||||
getInitialState: function () {
|
||||
return {
|
||||
editorId: _.uniqueId()
|
||||
}
|
||||
};
|
||||
},
|
||||
componentWillMount: function () {
|
||||
|
||||
},
|
||||
render: function () {
|
||||
var props = _.omit(this.props,['id','ref','key','value','valueLink','onChange']);
|
||||
var props = _.omit(this.props, ['id', 'ref', 'key', 'value', 'valueLink', 'onChange']);
|
||||
props.id = this.state.editorId;
|
||||
return React.DOM.div(props)
|
||||
return React.DOM.div(props);
|
||||
},
|
||||
componentWillUpdate: function (nextProps, nextState) {
|
||||
var value = nextProps.valueLink?nextProps.valueLink():nextProps.value;
|
||||
if (this.editor && this.editor.getValue() != value ) {
|
||||
this.editor.setValue(value,0);
|
||||
componentWillUpdate: function (nextProps/*, nextState*/) {
|
||||
var value = nextProps.valueLink ? nextProps.valueLink() : nextProps.value;
|
||||
if (this.editor && this.editor.getValue() != value) {
|
||||
this.editor.setValue(value, 0);
|
||||
}
|
||||
},
|
||||
componentDidMount: function () {
|
||||
this.editor = brace.edit(this.state.editorId);
|
||||
if (this.props.mode !== "html") {
|
||||
if (this.props.mode !== 'html') {
|
||||
this.editor.getSession().setMode('ace/mode/javascript');
|
||||
} else {
|
||||
this.editor.getSession().setMode('ace/mode/html');
|
||||
|
@ -41,17 +41,17 @@ var editor = React.createClass({
|
|||
this.editor.getSession().setUseWorker(false);
|
||||
this.editor.setTheme('ace/theme/monokai');
|
||||
|
||||
var value = this.props.valueLink?this.props.valueLink():this.props.value;
|
||||
this.editor.setValue(value,0);
|
||||
var value = this.props.valueLink ? this.props.valueLink() : this.props.value;
|
||||
this.editor.setValue(value, 0);
|
||||
if (this.props.readOnly) {
|
||||
this.editor.setReadOnly(true);
|
||||
} else {
|
||||
this.editor.setReadOnly(false);
|
||||
this.editor.on("change", function(e) {
|
||||
this.editor.on('change', function (/*e*/) {
|
||||
if (this.props.valueLink) {
|
||||
this.props.valueLink(this.editor.getValue());
|
||||
} else if (this.props.onChange) {
|
||||
this.props.onChange({target:{value:this.editor.getValue()}});
|
||||
this.props.onChange({target: {value: this.editor.getValue()}});
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
|
|
@ -57,7 +57,19 @@ function generateRenderFunc(renderFunc) {
|
|||
};
|
||||
}
|
||||
var z = {getInitialState: function() {return {name: 'reactTemplates'};}};
|
||||
var templateHTML = "<div>\n Have {_.filter(this.state.todos, {done:true}).length} todos done,\n and {_.filter(this.state.todos, {done:false}).length} not done\n <br/>\n <div rt-repeat=\"todo in this.state.todos\" key=\"{todo.key}\">\n <button onClick=\"(e)=>e.preventDefault(); this.remove(todo)\">x</button>\n <input type=\"checkbox\" checked=\"{todo.done}\" onChange=\"()=>this.toggleChecked(todoIndex)\"/>\n <span style=\"text-decoration: {todo.done ? 'line-through': 'none'}\">{todo.value}</span>\n </div>\n <input key=\"myinput\" type=\"text\" onKeyDown=\"(e) => if (e.keyCode == 13) { this.add(); }\" valueLink=\"{this.linkState('edited')}\"/>\n <button onClick=\"(e)=>e.preventDefault(); this.add()\" >Add</button><br/>\n <button onClick=\"(e)=>e.preventDefault(); this.clearDone()\">Clear done</button>\n</div>";
|
||||
var templateHTML = '<div>\n' +
|
||||
'Have {_.filter(this.state.todos, {done:true}).length} todos done,\n' +
|
||||
'and {_.filter(this.state.todos, {done:false}).length} not done\n' +
|
||||
' <br/>\n' +
|
||||
' <div rt-repeat="todo in this.state.todos" key="{todo.key}">\n' +
|
||||
' <button onClick="()=>this.remove(todo)">x</button>\n' +
|
||||
' <input type="checkbox" checked="{todo.done}" onChange="()=>this.toggleChecked(todoIndex)"/>\n' +
|
||||
' <span style="text-decoration: {todo.done ? \'line-through\': \'none\'}">{todo.value}</span>\n' +
|
||||
' </div>\n' +
|
||||
' <input key="myinput" type="text" onKeyDown="(e) => if (e.keyCode == 13) { e.preventDefault(); this.add(); }" valueLink="{this.linkState(\'edited\')}"/>\n' +
|
||||
' <button onClick="()=>this.add()">Add</button><br/>\n' +
|
||||
' <button onClick="()=>this.clearDone()">Clear done</button>\n' +
|
||||
'</div>';
|
||||
var templateProps = "{\n mixins: [React.addons.LinkedStateMixin],\n getInitialState: function () {\n return {edited: '', todos: [], counter: 0};\n },\n add: function () {\n if (this.state.edited.trim().length === 0) {\n return;\n }\n var newTodo = {value: this.state.edited, done: false, key: this.state.counter};\n this.setState({todos: this.state.todos.concat(newTodo), edited: '', counter: this.state.counter + 1});\n },\n remove: function (todo) {\n this.setState({todos: _.reject(this.state.todos, todo)});\n },\n toggleChecked: function (index) {\n var todos = _.cloneDeep(this.state.todos);\n todos[index].done = !todos[index].done;\n this.setState({todos: todos});\n },\n clearDone: function () {\n this.setState({todos: _.filter(this.state.todos, {done: false})});\n }\n}";
|
||||
|
||||
var Playground = React.createClass({
|
||||
|
|
|
@ -1,24 +1,41 @@
|
|||
.hidden {
|
||||
display:none;
|
||||
/*.hidden {*/
|
||||
/*display: none;*/
|
||||
/*}*/
|
||||
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.hiddenTab {
|
||||
/*width: 0;*/
|
||||
/*height: 0;*/
|
||||
}
|
||||
|
||||
.large-text-area {
|
||||
height:300px;
|
||||
height: 400px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.code-area {
|
||||
width: 50%;
|
||||
height:620px;
|
||||
float:left;
|
||||
height: 620px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.result-area {
|
||||
width: 50%;
|
||||
height: 620px;
|
||||
float:left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.sample-view {
|
||||
margin:10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.sample-view button {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.sample-view input[type=checkbox] {
|
||||
margin-right: 5px;
|
||||
}
|
|
@ -1,35 +1,43 @@
|
|||
<!DOCTYPE rt CodeEditor="./aceEditor">
|
||||
<div>
|
||||
<div class="code-area">
|
||||
<h2>Template:</h2>
|
||||
<CodeEditor class="large-text-area" style="border: {this.validHTML? '1px solid black':'2px solid red'};"
|
||||
|
||||
value="{this.state.templateHTML}"
|
||||
mode="html"
|
||||
onChange="(evt) => this.setState({'templateHTML':evt.target.value})"
|
||||
/>
|
||||
<br/>
|
||||
<h2>Class:</h2>
|
||||
<CodeEditor class="large-text-area" style="border: {this.validProps? '1px solid black':'2px solid red'};"
|
||||
value="{this.state.templateProps}"
|
||||
mode="javascript"
|
||||
onChange="(evt) => this.setState({'templateProps':evt.target.value})"
|
||||
/>
|
||||
<div id="myTab" role="tabpanel" class="code-area">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#template" aria-controls="template" role="tab" data-toggle="tab">Template</a></li>
|
||||
<li role="presentation"><a href="#classCode" aria-controls="classCode" role="tab" data-toggle="tab">Class</a></li>
|
||||
<li role="presentation"><a href="#generatedCode" aria-controls="generatedCode" role="tab" data-toggle="tab">Generated code</a></li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="template">
|
||||
<CodeEditor class="large-text-area" style="border: {this.validHTML? '1px solid black':'2px solid red'};"
|
||||
value="{this.state.templateHTML}"
|
||||
mode="html"
|
||||
onChange="(evt) => this.setState({'templateHTML':evt.target.value})"
|
||||
/>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="classCode">
|
||||
<CodeEditor class="large-text-area" style="border: {this.validProps? '1px solid black':'2px solid red'};"
|
||||
value="{this.state.templateProps}"
|
||||
mode="javascript"
|
||||
onChange="(evt) => this.setState({'templateProps':evt.target.value})"
|
||||
/>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="generatedCode">
|
||||
<CodeEditor class="large-text-area" style="border:1px solid black;"
|
||||
value="{this.templateSource}"
|
||||
mode="javascript"
|
||||
readOnly="{true}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div key="result-area" class="result-area">
|
||||
<h2>Generated code:</h2>
|
||||
<CodeEditor class="large-text-area" style="border:1px solid black;"
|
||||
value="{this.templateSource}"
|
||||
mode="javascript"
|
||||
readOnly="{true}"
|
||||
/>
|
||||
<div key="result-area" class="result-area well">
|
||||
<br/>
|
||||
<h2>Preview:</h2>
|
||||
<div class="sample-view">
|
||||
<form class="sample-view" onSubmit="(e) => e.preventDefault();">
|
||||
<this.sample key="sample">
|
||||
</this.sample>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -8,27 +8,70 @@ function onChange1(evt) {
|
|||
function onChange2(evt) {
|
||||
this.setState({ 'templateProps': evt.target.value });
|
||||
}
|
||||
function onSubmit3(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
module.exports = function () {
|
||||
return React.DOM.div({}, React.DOM.div({ 'className': 'code-area' }, React.DOM.h2({}, 'Template:'), CodeEditor({
|
||||
return React.DOM.div({}, React.DOM.div({
|
||||
'id': 'myTab',
|
||||
'role': 'tabpanel',
|
||||
'className': 'code-area'
|
||||
} /* Nav tabs */, React.DOM.ul({
|
||||
'className': 'nav nav-pills',
|
||||
'role': 'tablist'
|
||||
}, React.DOM.li({
|
||||
'role': 'presentation',
|
||||
'className': 'active'
|
||||
}, React.DOM.a({
|
||||
'href': '#template',
|
||||
'aria-controls': 'template',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Template')), React.DOM.li({ 'role': 'presentation' }, React.DOM.a({
|
||||
'href': '#classCode',
|
||||
'aria-controls': 'classCode',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Class')), React.DOM.li({ 'role': 'presentation' }, React.DOM.a({
|
||||
'href': '#generatedCode',
|
||||
'aria-controls': 'generatedCode',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Generated code'))) /* Tab panes */, React.DOM.div({ 'className': 'tab-content' }, React.DOM.div({
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane active',
|
||||
'id': 'template'
|
||||
}, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateHTML,
|
||||
'mode': 'html',
|
||||
'onChange': onChange1.bind(this)
|
||||
}), React.DOM.br({}), React.DOM.h2({}, 'Class:'), CodeEditor({
|
||||
})), React.DOM.div({
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane',
|
||||
'id': 'classCode'
|
||||
}, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateProps,
|
||||
'mode': 'javascript',
|
||||
'onChange': onChange2.bind(this)
|
||||
})), React.DOM.div({
|
||||
'key': 'result-area',
|
||||
'className': 'result-area'
|
||||
}, React.DOM.h2({}, 'Generated code:'), CodeEditor({
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane',
|
||||
'id': 'generatedCode'
|
||||
}, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: '1px solid black' },
|
||||
'value': this.templateSource,
|
||||
'mode': 'javascript',
|
||||
'readOnly': true
|
||||
}), React.DOM.br({}), React.DOM.h2({}, 'Preview:'), React.DOM.div({ 'className': 'sample-view' }, this.sample({ 'key': 'sample' }))));
|
||||
})))), React.DOM.div({
|
||||
'key': 'result-area',
|
||||
'className': 'result-area well'
|
||||
}, React.DOM.br({}), React.DOM.h2({}, 'Preview:'), React.DOM.form({
|
||||
'className': 'sample-view',
|
||||
'onSubmit': onSubmit3.bind(this)
|
||||
}, this.sample({ 'key': 'sample' }))));
|
||||
};
|
Loading…
Reference in New Issue