diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..91246e4 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "optional": ["es7.classProperties"] +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..0463860 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,29 @@ +{ + "parser": "babel-eslint", + "ecmaFeatures": { + "arrowFunctions": true, + "templateStrings": true, + "classes": true, + "modules": true, + "restParams": true, + "jsx": true + }, + + "env": { + "browser": true, + "node": true, + "es6": true + }, + + "globals": { + "BROWSER": true + }, + + "rules": { + "quotes": 0, + "no-trailing-spaces": 0, + "no-unused-vars": 0, + "no-alert": 0, + "strict": 0 + } +} \ No newline at end of file diff --git a/.jshintrc b/.jshintrc index 9018e4c..f631a7f 100644 --- a/.jshintrc +++ b/.jshintrc @@ -10,6 +10,7 @@ "unused": true, "boss": true, "eqnull": true, + "expr": true, "node": true, "browser": true, "devel": true, diff --git a/dist/css/react-star-rating.min.css b/dist/css/react-star-rating.min.css index d2be0bb..3cb52f2 100644 --- a/dist/css/react-star-rating.min.css +++ b/dist/css/react-star-rating.min.css @@ -1 +1 @@ -.react-star-rating__root{font-size:2em;vertical-align:middle;display:inline-block}.react-star-rating__root.rating-editing:hover{cursor:pointer}.rating-container{position:relative;vertical-align:middle;display:inline-block;color:#e3e3e3;overflow:hidden}.rating-container:before{content:attr(data-content)}.rating-container .rating-stars{position:absolute;left:0;top:0;white-space:nowrap;overflow:hidden;color:#F5A71B;-webkit-transition:all 0.01s;-moz-transition:all 0.01s;transition:all 0.01s;-webkit-mask-image:-webkit-gradient(linear, left top, left bottom, from(#FDBD47), to(#F5A71B))}.rating-container .rating-stars:before{content:attr(data-content)}.react-rating-caption{font-size:1.25em;vertical-align:middle;margin-right:0.5em}.rating-disabled .rating-container:hover{cursor:not-allowed}.react-star-rating__size--sm{font-size:1em}.react-star-rating__size--md{font-size:2em}.react-star-rating__size--lg{font-size:2.5em} \ No newline at end of file +.rating-container,.react-star-rating__root{vertical-align:middle;display:inline-block}.rating-container .rating-stars:before,.rating-container:before{content:attr(data-content)}.react-star-rating__root{font-size:2em}.react-star-rating__root.rating-editing:hover{cursor:pointer}.rating-container{position:relative;color:#e3e3e3;overflow:hidden}.rating-container .rating-stars{position:absolute;left:0;top:0;white-space:nowrap;overflow:hidden;color:#F5A71B;-webkit-transition:all .01s;-moz-transition:all .01s;transition:all .01s;-webkit-mask-image:-webkit-gradient(linear,left top,left bottom,from(#FDBD47),to(#F5A71B))}.react-rating-caption{font-size:1.25em;vertical-align:middle;margin-right:.5em}.rating-disabled .rating-container:hover{cursor:not-allowed}.react-star-rating__size--sm{font-size:1em}.react-star-rating__size--md{font-size:2em}.react-star-rating__size--lg{font-size:2.5em} \ No newline at end of file diff --git a/dist/demo/bundle.js b/dist/demo/bundle.js index f5e42a0..f81acac 100644 --- a/dist/demo/bundle.js +++ b/dist/demo/bundle.js @@ -1,137 +1,498 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o'), - React.createElement("p", null, ''), - React.createElement("p", null, ''), - React.createElement("p", null, '') - ), - React.createElement("h2", null, "Usage"), - React.createElement("hr", null), - React.createElement("form", {target: "_self", method: "GET", className: "demo-form"}, - React.createElement(StarRating, {name: "react-star-rating", caption: "Rate this component!", ratingAmount: 5}), - React.createElement("button", {type: "submit", className: "btn btn-submit"}, "Submit Rating") - ), - React.createElement("code", null, - React.createElement("p", null, 'var FormComponent = React.createClass({'), - React.createElement("p", null, ' render: function () { '), - React.createElement("p", null, ' return ('), - React.createElement("p", null, '
'), - React.createElement("p", null, ' '), - React.createElement("p", null, ' '), - React.createElement("p", null, ' '), - React.createElement("p", null, ' );'), - React.createElement("p", null, ' }'), - React.createElement("p", null, '});'), - React.createElement("p", null, ' '), - React.createElement("p", null, 'React.render(, document.getElementById(\'star-rating\')') - ), - React.createElement("h2", null, "Options"), - React.createElement("hr", null), - React.createElement("ul", null, - React.createElement("li", null, React.createElement("strong", null, "name"), '={string} - name for form input (required)'), - React.createElement("li", null, React.createElement("strong", null, "caption"), '={string} - caption for rating (optional)'), - React.createElement("li", null, React.createElement("strong", null, "ratingAmount"), '={number} - rating amount (required, default: 5)'), - React.createElement("li", null, React.createElement("strong", null, "rating"), '={number} - a set rating between the rating amount (optional)'), - React.createElement("li", null, React.createElement("strong", null, "disabled"), '={boolean} - whether to disable the rating from being selected (optional)'), - React.createElement("li", null, React.createElement("strong", null, "editing"), '={boolean} - whether the rating is explicitly in editing mode (optional)'), - React.createElement("li", null, React.createElement("strong", null, "size"), '={string} - size of stars (optional)'), - React.createElement("li", null, React.createElement("strong", null, "onRatingClick"), '={function} - a handler function that gets called onClick of the rating (optional) - gets passed (event, {position, rating, caption, name})') - ), - React.createElement("h2", null, "Examples"), - React.createElement("hr", null), - React.createElement(StarRating, {name: "handler", caption: "Use onClick Handlers!", ratingAmount: 5, step: 0.5, onRatingClick: this.handleRatingClick}), - React.createElement("p", null), - React.createElement("code", null, - React.createElement("p", null, ''), - React.createElement("p", null, '') - ), - React.createElement(StarRating, {name: "ten-stars", caption: "Configure number of stars!", ratingAmount: 10, step: 1, onRatingClick: this.handleRatingClick}), - React.createElement("code", null, - '' - ), - React.createElement(StarRating, {name: "half-stars", caption: "Use half-star steps!", ratingAmount: 5}), - React.createElement("code", null, - '' - ), - React.createElement(StarRating, {name: "small-rating", caption: "Small!", size: "sm", ratingAmount: 5, rating: 3}), - React.createElement("code", null, - '' - ), - React.createElement(StarRating, {name: "medium-rating", caption: "Medium!", size: "md", ratingAmount: 5, rating: 4}), - React.createElement("code", null, - '' - ), - React.createElement(StarRating, {name: "large-rating", caption: "Large!", size: "lg", ratingAmount: 5, rating: 5}), - React.createElement("code", null, - '' - ), - React.createElement(StarRating, {name: "disabled", caption: "Disabled.", ratingAmount: 5, rating: 3, disabled: true}), - React.createElement("code", null, - '' - ) - ), - React.createElement("footer", null, - React.createElement("p", {className: "footer-creds"}, - React.createElement("p", null, "Code licensed under ", React.createElement("a", {href: "https://github.com/cameronjroe/react-star-rating/blob/master/LICENSE"}, "MIT"), " - Currently v", currentVersion, " - ", React.createElement("a", {href: "https://github.com/cameronjroe/react-star-rating"}, "Github Repo")), - React.createElement("p", null, "Created by ", React.createElement("a", {href: "http://twitter.com/cameronjroe"}, "@cameronjroe"), " - ", React.createElement("iframe", {src: "https://ghbtns.com/github-btn.html?user=cameronjroe&type=follow&count=true", frameBorder: "0", scrolling: "0", width: "170px", height: "20px"})) - ) - ) - ) - ); +var React = _interopRequire(require("react")); + +var StarRating = _interopRequire(require("./StarRating")); + +var pkg = _interopRequire(require("../package.json")); + +var inject = document.querySelector(".inject"); + +var App = (function (_React$Component) { + function App() { + _classCallCheck(this, App); + + if (_React$Component != null) { + _React$Component.apply(this, arguments); + } } -}); + _inherits(App, _React$Component); + + _createClass(App, { + handleRatingClick: { + value: function handleRatingClick(e, data) { + alert("You left a " + data.rating + " star rating for " + data.name); + } + }, + render: { + value: function render() { + var currentVersion = pkg.version; + + return React.createElement( + "section", + null, + React.createElement( + "div", + { className: "intro" }, + React.createElement( + "h1", + { className: "main-title" }, + "react-star-rating", + React.createElement( + "small", + null, + " easy star ratings with React" + ) + ), + React.createElement(StarRating, { name: "hotels", size: "md", rating: 5, editing: true, ratingAmount: 5, step: 1 }), + React.createElement( + "p", + null, + "v", + currentVersion + ) + ), + React.createElement( + "div", + { className: "ratings-wrap" }, + React.createElement( + "h2", + null, + "Installation" + ), + React.createElement("hr", null), + React.createElement( + "code", + null, + "$ npm install react-star-rating --save" + ), + React.createElement( + "h2", + null, + "Usage" + ), + React.createElement("hr", null), + React.createElement( + "form", + { target: "_self", method: "GET", className: "demo-form" }, + React.createElement(StarRating, { name: "react-star-rating", caption: "Rate this component!", ratingAmount: 5 }), + React.createElement( + "button", + { type: "submit", className: "btn btn-submit" }, + "Submit Rating" + ) + ), + React.createElement( + "h3", + null, + "ES6" + ), + React.createElement( + "code", + null, + React.createElement( + "p", + null, + "import React from 'react'" + ), + React.createElement( + "p", + null, + "import StarRating from 'react-star-rating'" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + "class FormComponent extends React.Component {" + ), + React.createElement( + "p", + null, + " render() { " + ), + React.createElement( + "p", + null, + " return (" + ), + React.createElement( + "p", + null, + "
" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + " );" + ), + React.createElement( + "p", + null, + " }" + ), + React.createElement( + "p", + null, + "}" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + "React.render(, document.getElementById('star-rating'));" + ) + ), + React.createElement( + "h3", + null, + "ES5/Browserify" + ), + React.createElement( + "code", + null, + React.createElement( + "p", + null, + "var React = require('react');" + ), + React.createElement( + "p", + null, + "var StarRating = require('react-star-rating');" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + "var FormComponent = React.createClass({" + ), + React.createElement( + "p", + null, + " render: function () { " + ), + React.createElement( + "p", + null, + " return (" + ), + React.createElement( + "p", + null, + "
" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + " );" + ), + React.createElement( + "p", + null, + " }" + ), + React.createElement( + "p", + null, + "});" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + "React.render(, document.getElementById('star-rating'));" + ) + ), + React.createElement( + "h2", + null, + "Options" + ), + React.createElement("hr", null), + React.createElement( + "ul", + null, + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "name" + ), + "={string} - name for form input (required)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "caption" + ), + "={string} - caption for rating (optional)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "ratingAmount" + ), + "={number} - rating amount (required, default: 5)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "rating" + ), + "={number} - a set rating between the rating amount (optional)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "disabled" + ), + "={boolean} - whether to disable the rating from being selected (optional)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "editing" + ), + "={boolean} - whether the rating is explicitly in editing mode (optional)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "size" + ), + "={string} - size of stars (optional)" + ), + React.createElement( + "li", + null, + React.createElement( + "strong", + null, + "onRatingClick" + ), + "={function} - a handler function that gets called onClick of the rating (optional) - gets passed (event, {position, rating, caption, name})" + ) + ), + React.createElement( + "h2", + null, + "Examples" + ), + React.createElement("hr", null), + React.createElement(StarRating, { name: "handler", caption: "Use onClick Handlers!", ratingAmount: 5, step: 0.5, onRatingClick: this.handleRatingClick.bind(this) }), + React.createElement("p", null), + React.createElement( + "code", + null, + React.createElement( + "p", + null, + "// handler in react class" + ), + React.createElement( + "p", + null, + "handleRatingClick: function (e, data) {" + ), + React.createElement( + "p", + null, + " alert('You left a ' + data.rating + ' star rating for ' + data.caption);" + ), + React.createElement( + "p", + null, + "}" + ), + React.createElement( + "p", + null, + " " + ), + React.createElement( + "p", + null, + "" + ) + ), + React.createElement("p", null), + React.createElement( + "blockquote", + null, + React.createElement( + "strong", + null, + "If you're using ES6, make sure to bind the handler: " + ), + React.createElement( + "code", + null, + "this.handleRatingClick.bind(this, pass, args, here)" + ) + ), + React.createElement(StarRating, { name: "ten-stars", caption: "Configure number of stars!", ratingAmount: 10, step: 1, onRatingClick: this.handleRatingClick.bind(this) }), + React.createElement( + "code", + null, + "" + ), + React.createElement(StarRating, { name: "half-stars", caption: "Use half-star steps!", ratingAmount: 5 }), + React.createElement( + "code", + null, + "" + ), + React.createElement(StarRating, { name: "small-rating", caption: "Small!", size: "sm", ratingAmount: 5, rating: 3 }), + React.createElement( + "code", + null, + "" + ), + React.createElement(StarRating, { name: "medium-rating", caption: "Medium!", size: "md", ratingAmount: 5, rating: 4 }), + React.createElement( + "code", + null, + "" + ), + React.createElement(StarRating, { name: "large-rating", caption: "Large!", size: "lg", ratingAmount: 5, rating: 5 }), + React.createElement( + "code", + null, + "" + ), + React.createElement(StarRating, { name: "disabled", caption: "Disabled.", ratingAmount: 5, rating: 3, disabled: true }), + React.createElement( + "code", + null, + "" + ) + ), + React.createElement( + "footer", + null, + React.createElement( + "p", + { className: "footer-creds" }, + React.createElement( + "p", + null, + "Code licensed under ", + React.createElement( + "a", + { href: "https://github.com/cameronjroe/react-star-rating/blob/master/LICENSE" }, + "MIT" + ), + " - Currently v", + currentVersion, + " - ", + React.createElement( + "a", + { href: "https://github.com/cameronjroe/react-star-rating" }, + "Github Repo" + ) + ), + React.createElement( + "p", + null, + "Created by ", + React.createElement( + "a", + { href: "http://twitter.com/cameronjroe" }, + "@cameronjroe" + ), + " - ", + React.createElement("iframe", { src: "https://ghbtns.com/github-btn.html?user=cameronjroe&type=follow&count=true", frameBorder: "0", scrolling: "0", width: "170px", height: "20px" }) + ) + ) + ) + ); + } + } + }); + + return App; +})(React.Component); React.render(React.createElement(App, null), inject); -},{"../package.json":158,"./StarRating.jsx":159,"react":157}],2:[function(require,module,exports){ +},{"../package.json":158,"./StarRating":159,"react":157}],2:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -19845,10 +20206,12 @@ module.exports = require('./lib/React'); },{"./lib/React":30}],158:[function(require,module,exports){ module.exports={ "name": "react-star-rating", - "version": "1.1.3", + "version": "1.1.4", "description": "A simple star rating component built with React.", "main": "dist/react-star-rating.min.js", - "scripts": {}, + "scripts": { + "watch": "gulp watch" + }, "author": "Cameron J Roe (http://cameronjroe.com/)", "license": "MIT", "peerDependencies": { @@ -19858,8 +20221,11 @@ module.exports={ "babelify": "^5.0.4", "browserify": "^9.0.3", "gulp": "^3.8.11", + "gulp-babel": "^5.1.0", "gulp-concat": "^2.5.2", + "gulp-eslint": "^0.12.0", "gulp-jshint": "^1.9.2", + "gulp-minify-css": "^1.1.1", "gulp-react": "^3.0.0", "gulp-rename": "^1.2.0", "gulp-replace": "^0.5.3", @@ -19875,9 +20241,19 @@ module.exports={ } },{}],159:[function(require,module,exports){ -// {amd_start} +"use strict"; + +var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + +var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var React = require('react'); +var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + +var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + +var React = _interopRequire(require("react")); /** * @fileoverview react-star-rating @@ -19893,255 +20269,286 @@ var React = require('react'); * onRatingClick={function} - a handler function that gets called onClick of the rating (optional) * /> */ -module.exports = React.createClass({displayName: "exports", - - propTypes: { - name: React.PropTypes.string.isRequired, - caption: React.PropTypes.string, - ratingAmount: React.PropTypes.number.isRequired, - rating: React.PropTypes.number, - onRatingClick: React.PropTypes.func, - disabled: React.PropTypes.bool, - editing: React.PropTypes.bool, - size: React.PropTypes.string - }, - - getStars: function () { - var stars = ''; - var numRating = this.props.ratingAmount; - for(var i = 0; i < numRating; i++) { - stars += '\u2605'; - } - return stars; - }, - getDefaultProps: function () { - return { - step: 0.5, - ratingAmount: 5, - onRatingClick: function () {}, - disabled: false - }; - }, +var StarRating = (function (_React$Component) { + function StarRating(props) { + _classCallCheck(this, StarRating); - getInitialState: function () { - return { + _get(Object.getPrototypeOf(StarRating.prototype), "constructor", this).call(this, props); + this.state = { ratingCache: { pos: 0, rating: 0 }, - editing: this.props.editing || true, + editing: props.editing || true, stars: 5, rating: 0, pos: 0, glyph: this.getStars() }; - }, - - componentWillMount: function () { - this.min = 0; - this.max = this.props.ratingAmount || 5; - - if (this.props.rating) { - - this.state.editing = false; - - var ratingVal = this.props.rating; - this.setState({ - rating: ratingVal, - pos: this.getStarRatingPosition(ratingVal) - }); - } - - }, - - componentDidMount: function () { - this.root = this.refs.root.getDOMNode(); - this.ratingStars = this.refs.ratingStars.getDOMNode(); - this.ratingContainer = this.refs.ratingContainer.getDOMNode(); - }, - - componentWillUnmount: function () { - delete this.root; - delete this.ratingStars; - delete this.ratingContainer; - }, - - getPosition: function (e) { - return e.pageX - this.root.getBoundingClientRect().left; - }, - - applyPrecision: function (val, precision) { - return parseFloat(val.toFixed(precision)); - }, + } - getDecimalPlaces: function (num) { - var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); - return !match ? 0 : Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); - }, + _inherits(StarRating, _React$Component); - getWidthFromValue: function (val) { - var min = this.min, - max = this.max; - if (val <= min || min === max) { - return 0; - } - if (val >= max) { - return 100; - } - return (val - min) * 100 / (max - min); - }, - - getValueFromPosition: function (pos) { - var precision = this.getDecimalPlaces(this.props.step); - var maxWidth = this.ratingContainer.offsetWidth; - var diff = this.max - this.min; - var factor = (diff * pos) / (maxWidth * this.props.step); + _createClass(StarRating, { + getStars: { + value: function getStars() { + var stars = ""; + var numRating = this.props.ratingAmount; + for (var i = 0; i < numRating; i++) { + stars += "★"; + } + return stars; + } + }, + componentWillMount: { + value: function componentWillMount() { + this.min = 0; + this.max = this.props.ratingAmount || 5; + if (this.props.rating) { + + this.state.editing = false; + + var ratingVal = this.props.rating; + this.setState({ + rating: ratingVal, + pos: this.getStarRatingPosition(ratingVal) + }); + } + } + }, + componentDidMount: { + value: function componentDidMount() { + this.root = this.refs.root.getDOMNode(); + this.ratingStars = this.refs.ratingStars.getDOMNode(); + this.ratingContainer = this.refs.ratingContainer.getDOMNode(); + } + }, + componentWillUnmount: { + value: function componentWillUnmount() { + delete this.root; + delete this.ratingStars; + delete this.ratingContainer; + } + }, + getPosition: { + value: function getPosition(e) { + return e.pageX - this.root.getBoundingClientRect().left; + } + }, + applyPrecision: { + value: function applyPrecision(val, precision) { + return parseFloat(val.toFixed(precision)); + } + }, + getDecimalPlaces: { + value: function getDecimalPlaces(num) { + var match = ("" + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); + return !match ? 0 : Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); + } + }, + getWidthFromValue: { + value: function getWidthFromValue(val) { + var min = this.min, + max = this.max; + if (val <= min || min === max) { + return 0; + } + if (val >= max) { + return 100; + } + return (val - min) * 100 / (max - min); + } + }, + getValueFromPosition: { + value: function getValueFromPosition(pos) { + var precision = this.getDecimalPlaces(this.props.step); + var maxWidth = this.ratingContainer.offsetWidth; + var diff = this.max - this.min; + var factor = diff * pos / (maxWidth * this.props.step); factor = Math.ceil(factor); - var val = this.applyPrecision(parseFloat(this.min + factor * this.props.step), precision); + var val = this.applyPrecision(parseFloat(this.min + factor * this.props.step), precision); val = Math.max(Math.min(val, this.max), this.min); - return val; - }, - - calculate: function (pos) { - var val = this.getValueFromPosition(pos), - width = this.getWidthFromValue(val); - - width += '%'; - return {width: width, val: val}; - }, - - getStarRatingPosition: function (val) { - var width = this.getWidthFromValue(val); - return width += '%'; - }, - - getRatingEvent: function (e) { - var pos = this.getPosition(e); - return this.calculate(pos); - }, - - handleMouseLeave: function () { - this.setState({ - pos: this.state.ratingCache.pos, - rating: this.state.ratingCache.rating - }); - }, - - handleMouseMove: function (e) { - // get hover position - var ratingEvent = this.getRatingEvent(e); - this.setState({ - pos: ratingEvent.width, - rating: ratingEvent.val - }); - }, - - shouldComponentUpdate: function (nextProps, nextState) { - return nextState.ratingCache.rating !== this.state.ratingCache.rating || nextState.rating !== this.state.rating; - }, + return val; + } + }, + calculate: { + value: function calculate(pos) { + var val = this.getValueFromPosition(pos), + width = this.getWidthFromValue(val); - handleClick: function (e) { + width += "%"; + return { width: width, val: val }; + } + }, + getStarRatingPosition: { + value: function getStarRatingPosition(val) { + var width = this.getWidthFromValue(val) + "%"; + return width; + } + }, + getRatingEvent: { + value: function getRatingEvent(e) { + var pos = this.getPosition(e); + return this.calculate(pos); + } + }, + handleMouseLeave: { + value: function handleMouseLeave() { + this.setState({ + pos: this.state.ratingCache.pos, + rating: this.state.ratingCache.rating + }); + } + }, + handleMouseMove: { + value: function handleMouseMove(e) { + // get hover position + var ratingEvent = this.getRatingEvent(e); + this.setState({ + pos: ratingEvent.width, + rating: ratingEvent.val + }); + } + }, + shouldComponentUpdate: { + value: function shouldComponentUpdate(nextProps, nextState) { + return nextState.ratingCache.rating !== this.state.ratingCache.rating || nextState.rating !== this.state.rating; + } + }, + handleClick: { + value: function handleClick(e) { - // is it disabled? - if (this.props.disabled) { - e.stopPropagation(); - e.preventDefault(); - return false; - } + // is it disabled? + if (this.props.disabled) { + e.stopPropagation(); + e.preventDefault(); + return false; + } - var ratingCache = { - pos: this.state.pos, - rating: this.state.rating, - caption: this.props.caption, - name: this.props.name - }; + var ratingCache = { + pos: this.state.pos, + rating: this.state.rating, + caption: this.props.caption, + name: this.props.name + }; - this.setState({ - ratingCache: ratingCache - }); + this.setState({ + ratingCache: ratingCache + }); - this.props.onRatingClick(e, ratingCache); - }, + this.props.onRatingClick(e, ratingCache); + } + }, + treatName: { + value: function treatName(title) { + if (typeof title === "string") { + return title.toLowerCase().split(" ").join("_"); + } + } + }, + getClasses: { + value: function getClasses() { + var classes = ["react-star-rating__root"]; - treatName: function (title) { - if (typeof title === 'string') { - return title.toLowerCase().split(' ').join('_'); - } - }, + // is it disabled? + if (this.props.disabled) { + classes.push("rating-disabled"); + } - getClasses: function () { - var classes = ['react-star-rating__root']; + if (this.props.size) { + switch (this.props.size) { + case "sm": + classes.push("react-star-rating__size--sm"); + break; + case "md": + classes.push("react-star-rating__size--md"); + break; + case "lg": + classes.push("react-star-rating__size--lg"); + break; + default: + break; + } + } - // is it disabled? - if (this.props.disabled) { - classes.push('rating-disabled'); - } + if (this.state.editing) { + classes.push("rating-editing"); + } - if (this.props.size) { - switch(this.props.size) { - case 'sm': - classes.push('react-star-rating__size--sm'); - break; - case 'md': - classes.push('react-star-rating__size--md'); - break; - case 'lg': - classes.push('react-star-rating__size--lg'); - break; - default: - break; + return classes.join(" "); } - } + }, + render: { + value: function render() { - if (this.state.editing) { - classes.push('rating-editing'); - } + var caption = null; - return classes.join(' '); - }, + // is there a caption? + if (this.props.caption) { + caption = React.createElement( + "span", + { className: "react-rating-caption" }, + this.props.caption + ); + } - render: function () { + // get the classes on this render + var classes = this.getClasses(); + + // are we editing this rating? + var starRating; + if (this.state.editing) { + starRating = React.createElement( + "div", + { ref: "ratingContainer", className: "rating-container rating-gly-star", "data-content": this.state.glyph, onMouseMove: this.handleMouseMove.bind(this), onMouseLeave: this.handleMouseLeave.bind(this), onClick: this.handleClick.bind(this) }, + React.createElement("div", { ref: "ratingStars", className: "rating-stars", "data-content": this.state.glyph, style: { width: this.state.pos } }), + React.createElement("input", { type: "number", name: this.props.name, value: this.state.ratingCache.rating, style: { display: "none !important" }, min: this.min, max: this.max, readOnly: true }) + ); + } else { + starRating = React.createElement( + "div", + { ref: "ratingContainer", className: "rating-container rating-gly-star", "data-content": this.state.glyph }, + React.createElement("div", { ref: "ratingStars", className: "rating-stars", "data-content": this.state.glyph, style: { width: this.state.pos } }), + React.createElement("input", { type: "number", name: this.props.name, value: this.state.ratingCache.rating, style: { display: "none !important" }, min: this.min, max: this.max, readOnly: true }) + ); + } - var caption = null; - - // is there a caption? - if (this.props.caption) { - caption = (React.createElement("span", {className: "react-rating-caption"}, this.props.caption)); + return React.createElement( + "span", + { className: "react-star-rating" }, + caption, + React.createElement( + "span", + { ref: "root", className: classes }, + starRating + ) + ); + } } + }); - // get the classes on this render - var classes = this.getClasses(); - - // are we editing this rating? - var starRating; - if (this.state.editing) { - starRating = ( - React.createElement("div", {ref: "ratingContainer", className: "rating-container rating-gly-star", "data-content": this.state.glyph, onMouseMove: this.handleMouseMove, onMouseLeave: this.handleMouseLeave, onClick: this.handleClick}, - React.createElement("div", {ref: "ratingStars", className: "rating-stars", "data-content": this.state.glyph, style: {width: this.state.pos}}), - React.createElement("input", {type: "number", name: this.props.name, value: this.state.ratingCache.rating, style: {display: 'none !important'}, min: this.min, max: this.max, readOnly: true}) - ) - ); - } else { - starRating = ( - React.createElement("div", {ref: "ratingContainer", className: "rating-container rating-gly-star", "data-content": this.state.glyph}, - React.createElement("div", {ref: "ratingStars", className: "rating-stars", "data-content": this.state.glyph, style: {width: this.state.pos}}), - React.createElement("input", {type: "number", name: this.props.name, value: this.state.ratingCache.rating, style: {display: 'none !important'}, min: this.min, max: this.max, readOnly: true}) - ) - ); - } + return StarRating; +})(React.Component); + +StarRating.propTypes = { + name: React.PropTypes.string.isRequired, + caption: React.PropTypes.string, + ratingAmount: React.PropTypes.number.isRequired, + rating: React.PropTypes.number, + onRatingClick: React.PropTypes.func, + disabled: React.PropTypes.bool, + editing: React.PropTypes.bool, + size: React.PropTypes.string +}; - return ( - React.createElement("span", {className: "react-star-rating"}, - caption, - React.createElement("span", {ref: "root", className: classes}, - starRating - ) - ) - ); - } -}); +StarRating.defaultProps = { + step: 0.5, + ratingAmount: 5, + onRatingClick: function onRatingClick() {}, + disabled: false +}; -// {amd_end} +module.exports = StarRating; },{"react":157}]},{},[1]); diff --git a/dist/react-star-rating.js b/dist/react-star-rating.js index 2f41a06..c98cfeb 100644 --- a/dist/react-star-rating.js +++ b/dist/react-star-rating.js @@ -1,6 +1,22 @@ -// {amd_start} +'use strict'; -var React = require('react'); +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); /** * @fileoverview react-star-rating @@ -16,253 +32,284 @@ var React = require('react'); * onRatingClick={function} - a handler function that gets called onClick of the rating (optional) * /> */ -module.exports = React.createClass({displayName: "exports", - - propTypes: { - name: React.PropTypes.string.isRequired, - caption: React.PropTypes.string, - ratingAmount: React.PropTypes.number.isRequired, - rating: React.PropTypes.number, - onRatingClick: React.PropTypes.func, - disabled: React.PropTypes.bool, - editing: React.PropTypes.bool, - size: React.PropTypes.string - }, - - getStars: function () { - var stars = ''; - var numRating = this.props.ratingAmount; - for(var i = 0; i < numRating; i++) { - stars += '\u2605'; - } - return stars; - }, - - getDefaultProps: function () { - return { - step: 0.5, - ratingAmount: 5, - onRatingClick: function () {}, - disabled: false - }; - }, - getInitialState: function () { - return { +var StarRating = (function (_React$Component) { + function StarRating(props) { + _classCallCheck(this, StarRating); + + _get(Object.getPrototypeOf(StarRating.prototype), 'constructor', this).call(this, props); + this.state = { ratingCache: { pos: 0, rating: 0 }, - editing: this.props.editing || true, + editing: props.editing || true, stars: 5, rating: 0, pos: 0, glyph: this.getStars() }; - }, + } - componentWillMount: function () { - this.min = 0; - this.max = this.props.ratingAmount || 5; - - if (this.props.rating) { - - this.state.editing = false; + _inherits(StarRating, _React$Component); - var ratingVal = this.props.rating; + _createClass(StarRating, [{ + key: 'getStars', + value: function getStars() { + var stars = ''; + var numRating = this.props.ratingAmount; + for (var i = 0; i < numRating; i++) { + stars += '★'; + } + return stars; + } + }, { + key: 'componentWillMount', + value: function componentWillMount() { + this.min = 0; + this.max = this.props.ratingAmount || 5; + if (this.props.rating) { + + this.state.editing = false; + + var ratingVal = this.props.rating; + this.setState({ + rating: ratingVal, + pos: this.getStarRatingPosition(ratingVal) + }); + } + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + this.root = this.refs.root.getDOMNode(); + this.ratingStars = this.refs.ratingStars.getDOMNode(); + this.ratingContainer = this.refs.ratingContainer.getDOMNode(); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + delete this.root; + delete this.ratingStars; + delete this.ratingContainer; + } + }, { + key: 'getPosition', + value: function getPosition(e) { + return e.pageX - this.root.getBoundingClientRect().left; + } + }, { + key: 'applyPrecision', + value: function applyPrecision(val, precision) { + return parseFloat(val.toFixed(precision)); + } + }, { + key: 'getDecimalPlaces', + value: function getDecimalPlaces(num) { + var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); + return !match ? 0 : Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); + } + }, { + key: 'getWidthFromValue', + value: function getWidthFromValue(val) { + var min = this.min, + max = this.max; + if (val <= min || min === max) { + return 0; + } + if (val >= max) { + return 100; + } + return (val - min) * 100 / (max - min); + } + }, { + key: 'getValueFromPosition', + value: function getValueFromPosition(pos) { + var precision = this.getDecimalPlaces(this.props.step); + var maxWidth = this.ratingContainer.offsetWidth; + var diff = this.max - this.min; + var factor = diff * pos / (maxWidth * this.props.step); + factor = Math.ceil(factor); + var val = this.applyPrecision(parseFloat(this.min + factor * this.props.step), precision); + val = Math.max(Math.min(val, this.max), this.min); + return val; + } + }, { + key: 'calculate', + value: function calculate(pos) { + var val = this.getValueFromPosition(pos), + width = this.getWidthFromValue(val); + + width += '%'; + return { width: width, val: val }; + } + }, { + key: 'getStarRatingPosition', + value: function getStarRatingPosition(val) { + var width = this.getWidthFromValue(val) + '%'; + return width; + } + }, { + key: 'getRatingEvent', + value: function getRatingEvent(e) { + var pos = this.getPosition(e); + return this.calculate(pos); + } + }, { + key: 'handleMouseLeave', + value: function handleMouseLeave() { this.setState({ - rating: ratingVal, - pos: this.getStarRatingPosition(ratingVal) + pos: this.state.ratingCache.pos, + rating: this.state.ratingCache.rating }); } - - }, - - componentDidMount: function () { - this.root = this.refs.root.getDOMNode(); - this.ratingStars = this.refs.ratingStars.getDOMNode(); - this.ratingContainer = this.refs.ratingContainer.getDOMNode(); - }, - - componentWillUnmount: function () { - delete this.root; - delete this.ratingStars; - delete this.ratingContainer; - }, - - getPosition: function (e) { - return e.pageX - this.root.getBoundingClientRect().left; - }, - - applyPrecision: function (val, precision) { - return parseFloat(val.toFixed(precision)); - }, - - getDecimalPlaces: function (num) { - var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); - return !match ? 0 : Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); - }, - - getWidthFromValue: function (val) { - var min = this.min, - max = this.max; - if (val <= min || min === max) { - return 0; - } - if (val >= max) { - return 100; + }, { + key: 'handleMouseMove', + value: function handleMouseMove(e) { + // get hover position + var ratingEvent = this.getRatingEvent(e); + this.setState({ + pos: ratingEvent.width, + rating: ratingEvent.val + }); } - return (val - min) * 100 / (max - min); - }, - - getValueFromPosition: function (pos) { - var precision = this.getDecimalPlaces(this.props.step); - var maxWidth = this.ratingContainer.offsetWidth; - var diff = this.max - this.min; - var factor = (diff * pos) / (maxWidth * this.props.step); - factor = Math.ceil(factor); - var val = this.applyPrecision(parseFloat(this.min + factor * this.props.step), precision); - val = Math.max(Math.min(val, this.max), this.min); - return val; - }, - - calculate: function (pos) { - var val = this.getValueFromPosition(pos), - width = this.getWidthFromValue(val); - - width += '%'; - return {width: width, val: val}; - }, - - getStarRatingPosition: function (val) { - var width = this.getWidthFromValue(val); - return width += '%'; - }, - - getRatingEvent: function (e) { - var pos = this.getPosition(e); - return this.calculate(pos); - }, - - handleMouseLeave: function () { - this.setState({ - pos: this.state.ratingCache.pos, - rating: this.state.ratingCache.rating - }); - }, - - handleMouseMove: function (e) { - // get hover position - var ratingEvent = this.getRatingEvent(e); - this.setState({ - pos: ratingEvent.width, - rating: ratingEvent.val - }); - }, - - shouldComponentUpdate: function (nextProps, nextState) { - return nextState.ratingCache.rating !== this.state.ratingCache.rating || nextState.rating !== this.state.rating; - }, - - handleClick: function (e) { - - // is it disabled? - if (this.props.disabled) { - e.stopPropagation(); - e.preventDefault(); - return false; + }, { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(nextProps, nextState) { + return nextState.ratingCache.rating !== this.state.ratingCache.rating || nextState.rating !== this.state.rating; } + }, { + key: 'handleClick', + value: function handleClick(e) { + + // is it disabled? + if (this.props.disabled) { + e.stopPropagation(); + e.preventDefault(); + return false; + } - var ratingCache = { - pos: this.state.pos, - rating: this.state.rating, - caption: this.props.caption, - name: this.props.name - }; - - this.setState({ - ratingCache: ratingCache - }); - - this.props.onRatingClick(e, ratingCache); - }, - - treatName: function (title) { - if (typeof title === 'string') { - return title.toLowerCase().split(' ').join('_'); - } - }, + var ratingCache = { + pos: this.state.pos, + rating: this.state.rating, + caption: this.props.caption, + name: this.props.name + }; - getClasses: function () { - var classes = ['react-star-rating__root']; + this.setState({ + ratingCache: ratingCache + }); - // is it disabled? - if (this.props.disabled) { - classes.push('rating-disabled'); + this.props.onRatingClick(e, ratingCache); } - - if (this.props.size) { - switch(this.props.size) { - case 'sm': - classes.push('react-star-rating__size--sm'); - break; - case 'md': - classes.push('react-star-rating__size--md'); - break; - case 'lg': - classes.push('react-star-rating__size--lg'); - break; - default: - break; + }, { + key: 'treatName', + value: function treatName(title) { + if (typeof title === 'string') { + return title.toLowerCase().split(' ').join('_'); } } + }, { + key: 'getClasses', + value: function getClasses() { + var classes = ['react-star-rating__root']; + + // is it disabled? + if (this.props.disabled) { + classes.push('rating-disabled'); + } - if (this.state.editing) { - classes.push('rating-editing'); - } - - return classes.join(' '); - }, + if (this.props.size) { + switch (this.props.size) { + case 'sm': + classes.push('react-star-rating__size--sm'); + break; + case 'md': + classes.push('react-star-rating__size--md'); + break; + case 'lg': + classes.push('react-star-rating__size--lg'); + break; + default: + break; + } + } - render: function () { + if (this.state.editing) { + classes.push('rating-editing'); + } - var caption = null; - - // is there a caption? - if (this.props.caption) { - caption = (React.createElement("span", {className: "react-rating-caption"}, this.props.caption)); + return classes.join(' '); } + }, { + key: 'render', + value: function render() { + + var caption = null; + + // is there a caption? + if (this.props.caption) { + caption = _react2['default'].createElement( + 'span', + { className: 'react-rating-caption' }, + this.props.caption + ); + } - // get the classes on this render - var classes = this.getClasses(); + // get the classes on this render + var classes = this.getClasses(); + + // are we editing this rating? + var starRating; + if (this.state.editing) { + starRating = _react2['default'].createElement( + 'div', + { ref: 'ratingContainer', className: 'rating-container rating-gly-star', 'data-content': this.state.glyph, onMouseMove: this.handleMouseMove.bind(this), onMouseLeave: this.handleMouseLeave.bind(this), onClick: this.handleClick.bind(this) }, + _react2['default'].createElement('div', { ref: 'ratingStars', className: 'rating-stars', 'data-content': this.state.glyph, style: { width: this.state.pos } }), + _react2['default'].createElement('input', { type: 'number', name: this.props.name, value: this.state.ratingCache.rating, style: { display: 'none !important' }, min: this.min, max: this.max, readOnly: true }) + ); + } else { + starRating = _react2['default'].createElement( + 'div', + { ref: 'ratingContainer', className: 'rating-container rating-gly-star', 'data-content': this.state.glyph }, + _react2['default'].createElement('div', { ref: 'ratingStars', className: 'rating-stars', 'data-content': this.state.glyph, style: { width: this.state.pos } }), + _react2['default'].createElement('input', { type: 'number', name: this.props.name, value: this.state.ratingCache.rating, style: { display: 'none !important' }, min: this.min, max: this.max, readOnly: true }) + ); + } - // are we editing this rating? - var starRating; - if (this.state.editing) { - starRating = ( - React.createElement("div", {ref: "ratingContainer", className: "rating-container rating-gly-star", "data-content": this.state.glyph, onMouseMove: this.handleMouseMove, onMouseLeave: this.handleMouseLeave, onClick: this.handleClick}, - React.createElement("div", {ref: "ratingStars", className: "rating-stars", "data-content": this.state.glyph, style: {width: this.state.pos}}), - React.createElement("input", {type: "number", name: this.props.name, value: this.state.ratingCache.rating, style: {display: 'none !important'}, min: this.min, max: this.max, readOnly: true}) - ) - ); - } else { - starRating = ( - React.createElement("div", {ref: "ratingContainer", className: "rating-container rating-gly-star", "data-content": this.state.glyph}, - React.createElement("div", {ref: "ratingStars", className: "rating-stars", "data-content": this.state.glyph, style: {width: this.state.pos}}), - React.createElement("input", {type: "number", name: this.props.name, value: this.state.ratingCache.rating, style: {display: 'none !important'}, min: this.min, max: this.max, readOnly: true}) + return _react2['default'].createElement( + 'span', + { className: 'react-star-rating' }, + caption, + _react2['default'].createElement( + 'span', + { ref: 'root', className: classes }, + starRating ) ); } - - return ( - React.createElement("span", {className: "react-star-rating"}, - caption, - React.createElement("span", {ref: "root", className: classes}, - starRating - ) - ) - ); - } -}); - -// {amd_end} \ No newline at end of file + }]); + + return StarRating; +})(_react2['default'].Component); + +StarRating.propTypes = { + name: _react2['default'].PropTypes.string.isRequired, + caption: _react2['default'].PropTypes.string, + ratingAmount: _react2['default'].PropTypes.number.isRequired, + rating: _react2['default'].PropTypes.number, + onRatingClick: _react2['default'].PropTypes.func, + disabled: _react2['default'].PropTypes.bool, + editing: _react2['default'].PropTypes.bool, + size: _react2['default'].PropTypes.string +}; + +StarRating.defaultProps = { + step: 0.5, + ratingAmount: 5, + onRatingClick: function onRatingClick() {}, + disabled: false +}; + +exports['default'] = StarRating; +module.exports = exports['default']; \ No newline at end of file diff --git a/dist/react-star-rating.min.js b/dist/react-star-rating.min.js index c9cd05a..94e3d3e 100644 --- a/dist/react-star-rating.min.js +++ b/dist/react-star-rating.min.js @@ -1 +1 @@ -var React=require("react");module.exports=React.createClass({displayName:"exports",propTypes:{name:React.PropTypes.string.isRequired,caption:React.PropTypes.string,ratingAmount:React.PropTypes.number.isRequired,rating:React.PropTypes.number,onRatingClick:React.PropTypes.func,disabled:React.PropTypes.bool,editing:React.PropTypes.bool,size:React.PropTypes.string},getStars:function(){for(var t="",e=this.props.ratingAmount,a=0;e>a;a++)t+="★";return t},getDefaultProps:function(){return{step:.5,ratingAmount:5,onRatingClick:function(){},disabled:!1}},getInitialState:function(){return{ratingCache:{pos:0,rating:0},editing:this.props.editing||!0,stars:5,rating:0,pos:0,glyph:this.getStars()}},componentWillMount:function(){if(this.min=0,this.max=this.props.ratingAmount||5,this.props.rating){this.state.editing=!1;var t=this.props.rating;this.setState({rating:t,pos:this.getStarRatingPosition(t)})}},componentDidMount:function(){this.root=this.refs.root.getDOMNode(),this.ratingStars=this.refs.ratingStars.getDOMNode(),this.ratingContainer=this.refs.ratingContainer.getDOMNode()},componentWillUnmount:function(){delete this.root,delete this.ratingStars,delete this.ratingContainer},getPosition:function(t){return t.pageX-this.root.getBoundingClientRect().left},applyPrecision:function(t,e){return parseFloat(t.toFixed(e))},getDecimalPlaces:function(t){var e=(""+t).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return e?Math.max(0,(e[1]?e[1].length:0)-(e[2]?+e[2]:0)):0},getWidthFromValue:function(t){var e=this.min,a=this.max;return e>=t||e===a?0:t>=a?100:100*(t-e)/(a-e)},getValueFromPosition:function(t){var e=this.getDecimalPlaces(this.props.step),a=this.ratingContainer.offsetWidth,i=this.max-this.min,n=i*t/(a*this.props.step);n=Math.ceil(n);var s=this.applyPrecision(parseFloat(this.min+n*this.props.step),e);return s=Math.max(Math.min(s,this.max),this.min)},calculate:function(t){var e=this.getValueFromPosition(t),a=this.getWidthFromValue(e);return a+="%",{width:a,val:e}},getStarRatingPosition:function(t){var e=this.getWidthFromValue(t);return e+="%"},getRatingEvent:function(t){var e=this.getPosition(t);return this.calculate(e)},handleMouseLeave:function(){this.setState({pos:this.state.ratingCache.pos,rating:this.state.ratingCache.rating})},handleMouseMove:function(t){var e=this.getRatingEvent(t);this.setState({pos:e.width,rating:e.val})},shouldComponentUpdate:function(t,e){return e.ratingCache.rating!==this.state.ratingCache.rating||e.rating!==this.state.rating},handleClick:function(t){if(this.props.disabled)return t.stopPropagation(),t.preventDefault(),!1;var e={pos:this.state.pos,rating:this.state.rating,caption:this.props.caption,name:this.props.name};this.setState({ratingCache:e}),this.props.onRatingClick(t,e)},treatName:function(t){return"string"==typeof t?t.toLowerCase().split(" ").join("_"):void 0},getClasses:function(){var t=["react-star-rating__root"];if(this.props.disabled&&t.push("rating-disabled"),this.props.size)switch(this.props.size){case"sm":t.push("react-star-rating__size--sm");break;case"md":t.push("react-star-rating__size--md");break;case"lg":t.push("react-star-rating__size--lg")}return this.state.editing&&t.push("rating-editing"),t.join(" ")},render:function(){var t=null;this.props.caption&&(t=React.createElement("span",{className:"react-rating-caption"},this.props.caption));var e,a=this.getClasses();return e=this.state.editing?React.createElement("div",{ref:"ratingContainer",className:"rating-container rating-gly-star","data-content":this.state.glyph,onMouseMove:this.handleMouseMove,onMouseLeave:this.handleMouseLeave,onClick:this.handleClick},React.createElement("div",{ref:"ratingStars",className:"rating-stars","data-content":this.state.glyph,style:{width:this.state.pos}}),React.createElement("input",{type:"number",name:this.props.name,value:this.state.ratingCache.rating,style:{display:"none !important"},min:this.min,max:this.max,readOnly:!0})):React.createElement("div",{ref:"ratingContainer",className:"rating-container rating-gly-star","data-content":this.state.glyph},React.createElement("div",{ref:"ratingStars",className:"rating-stars","data-content":this.state.glyph,style:{width:this.state.pos}}),React.createElement("input",{type:"number",name:this.props.name,value:this.state.ratingCache.rating,style:{display:"none !important"},min:this.min,max:this.max,readOnly:!0})),React.createElement("span",{className:"react-star-rating"},t,React.createElement("span",{ref:"root",className:a},e))}}); \ No newline at end of file +"use strict";function _interopRequireDefault(t){return t&&t.__esModule?t:{"default":t}}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(t.__proto__=e)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function t(t,e){for(var a=0;aa;a++)t+="★";return t}},{key:"componentWillMount",value:function(){if(this.min=0,this.max=this.props.ratingAmount||5,this.props.rating){this.state.editing=!1;var t=this.props.rating;this.setState({rating:t,pos:this.getStarRatingPosition(t)})}}},{key:"componentDidMount",value:function(){this.root=this.refs.root.getDOMNode(),this.ratingStars=this.refs.ratingStars.getDOMNode(),this.ratingContainer=this.refs.ratingContainer.getDOMNode()}},{key:"componentWillUnmount",value:function(){delete this.root,delete this.ratingStars,delete this.ratingContainer}},{key:"getPosition",value:function(t){return t.pageX-this.root.getBoundingClientRect().left}},{key:"applyPrecision",value:function(t,e){return parseFloat(t.toFixed(e))}},{key:"getDecimalPlaces",value:function(t){var e=(""+t).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return e?Math.max(0,(e[1]?e[1].length:0)-(e[2]?+e[2]:0)):0}},{key:"getWidthFromValue",value:function(t){var e=this.min,a=this.max;return e>=t||e===a?0:t>=a?100:100*(t-e)/(a-e)}},{key:"getValueFromPosition",value:function(t){var e=this.getDecimalPlaces(this.props.step),a=this.ratingContainer.offsetWidth,i=this.max-this.min,n=i*t/(a*this.props.step);n=Math.ceil(n);var r=this.applyPrecision(parseFloat(this.min+n*this.props.step),e);return r=Math.max(Math.min(r,this.max),this.min)}},{key:"calculate",value:function(t){var e=this.getValueFromPosition(t),a=this.getWidthFromValue(e);return a+="%",{width:a,val:e}}},{key:"getStarRatingPosition",value:function(t){var e=this.getWidthFromValue(t)+"%";return e}},{key:"getRatingEvent",value:function(t){var e=this.getPosition(t);return this.calculate(e)}},{key:"handleMouseLeave",value:function(){this.setState({pos:this.state.ratingCache.pos,rating:this.state.ratingCache.rating})}},{key:"handleMouseMove",value:function(t){var e=this.getRatingEvent(t);this.setState({pos:e.width,rating:e.val})}},{key:"shouldComponentUpdate",value:function(t,e){return e.ratingCache.rating!==this.state.ratingCache.rating||e.rating!==this.state.rating}},{key:"handleClick",value:function(t){if(this.props.disabled)return t.stopPropagation(),t.preventDefault(),!1;var e={pos:this.state.pos,rating:this.state.rating,caption:this.props.caption,name:this.props.name};this.setState({ratingCache:e}),this.props.onRatingClick(t,e)}},{key:"treatName",value:function(t){return"string"==typeof t?t.toLowerCase().split(" ").join("_"):void 0}},{key:"getClasses",value:function(){var t=["react-star-rating__root"];if(this.props.disabled&&t.push("rating-disabled"),this.props.size)switch(this.props.size){case"sm":t.push("react-star-rating__size--sm");break;case"md":t.push("react-star-rating__size--md");break;case"lg":t.push("react-star-rating__size--lg")}return this.state.editing&&t.push("rating-editing"),t.join(" ")}},{key:"render",value:function(){var t=null;this.props.caption&&(t=_react2["default"].createElement("span",{className:"react-rating-caption"},this.props.caption));var e,a=this.getClasses();return e=this.state.editing?_react2["default"].createElement("div",{ref:"ratingContainer",className:"rating-container rating-gly-star","data-content":this.state.glyph,onMouseMove:this.handleMouseMove.bind(this),onMouseLeave:this.handleMouseLeave.bind(this),onClick:this.handleClick.bind(this)},_react2["default"].createElement("div",{ref:"ratingStars",className:"rating-stars","data-content":this.state.glyph,style:{width:this.state.pos}}),_react2["default"].createElement("input",{type:"number",name:this.props.name,value:this.state.ratingCache.rating,style:{display:"none !important"},min:this.min,max:this.max,readOnly:!0})):_react2["default"].createElement("div",{ref:"ratingContainer",className:"rating-container rating-gly-star","data-content":this.state.glyph},_react2["default"].createElement("div",{ref:"ratingStars",className:"rating-stars","data-content":this.state.glyph,style:{width:this.state.pos}}),_react2["default"].createElement("input",{type:"number",name:this.props.name,value:this.state.ratingCache.rating,style:{display:"none !important"},min:this.min,max:this.max,readOnly:!0})),_react2["default"].createElement("span",{className:"react-star-rating"},t,_react2["default"].createElement("span",{ref:"root",className:a},e))}}]),e}(_react2["default"].Component);StarRating.propTypes={name:_react2["default"].PropTypes.string.isRequired,caption:_react2["default"].PropTypes.string,ratingAmount:_react2["default"].PropTypes.number.isRequired,rating:_react2["default"].PropTypes.number,onRatingClick:_react2["default"].PropTypes.func,disabled:_react2["default"].PropTypes.bool,editing:_react2["default"].PropTypes.bool,size:_react2["default"].PropTypes.string},StarRating.defaultProps={step:.5,ratingAmount:5,onRatingClick:function(){},disabled:!1},exports["default"]=StarRating,module.exports=exports["default"]; \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 0c15102..d895186 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -5,102 +5,125 @@ var gulp = require('gulp'); var source = require('vinyl-source-stream'); var browserify = require('browserify'); var babelify = require('babelify'); -var reactify = require('reactify'); +var babel = require('gulp-babel'); var server = require('gulp-webserver'); var sass = require('gulp-sass'); var concat = require('gulp-concat'); var rename = require('gulp-rename'); -var react = require('gulp-react'); var uglify = require('gulp-uglify'); -var jshint = require('gulp-jshint'); +var eslint = require('gulp-eslint'); var replace = require('gulp-replace'); +var minifyCSS = require('gulp-minify-css'); +var config = { + componentFileName: 'react-star-rating', + componentSrc: './src/StarRating.jsx', + componentStylesDir: './src/sass', + stylesDest: './dist/css' +}; + +/** + * Lint + */ gulp.task('lint', function () { return gulp.src('./src/**/*.{jsx, js}') - .pipe(react()) - .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')); + .pipe(eslint({ + useEslintrc: true + })) + .pipe(eslint.format()) + .pipe(eslint.failOnError()); }); +/** + * Styles + */ gulp.task('styles', function () { - return gulp.src('./src/sass/*.scss') + return gulp.src(config.componentStylesDir + '/' + config.componentFileName + '.scss') .pipe(sass({ includePaths: require('node-bourbon').includePaths })) - .pipe(gulp.dest('./dist/css')); + .pipe(gulp.dest(config.stylesDest)) + .pipe(minifyCSS()) + .pipe(rename(config.componentFileName + '.min.css')) + .pipe(gulp.dest(config.stylesDest)); }); -gulp.task('build:styles', function () { - return gulp.src('./src/sass/react-star-rating.scss') - .pipe(sass({ - includePaths: require('node-bourbon').includePaths, - outputStyle: 'compressed' - })) - .pipe(rename('react-star-rating.min.css')) - .pipe(gulp.dest('./dist/css')); -}); - -gulp.task('build:npm', function () { - return gulp.src('./src/StarRating.jsx') - .pipe(react()) - .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')) - .pipe(rename('react-star-rating.js')) +/** + * Build + */ +gulp.task('build', ['lint'], function () { + return gulp.src(config.componentSrc) + .pipe(babel()) + .pipe(rename(config.componentFileName + '.js')) .pipe(gulp.dest('dist')) - .pipe(rename('react-star-rating.min.js')) + .pipe(rename(config.componentFileName + '.min.js')) .pipe(uglify()) .pipe(gulp.dest('dist')); }); -gulp.task('replace-scripts', function () { - return gulp.src('./src/StarRating.jsx') - .pipe(react()) - .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')) - .pipe(rename('react-star-rating.js')) - .pipe(replace(/module.exports/g, 'window.StarRating')) - .pipe(gulp.dest('dist/browser')) - .pipe(replace(/window.StarRating/g, 'module.exports')) - .pipe(replace(/\/\/ \{amd_start\}/, 'define(function(require,exports,module){')) - .pipe(replace(/\/\/ \{amd_end\}/, '});')) - .pipe(gulp.dest('dist/amd')); -}); +/** + * hacky, don't use !!!![Deprecated]!!!!! + */ +// gulp.task('replace-scripts', function () { +// return gulp.src('./src/StarRating.jsx') +// .pipe(babel()) +// .pipe(jshint()) +// .pipe(jshint.reporter('jshint-stylish')) +// .pipe(rename('react-star-rating.js')) +// .pipe(replace(/module.exports/g, 'window.StarRating')) +// .pipe(gulp.dest('dist/browser')) +// .pipe(replace(/window.StarRating/g, 'module.exports')) +// .pipe(replace(/\/\/ \{amd_start\}/, 'define(function(require,exports,module){')) +// .pipe(replace(/\/\/ \{amd_end\}/, '});')) +// .pipe(gulp.dest('dist/amd')); +// }); -gulp.task('build:browser', ['replace-scripts'], function () { - // amd - gulp.src('./dist/amd/react-star-rating.js') - .pipe(rename('react-star-rating.min.js')) - .pipe(uglify()) - .on('error', function (err) { - console.log(err); - }) - .pipe(gulp.dest('dist/amd')); - // browser - gulp.src('./dist/browser/react-star-rating.js') - .pipe(rename('react-star-rating.min.js')) - .pipe(uglify()) - .on('error', function (err) { - console.log(err); - }) - .pipe(gulp.dest('dist/browser')); -}); +/** + * Browser !!!![Deprecated]!!!!! + */ +// gulp.task('build:browser', ['replace-scripts'], function () { +// // amd +// gulp.src('./dist/amd/react-star-rating.js') +// .pipe(rename('react-star-rating.min.js')) +// .pipe(uglify()) +// .on('error', function (err) { +// console.log(err); +// }) +// .pipe(gulp.dest('dist/amd')); +// // browser +// gulp.src('./dist/browser/react-star-rating.js') +// .pipe(rename('react-star-rating.min.js')) +// .pipe(uglify()) +// .on('error', function (err) { +// console.log(err); +// }) +// .pipe(gulp.dest('dist/browser')); +// }); +/** + * Bundle + */ gulp.task('default', ['lint','styles'], function () { - return browserify('./src/index.jsx') - .transform(reactify) + return browserify('./src/index.jsx', {extensions: '.jsx'}) + .transform(babelify) .bundle() .on('error', function (err) { + console.log(err); console.log(err.fileName, err.lineNumber, err.description); }) .pipe(source('bundle.js')) - .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')) .pipe(gulp.dest('dist/demo')); }); +/** + * Watch + */ gulp.task('watch', ['default'], function () { gulp.watch(['./src/*.js', './src/**/*.jsx', './src/sass/{*/,}*.scss'], ['dist']); return gulp.src('.').pipe(server()); }); -gulp.task('dist', ['default', 'build:styles', 'build:npm', 'build:browser']); +/** + * Dist + */ +gulp.task('dist', ['default', 'styles', 'build']); diff --git a/package.json b/package.json index 2ae57ac..3b59c15 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "version": "1.1.4", "description": "A simple star rating component built with React.", "main": "dist/react-star-rating.min.js", - "scripts": {}, + "scripts": { + "watch": "gulp watch" + }, "author": "Cameron J Roe (http://cameronjroe.com/)", "license": "MIT", "peerDependencies": { @@ -13,8 +15,11 @@ "babelify": "^5.0.4", "browserify": "^9.0.3", "gulp": "^3.8.11", + "gulp-babel": "^5.1.0", "gulp-concat": "^2.5.2", + "gulp-eslint": "^0.12.0", "gulp-jshint": "^1.9.2", + "gulp-minify-css": "^1.1.1", "gulp-react": "^3.0.0", "gulp-rename": "^1.2.0", "gulp-replace": "^0.5.3", diff --git a/src/StarRating.jsx b/src/StarRating.jsx index 54a11f9..9bb7458 100644 --- a/src/StarRating.jsx +++ b/src/StarRating.jsx @@ -1,6 +1,4 @@ -// {amd_start} - -var React = require('react'); +import React from 'react'; /** * @fileoverview react-star-rating @@ -16,55 +14,35 @@ var React = require('react'); * onRatingClick={function} - a handler function that gets called onClick of the rating (optional) * /> */ -module.exports = React.createClass({ - - propTypes: { - name: React.PropTypes.string.isRequired, - caption: React.PropTypes.string, - ratingAmount: React.PropTypes.number.isRequired, - rating: React.PropTypes.number, - onRatingClick: React.PropTypes.func, - disabled: React.PropTypes.bool, - editing: React.PropTypes.bool, - size: React.PropTypes.string - }, - - getStars: function () { - var stars = ''; - var numRating = this.props.ratingAmount; - for(var i = 0; i < numRating; i++) { - stars += '\u2605'; - } - return stars; - }, - - getDefaultProps: function () { - return { - step: 0.5, - ratingAmount: 5, - onRatingClick: function () {}, - disabled: false - }; - }, +class StarRating extends React.Component { - getInitialState: function () { - return { + constructor(props) { + super(props); + this.state = { ratingCache: { pos: 0, rating: 0 }, - editing: this.props.editing || true, + editing: props.editing || true, stars: 5, rating: 0, pos: 0, glyph: this.getStars() }; - }, + } - componentWillMount: function () { + getStars() { + var stars = ''; + var numRating = this.props.ratingAmount; + for(var i = 0; i < numRating; i++) { + stars += '\u2605'; + } + return stars; + } + + componentWillMount() { this.min = 0; this.max = this.props.ratingAmount || 5; - if (this.props.rating) { this.state.editing = false; @@ -75,35 +53,34 @@ module.exports = React.createClass({ pos: this.getStarRatingPosition(ratingVal) }); } + } - }, - - componentDidMount: function () { + componentDidMount() { this.root = this.refs.root.getDOMNode(); this.ratingStars = this.refs.ratingStars.getDOMNode(); this.ratingContainer = this.refs.ratingContainer.getDOMNode(); - }, + } - componentWillUnmount: function () { + componentWillUnmount() { delete this.root; delete this.ratingStars; delete this.ratingContainer; - }, + } - getPosition: function (e) { + getPosition(e) { return e.pageX - this.root.getBoundingClientRect().left; - }, + } - applyPrecision: function (val, precision) { + applyPrecision(val, precision) { return parseFloat(val.toFixed(precision)); - }, + } - getDecimalPlaces: function (num) { + getDecimalPlaces(num) { var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); return !match ? 0 : Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); - }, + } - getWidthFromValue: function (val) { + getWidthFromValue(val) { var min = this.min, max = this.max; if (val <= min || min === max) { @@ -113,9 +90,9 @@ module.exports = React.createClass({ return 100; } return (val - min) * 100 / (max - min); - }, + } - getValueFromPosition: function (pos) { + getValueFromPosition(pos) { var precision = this.getDecimalPlaces(this.props.step); var maxWidth = this.ratingContainer.offsetWidth; var diff = this.max - this.min; @@ -124,47 +101,47 @@ module.exports = React.createClass({ var val = this.applyPrecision(parseFloat(this.min + factor * this.props.step), precision); val = Math.max(Math.min(val, this.max), this.min); return val; - }, + } - calculate: function (pos) { + calculate(pos) { var val = this.getValueFromPosition(pos), width = this.getWidthFromValue(val); width += '%'; return {width: width, val: val}; - }, + } - getStarRatingPosition: function (val) { - var width = this.getWidthFromValue(val); - return width += '%'; - }, + getStarRatingPosition(val) { + var width = this.getWidthFromValue(val) + '%'; + return width; + } - getRatingEvent: function (e) { + getRatingEvent(e) { var pos = this.getPosition(e); return this.calculate(pos); - }, + } - handleMouseLeave: function () { + handleMouseLeave() { this.setState({ pos: this.state.ratingCache.pos, rating: this.state.ratingCache.rating }); - }, + } - handleMouseMove: function (e) { + handleMouseMove(e) { // get hover position var ratingEvent = this.getRatingEvent(e); this.setState({ pos: ratingEvent.width, rating: ratingEvent.val }); - }, + } - shouldComponentUpdate: function (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return nextState.ratingCache.rating !== this.state.ratingCache.rating || nextState.rating !== this.state.rating; - }, + } - handleClick: function (e) { + handleClick(e) { // is it disabled? if (this.props.disabled) { @@ -185,15 +162,15 @@ module.exports = React.createClass({ }); this.props.onRatingClick(e, ratingCache); - }, + } - treatName: function (title) { + treatName(title) { if (typeof title === 'string') { return title.toLowerCase().split(' ').join('_'); } - }, + } - getClasses: function () { + getClasses() { var classes = ['react-star-rating__root']; // is it disabled? @@ -222,9 +199,9 @@ module.exports = React.createClass({ } return classes.join(' '); - }, + } - render: function () { + render() { var caption = null; @@ -240,7 +217,7 @@ module.exports = React.createClass({ var starRating; if (this.state.editing) { starRating = ( -
+
@@ -263,6 +240,24 @@ module.exports = React.createClass({ ); } -}); - -// {amd_end} \ No newline at end of file +} + +StarRating.propTypes = { + name: React.PropTypes.string.isRequired, + caption: React.PropTypes.string, + ratingAmount: React.PropTypes.number.isRequired, + rating: React.PropTypes.number, + onRatingClick: React.PropTypes.func, + disabled: React.PropTypes.bool, + editing: React.PropTypes.bool, + size: React.PropTypes.string +}; + +StarRating.defaultProps = { + step: 0.5, + ratingAmount: 5, + onRatingClick() {}, + disabled: false +}; + +export default StarRating; diff --git a/src/index.jsx b/src/index.jsx index a9351c8..0951670 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,20 +1,20 @@ -var React = require('react'); -var StarRating = require('./StarRating.jsx'); -var pkg = require('../package.json'); +import React from 'react'; +import StarRating from './StarRating'; +import pkg from '../package.json'; var inject = document.querySelector('.inject'); -var App = React.createClass({ +class App extends React.Component { - handleRatingClick: function (e, data) { + handleRatingClick(e, data) { alert('You left a ' + data.rating + ' star rating for ' + data.name); - }, + } - render: function () { + render() { var currentVersion = pkg.version; return ( -
+

