A circular carousel with a "shooting gallery" type interaction. Points of interest:
-
All DOM manipulation is handled by React.js. Although React has a poor reputation for dealing with animation, reasonably appealing effects can be achieved with the 'transition' style property and properly keyed dynamic children.
-
All styles are calculated on‐the‐fly and applied inline. This offers considerably greater expressiveness compared to static external stylesheets with global classnames. For a practical demonstration of the utility of this methodology, consider
components/Button.jsx
, which faithfully implements a fully-featured bootstrap style button with no external CSS dependencies. See Christopher Chedeau's terrific talk and slide deck for further exposition and rationalle. I believe this will be the most important paradigm shift in front‐end web development since Node.js. -
The model and events layers are implemented with a simple Flux architecture, using Immutable.js data structures as backing stores. This is a tremendous simplification over model‐view‐controller architectures, as our components do not need to be concerned with managing their state — whenever the store is altered, it emits a change event received by the master component's event listener. This calls
Carousel.onChange()
, which retrieves the new state from store, triggering a re‐render and propagating updated state into itscomponents/Shape.jsx
children. Because all components implement PureRenderMixin, React is able to avoid unnecessarily re‐rendering unchanged elements. -
Immutable.js has an API for functional manipulation of data structures, superior in many respects to underscore/lodash. In particular,
Immutable.Record
provides an immutable data structure whose member variables can be transparently consumed by any client using plain‐old‐javascript accessor syntax, including the React.PropTypes.shape() type checker function. -
All sources are written in ES6 and compiled to ES5 with Babel. This project relies heavily on many ES6 features — note the use of classes and destructuring assignment in CarouselStore.jsx, and pervasive use of computed property names, template strings and
Object.assign
throughout the inline styling system. -
Tested in desktop Chrome 41, Safari 8 and Firefox 36. Certain not to work on IE 9 or lower due to dependency on flexbox support (although see this commit for an approach utilizing
display: table-cell;
). IE 10 support is probably realistic, and the path toward supporting prefixed CSS in a general way while maintaing the purity ofrender()
is clear: we detect prefixes before initializing React and then pass a key‐value store from standard property names to prefixed names through the tree of React components as props. Seeutils/detectPrefixes.js
andindex.jsx
for details. As for mobile, React Touch events looks straightforward, and Button.jsx allows for responsive resizing of UI widgets in a way that is strictly impossible with css‐based bootstrap.
npm install
npm start
open http://localhost:3000
npm run webpack
or npm run browserify