Browse Source

Merge pull request #73 from vaadin/react-docs

Replace React integration demo with proper documentation
tags/v1.2.0
Sauli Tähkäpää 7 years ago
parent
commit
7c1284f123

+ 0
- 32
demo/common.html View File

@@ -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>

+ 0
- 56
demo/index.html View File

@@ -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>

+ 0
- 15924
demo/js_dependencies/JSXTransformer.js
File diff suppressed because it is too large
View File


+ 0
- 15
demo/js_dependencies/react.min.js
File diff suppressed because it is too large
View File


+ 0
- 64
demo/react-demo-embed.html View File

@@ -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>

+ 0
- 148
demo/react.html View File

@@ -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>

BIN
docs/integrations/img/react-integration.png View File


+ 121
- 0
docs/integrations/integrations-react.adoc View File

@@ -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'));
});
----

+ 2
- 55
tasks/docsite.js View File

@@ -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 + '/**/*';

Loading…
Cancel
Save