On Github BrandonCouts / react-presentation
Iso-what?
Isomorphic. Javascript. It means writing one codebase that can run on both the server side and the client side.
I’m an Angular fan just like everybody else, but one pain point is the potential SEO impact.
"But I thought Google executes and indexes javascript?"
Yeah, not really. They just give you an opportunity to serve up static HTML. You still have to generate that HTML with PhantomJS or a third party service.
Enter React.
React is a JavaScript library for creating user interfaces by Facebook and Instagram. Many people choose to think of React as the V in MVC.
We built React to solve one problem: building large applications with data that changes over time.
A lot of companies do:
It only updates what it needs to by providing simple semantics (props, state, lifecycle).
JSX - React
var HelloMessage = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; } }); React.render(<hellomessage name="Jorge"></hellomessage>, mountNode);
var HelloMessage = React.createClass({ displayName: "HelloMessage", render: function() { return React.createElement("div", null, "Hello ", this.props.name); } }); React.render(React.createElement(HelloMessage, {name: "Jorge"}), mountNode);
Using props and state, we can put together a small Todo application. This example uses state to track the current list of items as well as the text that the user has entered. Although event handlers appear to be rendered inline, they will be collected and implemented using event delegation.
var TodoList = React.createClass({ render: function() { var createItem = function(itemText, index) { return <li key="{index" +="" itemtext}="">{itemText}</li>; }; return <ul>{this.props.items.map(createItem)}</ul>; } }); var TodoApp = React.createClass({ getInitialState: function() { return { items: [], text: '' }; }, onChange: function(e) { this.setState({text: e.target.value}); }, handleSubmit: function(e) { e.preventDefault(); var nextItems = this.state.items.concat([this.state.text]); var nextText = ''; this.setState({items: nextItems, text: nextText}); }, render: function() { return ( <div> <h3>TODO</h3> <todolist items="{this.state.items}"> <form onsubmit="{this.handleSubmit}"> <input onchange="{this.onChange}" value="{this.state.text}"> <button>{'Add #' + (this.state.items.length + 1)}</button> </form> </todolist></div> ); } }); React.render(<todoapp></todoapp>, mountNode);
React is all about one-way data flow down the component hierarchy.
Imagine that we already have a JSON API and a mock from our designer. Our designer apparently isn't very good because the mock looks like this:
[ {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} ];
/** @jsx React.DOM */ var ProductCategoryRow = React.createClass({ render: function() { return ({this.props.category}); } }); var ProductRow = React.createClass({ render: function() { var name = this.props.product.stocked ? this.props.product.name : <span style="{{color:'red'}}"> {this.props.product.name} </span>; return ( {name} {this.props.product.price} ); } }); var ProductTable = React.createClass({ render: function() { console.log(this.props); var rows = []; var lastCategory = null; this.props.products.forEach(function(product) { if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) { return; } if (product.category !== lastCategory) { rows.push(<productcategoryrow category="{product.category}" key="{product.category}">); } rows.push(<productrow product="{product}" key="{product.name}">); lastCategory = product.category; }.bind(this)); return ( {rows}<table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody></tbody> </table> ); } }); var SearchBar = React.createClass({ handleChange: function() { this.props.onUserInput( this.refs.filterTextInput.getDOMNode().value, this.refs.inStockOnlyInput.getDOMNode().checked ); }, render: function() { return ( <form> <input type="text" placeholder="Search..." value="{this.props.filterText}" ref="filterTextInput" onchange="{this.handleChange}"> <p> <input type="checkbox" checked="{this.props.inStockOnly}" ref="inStockOnlyInput" onchange="{this.handleChange}"> {' '} Only show products in stock </p> </form> ); } }); var FilterableProductTable = React.createClass({ getInitialState: function() { return { filterText: '', inStockOnly: false }; }, handleUserInput: function(filterText, inStockOnly) { this.setState({ filterText: filterText, inStockOnly: inStockOnly }); }, render: function() { return ( <div> <searchbar filtertext="{this.state.filterText}" instockonly="{this.state.inStockOnly}" onuserinput="{this.handleUserInput}"> <producttable products="{this.props.products}" filtertext="{this.state.filterText}" instockonly="{this.state.inStockOnly}"> </producttable></searchbar></div> ); } }); var PRODUCTS = [ {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'}, {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'}, {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'}, {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'}, {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'}, {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'} ]; React.render(<filterableproducttable products="{PRODUCTS}">, document.body); </filterableproducttable></productrow></productcategoryrow>
Press ESC to enter the slide overview.
Hold down alt and click on any element to zoom in on it using zoom.js. Alt + click anywhere to zoom back out.
Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides.
Write content using inline or external Markdown. Instructions and more info available in the readme.
<section data-markdown> ## Markdown support Write content using inline or external Markdown. Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown). </section>
Hit the next arrow...
... to step through ...
... a fragmented slide.
This slide has fragments which are also stepped through in the notes window.There's different types of fragments, like:
grow
shrink
fade-out
current-visible
highlight-red
highlight-blue
You can select from different transitions, like: None - Fade - Slide - Convex - Concave - Zoom
reveal.js comes with a few themes built in: Black (default) - White - League - Sky - Beige - Simple Serif - Blood - Night - Moon - Solarized
Set data-background="#dddddd" on a slide to change the background color. All CSS color formats are supported.
<section data-background="image.png">
<section data-background="image.png" data-background-repeat="repeat" data-background-size="100px">
<section data-background-video="video.mp4,video.webm">
Different background transitions are available via the backgroundTransition option. This one's called "zoom".
Reveal.configure({ backgroundTransition: 'zoom' })
You can override background transitions per-slide.
<section data-background-transition="zoom">
function linkify( selector ) { if( supports3DTransforms ) { var nodes = document.querySelectorAll( selector ); for( var i = 0, len = nodes.length; i < len; i++ ) { var node = nodes[i]; if( !node.className ) { node.className += ' roll'; } } } }
Code syntax highlighting courtesy of highlight.js.
These guys come in two forms, inline: “The nice thing about standards is that there are so many to choose from” and block:
“For years there has been a theory that millions of monkeys typing at random on millions of typewriters would reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.”You can link between slides internally, like this.
There's a speaker view. It includes a timer, preview of the upcoming slide as well as your speaker notes.
Press the S key to try it out.
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).Presentations can be exported to PDF, here's an example:
Set data-state="something" on a slide and "something" will be added as a class to the document element when the slide is open. This lets you apply broader style changes, like switching the page background.
Additionally custom events can be triggered on a per slide basis by binding to the data-state name.
Reveal.addEventListener( 'customevent', function() { console.log( '"customevent" has fired' ); } );
Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen.