mirror of
https://github.com/bobwen-dev/react-templates
synced 2025-04-12 00:56:39 +02:00
add tabs to playground
This commit is contained in:
parent
e646677554
commit
a62b54c520
14
index.html
14
index.html
@ -3,12 +3,24 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>React templates - Image Search Sample</title>
|
<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"/>
|
<link rel="stylesheet" href="playground/playground.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="playground">
|
<div id="playground">
|
||||||
</div>
|
</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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Created by avim on 11/25/2014.
|
* Created by avim on 11/25/2014.
|
||||||
*/
|
*/
|
||||||
|
'use strict';
|
||||||
var React = require('react/addons');
|
var React = require('react/addons');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var brace = require('brace');
|
var brace = require('brace');
|
||||||
@ -11,29 +11,29 @@ require('brace/mode/html');
|
|||||||
require('brace/theme/monokai');
|
require('brace/theme/monokai');
|
||||||
|
|
||||||
var editor = React.createClass({
|
var editor = React.createClass({
|
||||||
diplayName:"BraceEditor",
|
displayName: 'BraceEditor',
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
editorId: _.uniqueId()
|
editorId: _.uniqueId()
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
componentWillMount: function () {
|
componentWillMount: function () {
|
||||||
|
|
||||||
},
|
},
|
||||||
render: 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;
|
props.id = this.state.editorId;
|
||||||
return React.DOM.div(props)
|
return React.DOM.div(props);
|
||||||
},
|
},
|
||||||
componentWillUpdate: function (nextProps, nextState) {
|
componentWillUpdate: function (nextProps/*, nextState*/) {
|
||||||
var value = nextProps.valueLink?nextProps.valueLink():nextProps.value;
|
var value = nextProps.valueLink ? nextProps.valueLink() : nextProps.value;
|
||||||
if (this.editor && this.editor.getValue() != value ) {
|
if (this.editor && this.editor.getValue() != value) {
|
||||||
this.editor.setValue(value,0);
|
this.editor.setValue(value, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
this.editor = brace.edit(this.state.editorId);
|
this.editor = brace.edit(this.state.editorId);
|
||||||
if (this.props.mode !== "html") {
|
if (this.props.mode !== 'html') {
|
||||||
this.editor.getSession().setMode('ace/mode/javascript');
|
this.editor.getSession().setMode('ace/mode/javascript');
|
||||||
} else {
|
} else {
|
||||||
this.editor.getSession().setMode('ace/mode/html');
|
this.editor.getSession().setMode('ace/mode/html');
|
||||||
@ -41,17 +41,17 @@ var editor = React.createClass({
|
|||||||
this.editor.getSession().setUseWorker(false);
|
this.editor.getSession().setUseWorker(false);
|
||||||
this.editor.setTheme('ace/theme/monokai');
|
this.editor.setTheme('ace/theme/monokai');
|
||||||
|
|
||||||
var value = this.props.valueLink?this.props.valueLink():this.props.value;
|
var value = this.props.valueLink ? this.props.valueLink() : this.props.value;
|
||||||
this.editor.setValue(value,0);
|
this.editor.setValue(value, 0);
|
||||||
if (this.props.readOnly) {
|
if (this.props.readOnly) {
|
||||||
this.editor.setReadOnly(true);
|
this.editor.setReadOnly(true);
|
||||||
} else {
|
} else {
|
||||||
this.editor.setReadOnly(false);
|
this.editor.setReadOnly(false);
|
||||||
this.editor.on("change", function(e) {
|
this.editor.on('change', function (/*e*/) {
|
||||||
if (this.props.valueLink) {
|
if (this.props.valueLink) {
|
||||||
this.props.valueLink(this.editor.getValue());
|
this.props.valueLink(this.editor.getValue());
|
||||||
} else if (this.props.onChange) {
|
} else if (this.props.onChange) {
|
||||||
this.props.onChange({target:{value:this.editor.getValue()}});
|
this.props.onChange({target: {value: this.editor.getValue()}});
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,19 @@ function generateRenderFunc(renderFunc) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
var z = {getInitialState: function() {return {name: 'reactTemplates'};}};
|
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 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({
|
var Playground = React.createClass({
|
||||||
|
@ -1,24 +1,41 @@
|
|||||||
.hidden {
|
/*.hidden {*/
|
||||||
display:none;
|
/*display: none;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hiddenTab {
|
||||||
|
/*width: 0;*/
|
||||||
|
/*height: 0;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.large-text-area {
|
.large-text-area {
|
||||||
height:300px;
|
height: 400px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-area {
|
.code-area {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
height:620px;
|
height: 620px;
|
||||||
float:left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-area {
|
.result-area {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
height: 620px;
|
height: 620px;
|
||||||
float:left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sample-view {
|
.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">
|
<!DOCTYPE rt CodeEditor="./aceEditor">
|
||||||
<div>
|
<div>
|
||||||
<div class="code-area">
|
<div id="myTab" role="tabpanel" class="code-area">
|
||||||
<h2>Template:</h2>
|
<!-- Nav tabs -->
|
||||||
<CodeEditor class="large-text-area" style="border: {this.validHTML? '1px solid black':'2px solid red'};"
|
<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>
|
||||||
value="{this.state.templateHTML}"
|
<li role="presentation"><a href="#classCode" aria-controls="classCode" role="tab" data-toggle="tab">Class</a></li>
|
||||||
mode="html"
|
<li role="presentation"><a href="#generatedCode" aria-controls="generatedCode" role="tab" data-toggle="tab">Generated code</a></li>
|
||||||
onChange="(evt) => this.setState({'templateHTML':evt.target.value})"
|
</ul>
|
||||||
/>
|
<!-- Tab panes -->
|
||||||
<br/>
|
<div class="tab-content">
|
||||||
<h2>Class:</h2>
|
<div role="tabpanel" class="tab-pane active" id="template">
|
||||||
<CodeEditor class="large-text-area" style="border: {this.validProps? '1px solid black':'2px solid red'};"
|
<CodeEditor class="large-text-area" style="border: {this.validHTML? '1px solid black':'2px solid red'};"
|
||||||
value="{this.state.templateProps}"
|
value="{this.state.templateHTML}"
|
||||||
mode="javascript"
|
mode="html"
|
||||||
onChange="(evt) => this.setState({'templateProps':evt.target.value})"
|
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>
|
||||||
<div key="result-area" class="result-area">
|
<div key="result-area" class="result-area well">
|
||||||
<h2>Generated code:</h2>
|
|
||||||
<CodeEditor class="large-text-area" style="border:1px solid black;"
|
|
||||||
value="{this.templateSource}"
|
|
||||||
mode="javascript"
|
|
||||||
readOnly="{true}"
|
|
||||||
/>
|
|
||||||
<br/>
|
<br/>
|
||||||
<h2>Preview:</h2>
|
<h2>Preview:</h2>
|
||||||
<div class="sample-view">
|
<form class="sample-view" onSubmit="(e) => e.preventDefault();">
|
||||||
<this.sample key="sample">
|
<this.sample key="sample">
|
||||||
</this.sample>
|
</this.sample>
|
||||||
</div>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,27 +8,70 @@ function onChange1(evt) {
|
|||||||
function onChange2(evt) {
|
function onChange2(evt) {
|
||||||
this.setState({ 'templateProps': evt.target.value });
|
this.setState({ 'templateProps': evt.target.value });
|
||||||
}
|
}
|
||||||
|
function onSubmit3(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
module.exports = function () {
|
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',
|
'className': 'large-text-area',
|
||||||
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
||||||
'value': this.state.templateHTML,
|
'value': this.state.templateHTML,
|
||||||
'mode': 'html',
|
'mode': 'html',
|
||||||
'onChange': onChange1.bind(this)
|
'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',
|
'className': 'large-text-area',
|
||||||
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
||||||
'value': this.state.templateProps,
|
'value': this.state.templateProps,
|
||||||
'mode': 'javascript',
|
'mode': 'javascript',
|
||||||
'onChange': onChange2.bind(this)
|
'onChange': onChange2.bind(this)
|
||||||
})), React.DOM.div({
|
})), React.DOM.div({
|
||||||
'key': 'result-area',
|
'role': 'tabpanel',
|
||||||
'className': 'result-area'
|
'className': 'tab-pane',
|
||||||
}, React.DOM.h2({}, 'Generated code:'), CodeEditor({
|
'id': 'generatedCode'
|
||||||
|
}, CodeEditor({
|
||||||
'className': 'large-text-area',
|
'className': 'large-text-area',
|
||||||
'style': { border: '1px solid black' },
|
'style': { border: '1px solid black' },
|
||||||
'value': this.templateSource,
|
'value': this.templateSource,
|
||||||
'mode': 'javascript',
|
'mode': 'javascript',
|
||||||
'readOnly': true
|
'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…
x
Reference in New Issue
Block a user