{'react-star-rating'} @@ -26,34 +26,38 @@ var App = React.createClass({

Installation


-

You can install react-star-rating with npm or bower.

-

CommonJS/Browserify

{'$ npm install react-star-rating --save'} -

Bower/AMD

- -

{'$ bower install react-star-rating --save'}

-

{'\n'}

-

{'var StarRating = require(\'react-star-rating/dist/amd/react-star-rating\');'}

-
-

Browser Global

-

The bower repo contains react-star-rating.js and react-star-rating.min.js with a global object accessible from window.StarRating.

- -

{''}

-

{''}

-

{''}

-

{''}

-

Usage


+

ES6

+

{'import React from \'react\''}

+

{'import StarRating from \'react-star-rating\''}

+

{' '}

+

{'class FormComponent extends React.Component {'}

+

{' render() { '}

+

{' return ('}

+

{'

'}

+

{' '}

+

{' '}

+

{'

'}

+

{' );'}

+

{' }'}

+

{'}'}

+

{' '}

+

{'React.render(, document.getElementById(\'star-rating\'));'}

+
+

ES5/Browserify

+ +

{'var React = require(\'react\');'}

+

{'var StarRating = require(\'react-star-rating\');'}

+

{' '}

{'var FormComponent = React.createClass({'}

{' render: function () { '}

{' return ('}

@@ -65,7 +69,7 @@ var App = React.createClass({

{' }'}

{'});'}

{' '}

-

{'React.render(, document.getElementById(\'star-rating\')'}

+

{'React.render(, document.getElementById(\'star-rating\'));'}

Options


@@ -81,17 +85,19 @@ var App = React.createClass({

Examples


- +

-

{''}

+

{'// handler in react class'}

+

{'handleRatingClick: function (e, data) {'}

+

{' alert(\'You left a \' + data.rating + \' star rating for \' + data.caption);'}

+

{'}'}

+

{' '}

{''}

- +

+
{'If you\'re using ES6, make sure to bind the handler: '}{'this.handleRatingClick.bind(this, pass, args, here)'}
+ {''} @@ -122,10 +128,10 @@ var App = React.createClass({

Created by @cameronjroe -

-

+
); } -}); +} -React.render(, inject); \ No newline at end of file +React.render(, inject);