Replace React integration demo with proper documentationtags/v1.2.0
@@ -1,32 +0,0 @@ | |||
<link rel="stylesheet" href="../../elements-demo-resources/demo.css"> | |||
<script src="../../elements-demo-resources/ga.js"></script> | |||
<script> | |||
window.localUserUrl = 'users.json'; | |||
var bowerComponents = '../../'; | |||
window.xCodeExampleSourceHead = | |||
' <script src="https://cdn.vaadin.com/vaadin-core-elements/latest/webcomponentsjs/webcomponents-lite.js"><\/script>\n' + | |||
' <link href="https://cdn.vaadin.com/vaadin-core-elements/latest/vaadin-core-elements/vaadin-core-elements.html" rel="import">\n'; | |||
if (!window.Polymer) { | |||
var link = document.querySelector('link[href$="common.html"]'); | |||
var baseCommon = link.href.replace(/common.html/, ''); | |||
var base = baseCommon + bowerComponents; | |||
var polymerImport = document.createElement('link'); | |||
polymerImport.rel = 'import'; | |||
polymerImport.href = base + 'polymer/polymer.html'; | |||
polymerImport.onload = function() { | |||
window.localUserUrl = baseCommon + 'users.json'; | |||
Polymer.Base.importHref(base + 'code-example/code-example.html'); | |||
Polymer.Base.importHref(base + 'table-of-contents/table-of-contents.html'); | |||
Polymer.Base.importHref(base + 'vaadin-grid/vaadin-grid.html'); | |||
Polymer.Base.importHref(base + 'elements-demo-resources/getjson.html'); | |||
}; | |||
document.head.appendChild(polymerImport); | |||
} | |||
</script> |
@@ -1,56 +0,0 @@ | |||
<!doctype html> | |||
<html> | |||
<head> | |||
<title>Vaadin Core Elements Code Examples</title> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
<script src="../../marked/lib/marked.js"></script> | |||
<script src="../../code-example/vendor/prismjs/prism.js"></script> | |||
<link rel="stylesheet" href="../../code-example/vendor/prismjs/prism.css"> | |||
<link rel="stylesheet" href="../../elements-demo-resources/demo.css"> | |||
<style type="text/css"> | |||
#readme code { | |||
font-size: 12px; | |||
max-height: none !important; | |||
} | |||
</style> | |||
</head> | |||
<body> | |||
<section id="readme"> | |||
</section> | |||
<script> | |||
var readme = document.getElementById("readme"); | |||
var xhr = new XMLHttpRequest(); | |||
xhr.onload = function (e) { | |||
if (xhr.readyState === 4) { | |||
if (xhr.status === 200) { | |||
readme.innerHTML = marked(xhr.responseText); | |||
[].forEach.call(readme.querySelectorAll("pre"), function(pre) { | |||
var code = document.createElement("code"); | |||
code.innerHTML = pre.innerHTML; | |||
var parent = pre.parentElement; | |||
parent.insertBefore(code, pre); | |||
parent.removeChild(pre); | |||
code.className = "language-markup"; | |||
Prism.highlightElement(code); | |||
}); | |||
} else { | |||
console.error(xhr.statusText); | |||
} | |||
} | |||
}; | |||
xhr.onerror = function (e) { | |||
console.error(xhr.statusText); | |||
}; | |||
xhr.open("GET", "../README.md"); | |||
xhr.send(); | |||
</script> | |||
</body> | |||
</html> |
@@ -1,64 +0,0 @@ | |||
<!doctype html> | |||
<html> | |||
<head> | |||
<title>vaadin-grid Code Examples - React Integration</title> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
<script src="../../webcomponentsjs/webcomponents-lite.js"></script> | |||
<script src="js_dependencies/react.min.js"></script> | |||
<script src="js_dependencies/JSXTransformer.js"></script> | |||
<link rel="import" href="common.html"> | |||
<style> | |||
body { | |||
padding: 0; | |||
margin: 0; | |||
font-family: 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei New', 'Microsoft Yahei', SimSun, STXihei, sans-serif; | |||
} | |||
img.user-image { | |||
position: absolute; | |||
bottom: 0px; | |||
right: 0px; | |||
max-width: 33%; | |||
max-height: 33%; | |||
} | |||
</style> | |||
</head> | |||
<body style="padding: 0; margin: 0;"> | |||
<div id="reactdemo"></div> | |||
<script> | |||
(function wait() { | |||
// Wait for the polyfilled browsers to finish importing needed resources | |||
if (!document.querySelector('link[href$="vaadin-grid.html"]') || !window.getJSON) { | |||
return setTimeout(wait, 50); | |||
} | |||
// Want to avoid maintaining the React demo source in 2 places so we'll | |||
// evaluate the jsx code in react.html manually here | |||
var xhr = new XMLHttpRequest(); | |||
xhr.onreadystatechange = function() { | |||
if (xhr.readyState == XMLHttpRequest.DONE) { | |||
if (xhr.status == 200) { | |||
var text = xhr.responseText; | |||
var scriptTag = '<script type="text/jsx">'; | |||
var start = text.indexOf(scriptTag) + scriptTag.length; | |||
var end = text.indexOf('<\/script>', start); | |||
HTMLImports.whenReady(function() { | |||
JSXTransformer.exec(text.substr(start, end - start)); | |||
}); | |||
} | |||
} | |||
}; | |||
xhr.open('GET', 'react.html', true); | |||
xhr.send(); | |||
})(); | |||
</script> | |||
</body> | |||
</html> |
@@ -1,148 +0,0 @@ | |||
<!doctype html> | |||
<!-- | |||
title: Overview | |||
order: 1 | |||
layout: page | |||
--> | |||
<html> | |||
<head> | |||
<title>vaadin-core-elements Code Examples - React Integration</title> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
<script src="../../webcomponentsjs/webcomponents-lite.js"></script> | |||
<link rel="import" href="common.html"> | |||
</head> | |||
<body unresolved> | |||
<section> | |||
<h1>React Integration</h1> | |||
<p>This example demonstrates using vaadin-grid with React framework. | |||
As React doesn't support custom attributes for elements, | |||
vaadin-grid DOM API can't be fully utilized in the initialization.</p> | |||
<p>Fortunately vaadin-grid also provides corresponding JavaScript APIs.</p> | |||
<p><strong>Note:</strong> vaadin-grid is not a React component. Instead, it must be | |||
used with React like any JavaScript class. Please see the code example below or the | |||
<a href='https://facebook.github.io/react/docs/component-specs.html'>React documentation</a> | |||
for more information.</p> | |||
<code-example> | |||
<div demo> | |||
<div id="reactdemo"> | |||
</div> | |||
<script type="text/jsx"> | |||
// Create the UserGrid class | |||
var UserGrid = React.createClass({ | |||
render: function(){ | |||
return ( | |||
<vaadin-grid></vaadin-grid> | |||
) | |||
}, | |||
componentDidMount: function() { | |||
var _this = this; | |||
var vGrid = _this.getDOMNode(); | |||
// Let the mounted <vaadin-grid> upgrade | |||
(function wait() { | |||
if (vGrid.selection) { | |||
// Assign the data source | |||
vGrid.items = _this.items; | |||
vGrid.size = 1000; | |||
// Bind selection listener | |||
vGrid.addEventListener("selected-items-changed", _this.onRowSelect); | |||
var pictureRenderer = function(cell) { | |||
cell.element.innerHTML = "<img style='width: 30px' src='" + cell.data + "'></img>"; | |||
}; | |||
// Define columns | |||
vGrid.columns = [ | |||
{name: "user.picture.thumbnail", width: 100, renderer: pictureRenderer}, | |||
{name: "user.name.first"}, | |||
{name: "user.name.last"}, | |||
{name: "user.email"}, | |||
]; | |||
} else { | |||
setTimeout( wait, 50 ); | |||
} | |||
})(); | |||
}, | |||
items: function(params, callback) { | |||
var url = 'https://randomuser.me/api?index=' + params.index + '&results=' + params.count; | |||
getJSON(url, function(data) { | |||
callback(data.results); | |||
}); | |||
}, | |||
onRowSelect: function(e) { | |||
var onUserSelect = this.props.onUserSelect; | |||
var index = e.target.selection.selected()[0]; | |||
e.target.getItem(index, function(err, data) { | |||
onUserSelect(err ? undefined : data.user); | |||
}); | |||
} | |||
}); | |||
var UserApp = React.createClass({ | |||
render: function() { | |||
var userImage; | |||
if (this.state.selected) { | |||
userImage = <img className="user-image" src={this.state.selected.picture.large} ></img>; | |||
} | |||
return ( | |||
<div> | |||
<UserGrid onUserSelect={this.userSelect}></UserGrid> | |||
{userImage} | |||
</div> | |||
); | |||
}, | |||
getInitialState: function() { | |||
return {}; | |||
}, | |||
userSelect: function(user) { | |||
this.setState({selected: user}); | |||
} | |||
}); | |||
HTMLImports.whenReady(function(){ | |||
React.render(<UserApp></UserApp>, document.getElementById('reactdemo')); | |||
}); | |||
</script> | |||
</div> | |||
<code hidden> | |||
document.body.removeAttribute('unresolved'); | |||
</code> | |||
</code-example> | |||
<iframe id='react-embed' src='react-demo-embed.html' style='width: 100%; height: 550px; border: none; display: none;'></iframe> | |||
<script> | |||
var codeExample = document.querySelector("code-example"); | |||
(function wait() { | |||
if (codeExample.async) { | |||
codeExample.async(function() { | |||
var demo = document.querySelector("div[demo]"); | |||
var embed = document.getElementById("react-embed"); | |||
demo.innerHTML = ""; | |||
demo.appendChild(embed); | |||
embed.style.display = "block"; | |||
}); | |||
} else { | |||
setTimeout( wait, 50 ); | |||
} | |||
})(); | |||
</script> | |||
</section> | |||
</body> | |||
</html> |
@@ -0,0 +1,121 @@ | |||
--- | |||
title: React Integration | |||
order: 1 | |||
layout: page | |||
--- | |||
# React Integration | |||
The link:https://facebook.github.io/react/[React] library from Facebook easily integrates with web components. | |||
As long as you import required polyfills and add HTML imports for the elements you are using, you can simply start adding these custom elements to your JSX markup. | |||
ifdef::web[] | |||
==== | |||
See also the link:https://facebook.github.io/react/docs/webcomponents.html[Web Components page] in React documentation. | |||
==== | |||
endif::web[] | |||
## Grid Example | |||
[[figure.vaadin-grid.react]] | |||
.React integration example using [vaadinelement]#vaadin-grid# | |||
image::img/react-integration.png[] | |||
The example consists of two React components: [classname]#UserApp# and [classname]#UserGrid#. | |||
The [classname]#UserGrid# component wraps the [vaadinelement]#vaadin-grid# element and does all necessary initialization to display a list of random users. | |||
As React does not support link:https://facebook.github.io/react/docs/jsx-gotchas.html#custom-html-attributes[custom attributes] on standard elements, [vaadinelement]#vaadin-grid# DOM API cannot be fully utilized in the initialization. | |||
Fortunately, [vaadinelement]#vaadin-grid# also provides corresponding JavaScript APIs. | |||
Selecting an item in the [classname]#UserGrid# is handled by the [classname]#UserApp# component. | |||
The selection is handled by displaying the photo of the selected user below the [vaadinelement]#vaadin-grid#. | |||
The code below can be run and forked as a JSFiddle at https://jsfiddle.net/pw1nLaL8/2/. | |||
[source, javascript] | |||
---- | |||
// Create the UserGrid class | |||
var UserGrid = React.createClass({ | |||
render: function(){ | |||
return ( | |||
<vaadin-grid></vaadin-grid> | |||
) | |||
}, | |||
componentDidMount: function() { | |||
var _this = this; | |||
var vGrid = ReactDOM.findDOMNode(this); | |||
// Let the mounted <vaadin-grid> upgrade | |||
(function wait() { | |||
if (vGrid.selection) { | |||
// Assign the data source | |||
vGrid.items = _this.items; | |||
vGrid.size = 1000; | |||
// Bind selection listener | |||
vGrid.addEventListener("selected-items-changed", _this.onRowSelect); | |||
var pictureRenderer = function(cell) { | |||
cell.element.innerHTML = "<img style='width: 30px' src='" + cell.data + "'></img>"; | |||
}; | |||
// Define columns | |||
vGrid.columns = [ | |||
{name: "user.picture.thumbnail", width: 100, renderer: pictureRenderer}, | |||
{name: "user.name.first"}, | |||
{name: "user.name.last"}, | |||
{name: "user.email"}, | |||
]; | |||
} else { | |||
setTimeout(wait, 50); | |||
} | |||
})(); | |||
}, | |||
items: function(params, callback) { | |||
var url = 'https://randomuser.me/api?index=' + params.index + '&results=' + params.count; | |||
getJSON(url, function(data) { | |||
callback(data.results); | |||
}); | |||
}, | |||
onRowSelect: function(e) { | |||
var onUserSelect = this.props.onUserSelect; | |||
var index = e.target.selection.selected()[0]; | |||
e.target.getItem(index, function(err, data) { | |||
onUserSelect(err ? undefined : data.user); | |||
}); | |||
} | |||
}); | |||
var UserApp = React.createClass({ | |||
render: function() { | |||
var userImage; | |||
if (this.state.selected) { | |||
userImage = <img className="user-image" src={this.state.selected.picture.large} ></img>; | |||
} | |||
return ( | |||
<div> | |||
<UserGrid onUserSelect={this.userSelect}></UserGrid> | |||
{userImage} | |||
</div> | |||
); | |||
}, | |||
getInitialState: function() { | |||
return {}; | |||
}, | |||
userSelect: function(user) { | |||
this.setState({selected: user}); | |||
} | |||
}); | |||
HTMLImports.whenReady(function(){ | |||
ReactDOM.render(<UserApp></UserApp>, document.getElementById('container')); | |||
}); | |||
---- |
@@ -42,18 +42,9 @@ gulp.task('cdn:docsite:bower_components', ['cdn:stage-bower_components'], functi | |||
}); | |||
gulp.task('cdn:docsite:core-elements', function() { | |||
return gulp.src(['docs/*', '!docs/angular2.adoc']) | |||
.pipe(gulp.dest(docPath)); | |||
return gulp.src(['docs/**']).pipe(gulp.dest(docPath)); | |||
}); | |||
gulp.task('cdn:docsite:core-elements-ng2-integration', function() { | |||
return gulp.src('docs/angular2.adoc') | |||
.pipe(gulp.dest(docPath + '/integrations')); | |||
}); | |||
gulp.task('cdn:docsite:core-elements-integrations', function() { | |||
return getDocModifyTask('demo/**', docPath + '/integrations'); | |||
}); | |||
gulp.task('cdn:docsite:core-elements-elements', ['cdn:docsite:bower_components'], function() { | |||
var bowerJson = require('../' + stagingPath + '/bower.json'); | |||
@@ -68,52 +59,8 @@ gulp.task('cdn:docsite:core-elements-elements', ['cdn:docsite:bower_components'] | |||
.pipe(gulp.dest(docPath + '/')); | |||
}); | |||
function getDocModifyTask(sourceFiles, targetFolder, n) { | |||
fs.mkdirsSync(targetFolder); | |||
gutil.log('Generating site documentation from ' + sourceFiles + ' into ' + targetFolder); | |||
return gulp.src([sourceFiles, '!**/*-embed.html']) | |||
// Remove bad tags | |||
.pipe(replace(/^.*<(!doctype|\/?html|\/?head|\/?body|meta|title).*>.*\n/img, '')) | |||
// Uncomment metainfo, and enclose all the example in {% raw %} ... {% endraw %} to avoid liquid conflicts | |||
// We use gulp-modify instead of replace in order to handle the github url for this file | |||
.pipe(modify({ | |||
fileModifier: function(file, contents) { | |||
var re = new RegExp(".*/" + n + "/"); | |||
var gh = 'https://github.com/vaadin/' + n + '/edit/master/' + file.path.replace(re, ''); | |||
return contents.replace(/^.*<!--[ \n]+([\s\S]*?title:[\s\S]*?)[ \n]+-->.*\n([\s\S]*)/img, | |||
'---\n$1\nsourceurl: ' + gh + '\n---\n{% raw %}\n$2\n{% endraw %}'); | |||
} | |||
})) | |||
.pipe(replace(/^.*<section>[\s\S]*?table-of-contents[\s\S]*?<\/section>.*\n/im, '')) | |||
// Add ids to headers, so as site configures permalinks | |||
.pipe(replace(/<h(\d+)>(.*)(<\/h\d+>)/img, function($0, $1, $2, $3){ | |||
var id = $2.trim().toLowerCase().replace(/[^\w]+/g,'_'); | |||
return '<h' + $1 + ' id="' + id + '">' + $2 + $3; | |||
})) | |||
// Remove webcomponents polyfill since it's added at top of the site | |||
.pipe(replace(/^.*<script.*?\/webcomponents.*\.js[\"'].*?<\/script>\s*?\n?/img, '')) | |||
// embed files are displayed as iframe, we don't remove above fragments like body or polyfill | |||
.pipe(addsrc(sourceFiles + '/*-embed.html')) | |||
// Remove Analytics | |||
.pipe(replace(/^.*<script.*?ga\.js[\"'].*?<\/script>\s*?\n?/img, '')) | |||
// Adjust bowerComponents variable in common.html | |||
.pipe(replace(/(bowerComponents *= *)'..\/..\/'/, "$1'../bower_components/'")) | |||
// Adjust location of the current component in bower_components (..) | |||
.pipe(replace(/(src|href)=("|')\.\.(\/\w)/mg, '$1=$2../bower_components/' + n + '$3')) | |||
// Adjust location of dependencies in bower_components (../..) | |||
.pipe(replace(/(src|href)=("|')(.*?)\.\.\/\.\.\//mg, '$1=$2../bower_components/')) | |||
// Remove references to demo.css file | |||
.pipe(replace(/^.*<link.*demo.css.*\n/im, '')) | |||
// Remove table of contents | |||
.pipe(replace(/^.*table-of-contents.html.*\n/im, '')) | |||
.pipe(gulp.dest(targetFolder)); | |||
} | |||
gulp.task('cdn:docsite:stage', ['cdn:docsite:core-elements', | |||
'cdn:docsite:core-elements-elements', | |||
'cdn:docsite:core-elements-integrations', | |||
'cdn:docsite:core-elements-ng2-integration']); | |||
'cdn:docsite:core-elements-elements']); | |||
gulp.task('cdn:docsite:zip', ['cdn:docsite:stage'], function() { | |||
var src = docPath + '/**/*'; |