react-star-rating
Advanced tools
Comparing version 1.3.2 to 1.4.0
@@ -1,4 +0,3 @@ | ||
/** | ||
* Gulp | ||
*/ | ||
'use strict'; | ||
var gulp = require('gulp'); | ||
@@ -17,2 +16,3 @@ var source = require('vinyl-source-stream'); | ||
var minifyCSS = require('gulp-minify-css'); | ||
var karma = require('gulp-karma'); | ||
@@ -52,10 +52,2 @@ var config = { | ||
gulp.task('demo-styles', function () { | ||
return gulp.src(config.componentStylesDir + '/demo.scss') | ||
.pipe(sass({ | ||
includePaths: require('node-bourbon').includePaths | ||
})) | ||
.pipe(gulp.dest(config.stylesDest)); | ||
}); | ||
/** | ||
@@ -75,5 +67,16 @@ * Build | ||
/** | ||
* Demo Styles | ||
*/ | ||
gulp.task('demo-styles', function () { | ||
return gulp.src(config.componentStylesDir + '/demo.scss') | ||
.pipe(sass({ | ||
includePaths: require('node-bourbon').includePaths | ||
})) | ||
.pipe(gulp.dest(config.stylesDest)); | ||
}); | ||
/** | ||
* Demo Bundle | ||
*/ | ||
gulp.task('default', ['lint','styles'], function () { | ||
gulp.task('default', ['lint', 'styles'], function () { | ||
return browserify('./src/docs.jsx', {extensions: '.jsx'}) | ||
@@ -94,3 +97,5 @@ .transform(babelify) | ||
gulp.watch(['./src/*.js', './src/**/*.jsx', './src/sass/{*/,}*.scss'], ['dist']); | ||
return gulp.src('.').pipe(server()); | ||
return gulp.src('.').pipe(server({ | ||
port: 3000 | ||
})); | ||
}); | ||
@@ -97,0 +102,0 @@ |
{ | ||
"name": "react-star-rating", | ||
"version": "1.3.2", | ||
"version": "1.4.0", | ||
"description": "A simple star rating component built with React.", | ||
"main": "./dist/react-star-rating.min.js", | ||
"scripts": { | ||
"watch": "gulp watch" | ||
"start": "npm run watch", | ||
"watch": "gulp watch", | ||
"build": "gulp dist", | ||
"test": "karma start", | ||
"dev": "webpack-dev-server --progress --colors --hot --inline --no-info" | ||
}, | ||
"author": "Cameron J Roe <cameronjroe@gmail.com> (http://cameronjroe.com/)", | ||
"license": "MIT", | ||
"peerDependencies": { | ||
"react": "^0.13.0" | ||
"dependencies": { | ||
"classnames": "^2.2.0", | ||
"react": "^0.14.2", | ||
"react-addons-test-utils": "^0.14.2", | ||
"react-dom": "^0.14.2" | ||
}, | ||
"devDependencies": { | ||
"babel-eslint": "^3.1.23", | ||
"babelify": "^6.1.3", | ||
"browserify": "^11.0.0", | ||
"babel-eslint": "^4.1.4", | ||
"babel-preset-es2015": "^6.0.15", | ||
"babel-preset-react": "^6.0.15", | ||
"babel-preset-stage-0": "^6.1.2", | ||
"babelify": "^7.2.0", | ||
"browserify": "^12.0.1", | ||
"chai": "^3.4.0", | ||
"css-loader": "^0.22.0", | ||
"gulp": "^3.9.0", | ||
"gulp-babel": "^5.1.0", | ||
"gulp-babel": "^6.0.0", | ||
"gulp-concat": "^2.6.0", | ||
"gulp-eslint": "^0.15.0", | ||
"gulp-jshint": "^1.11.2", | ||
"gulp-minify-css": "^1.2.0", | ||
"gulp-eslint": "^1.0.0", | ||
"gulp-jshint": "^1.12.0", | ||
"gulp-karma": "0.0.5", | ||
"gulp-minify-css": "^1.2.1", | ||
"gulp-rename": "^1.2.2", | ||
"gulp-replace": "^0.5.3", | ||
"gulp-sass": "^2.0.4", | ||
"gulp-uglify": "^1.2.0", | ||
"gulp-replace": "^0.5.4", | ||
"gulp-sass": "^2.1.0", | ||
"gulp-uglify": "^1.4.2", | ||
"gulp-webserver": "^0.9.1", | ||
"isparta": "^3.5.1", | ||
"istanbul-instrumenter-loader": "^0.1.3", | ||
"jshint-stylish": "^2.0.1", | ||
"jsxhint-loader": "^0.2.0", | ||
"karma": "^0.13.15", | ||
"karma-chai": "^0.1.0", | ||
"karma-chrome-launcher": "^0.2.1", | ||
"karma-coverage": "^0.5.3", | ||
"karma-mocha": "^0.2.0", | ||
"karma-sinon": "^1.0.4", | ||
"karma-sourcemap-loader": "^0.3.6", | ||
"karma-webpack": "^1.7.0", | ||
"mocha": "^2.3.3", | ||
"node-bourbon": "^4.2.3", | ||
"node-sass": "^3.4.1", | ||
"sass-loader": "^3.1.1", | ||
"sinon": "^1.17.2", | ||
"style-loader": "^0.13.0", | ||
"through2": "^2.0.0", | ||
"vinyl-source-stream": "^1.1.0" | ||
}, | ||
"dependencies": { | ||
"classnames": "^2.1.3" | ||
"vinyl-source-stream": "^1.1.0", | ||
"webpack": "^1.12.2" | ||
} | ||
} |
@@ -1,3 +0,5 @@ | ||
# react-star-rating [](http://forthebadge.com) | ||
# react-star-rating  | ||
[](https://nodei.co/npm/react-star-rating/) | ||
<!-- [](https://travis-ci.org/) --> | ||
@@ -8,2 +10,4 @@  | ||
## v1.4.0 coming soon. | ||
## Install | ||
@@ -57,7 +61,7 @@ | ||
- **caption**={string} - caption for rating (optional) | ||
- **ratingAmount**={number} - rating amount (required, default: 5) | ||
- **totalStars**={number} - rating amount (required, default: 5) | ||
- **rating**={number} - a set rating between the rating amount (optional) | ||
- **disabled**={boolean} - whether to disable the rating from being selected (optional) | ||
- **editing**={boolean} - whether the rating is explicitly in editing mode (optional) | ||
- **size**={string} - size of stars (optional) | ||
- **size**={number} - size of stars (optional) | ||
- **onRatingClick**={function} - a handler function that gets called onClick of the rating (optional) - gets passed (event, {position, rating, caption, name}) | ||
@@ -68,5 +72,5 @@ | ||
- [x] Fix ES6 bug with bundling | ||
- [ ] Add svg stars | ||
- [x] Add svg stars | ||
- [x] Double-check touch support works | ||
- [ ] Re-implement star hovering (kinda janky right now) | ||
- [ ] Double-check touch support works | ||
@@ -73,0 +77,0 @@ |
@@ -0,2 +1,4 @@ | ||
'use strict'; | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import StarRating from './StarRating'; | ||
@@ -10,2 +12,3 @@ import pkg from '../package'; | ||
handleRatingClick(e, data) { | ||
console.log(data); | ||
alert('You left a ' + data.rating + ' star rating for ' + data.name); | ||
@@ -22,5 +25,5 @@ } | ||
{'react-star-rating'} | ||
<small> easy star ratings with React</small> | ||
<small> easy star ratings with Test</small> | ||
</h1> | ||
<StarRating name="hotels" size="md" rating={5} editing={true} ratingAmount={5} step={1} /> | ||
<StarRating name="hotels" size={50} rating={5} editing={false} totalStars={5} step={1} /> | ||
<p style={{marginBottom: '10px'}}>v{currentVersion}</p> | ||
@@ -38,3 +41,3 @@ <a href="https://github.com/cameronjroe/react-star-rating" className="btn btn-primary">View on Github</a> | ||
<form target="_self" method="GET" className="demo-form"> | ||
<StarRating name="react-star-rating" caption="Rate this component!" ratingAmount={5} /> | ||
<StarRating name="react-star-rating" caption="Rate this component!" totalStars={5} /> | ||
<button type="submit" className="btn btn-primary">Submit Rating</button> | ||
@@ -51,3 +54,3 @@ </form> | ||
<p>{' <form target="_self" method="GET">'}</p> | ||
<p>{' <StarRating name="react-star-rating" caption="Rate this component!" ratingAmount={5} />'}</p> | ||
<p>{' <StarRating name="react-star-rating" caption="Rate this component!" totalStars={5} />'}</p> | ||
<p>{' <button type="submit" className="btn btn-primary">Submit Rating</button>'}</p> | ||
@@ -70,3 +73,3 @@ <p>{' </form>'}</p> | ||
<p>{' <form target="_self" method="GET">'}</p> | ||
<p>{' <StarRating name="react-star-rating" caption="Rate this component!" ratingAmount={5} />'}</p> | ||
<p>{' <StarRating name="react-star-rating" caption="Rate this component!" totalStars={5} />'}</p> | ||
<p>{' <button type="submit" className="btn btn-primary">Submit Rating</button>'}</p> | ||
@@ -85,7 +88,7 @@ <p>{' </form>'}</p> | ||
<li><strong>caption</strong>{'={string} - caption for rating (optional)'}</li> | ||
<li><strong>ratingAmount</strong>{'={number} - rating amount (required, default: 5)'}</li> | ||
<li><strong>totalStars</strong>{'={number} - rating amount (required, default: 5)'}</li> | ||
<li><strong>rating</strong>{'={number} - a set rating between the rating amount (optional)'}</li> | ||
<li><strong>disabled</strong>{'={boolean} - whether to disable the rating from being selected (optional)'}</li> | ||
<li><strong>editing</strong>{'={boolean} - whether the rating is explicitly in editing mode (optional)'}</li> | ||
<li><strong>size</strong>{'={string} - size of stars (optional)'}</li> | ||
<li><strong>size</strong>{'={number} - size of stars (optional)'}</li> | ||
<li><strong>onRatingClick</strong>{'={function} - a handler function that gets called onClick of the rating (optional) - gets passed (event, {position, rating, caption, name})'}</li> | ||
@@ -95,3 +98,3 @@ </ul> | ||
<hr/> | ||
<StarRating name="handler" caption="Use onClick Handlers!" ratingAmount={5} step={0.5} onRatingClick={this.handleRatingClick.bind(this)} /> | ||
<StarRating name="handler" caption="Use onClick Handlers!" totalStars={5} onRatingClick={this.handleRatingClick.bind(this)} /> | ||
<p></p> | ||
@@ -104,36 +107,40 @@ <code> | ||
<p>{' '}</p> | ||
<p>{'<StarRating name="handler" caption="Use onClick Handlers!" ratingAmount={5} step={0.5} onRatingClick={handleRatingClick} />'}</p> | ||
<p>{'<StarRating name="handler" caption="Use onClick Handlers!" totalStars={5} onRatingClick={handleRatingClick} />'}</p> | ||
</code> | ||
<p></p> | ||
<blockquote><strong>{'If you\'re using ES6, make sure to bind the handler: '}</strong><code>{'this.handleRatingClick.bind(this, pass, args, here)'}</code></blockquote> | ||
<StarRating name="ten-stars" caption="Configure number of stars!" ratingAmount={10} step={1} onRatingClick={this.handleRatingClick.bind(this)} /> | ||
<StarRating name="ten-stars" caption="Configure number of stars!" totalStars={10} step={1} onRatingClick={this.handleRatingClick.bind(this)} /> | ||
<code> | ||
{'<StarRating name="ten-stars" caption="Configure number of stars!" ratingAmount={10} step={1} onRatingClick={this.handleRatingClick} />'} | ||
{'<StarRating name="ten-stars" caption="Configure number of stars!" totalStars={10} step={1} onRatingClick={this.handleRatingClick} />'} | ||
</code> | ||
<StarRating name="half-stars" caption="Use half-star steps!" ratingAmount={5} /> | ||
{/*<StarRating name="half-stars" caption="Use half-star steps!" totalStars={5} /> | ||
<code> | ||
{'<StarRating name="half-stars" caption="Use half-star steps!" ratingAmount={5} />'} | ||
{'<StarRating name="half-stars" caption="Use half-star steps!" totalStars={5} />'} | ||
</code>*/} | ||
<StarRating name="small-rating" caption="Small!" size={30} totalStars={5} rating={3} /> | ||
<code> | ||
{'<StarRating name="small-rating" caption="Small!" size={30} totalStars={5} rating={3} />'} | ||
</code> | ||
<StarRating name="small-rating" caption="Small!" size="sm" ratingAmount={5} rating={3} /> | ||
<StarRating name="medium-rating" caption="Medium!" size={50} totalStars={5} rating={4} /> | ||
<code> | ||
{'<StarRating name="small-rating" caption="Small!" size="sm" ratingAmount={5} rating={3} />'} | ||
{'<StarRating name="medium-rating" caption="Medium!" size={50} totalStars={5} rating={4} />'} | ||
</code> | ||
<StarRating name="medium-rating" caption="Medium!" size="md" ratingAmount={5} rating={4} /> | ||
<StarRating name="large-rating" caption="Large!" size={70} totalStars={5} rating={5} /> | ||
<code> | ||
{'<StarRating name="medium-rating" caption="Medium!" size="md" ratingAmount={5} rating={4} />'} | ||
{'<StarRating name="large-rating" caption="Large!" size={70} totalStars={5} rating={5} />'} | ||
</code> | ||
<StarRating name="large-rating" caption="Large!" size="lg" ratingAmount={5} rating={5} /> | ||
<StarRating name="jumbo-rating" caption="Jumbo!" size={100} totalStars={5} rating={5} /> | ||
<code> | ||
{'<StarRating name="large-rating" caption="Large!" size="lg" ratingAmount={5} rating={5} />'} | ||
{'<StarRating name="jumbo-rating" caption="Jumbo!" size={100} totalStars={5} rating={5} />'} | ||
</code> | ||
<StarRating name="disabled" caption="Disabled." ratingAmount={5} rating={3} disabled={true} /> | ||
<StarRating name="disabled" caption="Disabled." totalStars={5} rating={3} disabled={true} /> | ||
<code> | ||
{'<StarRating name="disabled" caption="Disabled." ratingAmount={5} rating={3} disabled={true} />'} | ||
{'<StarRating name="disabled" caption="Disabled." totalStars={5} rating={3} disabled={true} />'} | ||
</code> | ||
</div> | ||
<footer> | ||
<p className="footer-creds"> | ||
<div className="footer-creds"> | ||
<p>Code licensed under <a href="https://github.com/cameronjroe/react-star-rating/blob/master/LICENSE">MIT</a> - Currently v{currentVersion} - <a href="https://github.com/cameronjroe/react-star-rating">Github Repo</a></p> | ||
<p>Created by <a href="http://twitter.com/cameronjroe">@cameronjroe</a> - <iframe src="https://ghbtns.com/github-btn.html?user=cameronjroe&type=follow&count=true" frameBorder="0" scrolling="0" width="170px" height="20px"></iframe></p> | ||
</p> | ||
</div> | ||
</footer> | ||
@@ -146,2 +153,2 @@ </section> | ||
React.render(<App />, inject); | ||
ReactDOM.render(<App />, inject); |
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import cx from 'classnames'; | ||
function isFloat(n) { | ||
return n === Number(n) && n % 1 !== 0; | ||
} | ||
// TODO | ||
// - Add support for svg symbol | ||
// - Add svg masking when react supports it | ||
// - Update onClick to onSelect which supports mobile, desktop | ||
// - Add onChange to trigger function when rating changes | ||
/** | ||
* @fileoverview react-star-rating | ||
* @author @cameronjroe | ||
* <StarRating | ||
* <StarRating | ||
* name={string} - name for form input (required) | ||
* caption={string} - caption for rating (optional) | ||
* ratingAmount={number} - the rating amount (required, default: 5) | ||
* totalStars={number} - the total amount of stars (required, default: 5) | ||
* rating={number} - a set rating between the rating amount (optional) | ||
* disabled={boolean} - whether to disable the rating from being selected (optional) | ||
* editing={boolean} - whether the rating is explicitly in editing mode (optional) | ||
* size={string} - size of stars (optional) | ||
* size={number} - size of stars (optional) | ||
* onRatingClick={function} - a handler function that gets called onClick of the rating (optional) | ||
@@ -20,46 +31,42 @@ * /> | ||
static propTypes = { | ||
name: React.PropTypes.string.isRequired, | ||
caption: React.PropTypes.string, | ||
totalStars: React.PropTypes.number.isRequired, | ||
rating: React.PropTypes.number, | ||
onRatingClick: React.PropTypes.func, | ||
disabled: React.PropTypes.bool, | ||
editing: React.PropTypes.bool, | ||
size: React.PropTypes.number | ||
} | ||
static defaultProps = { | ||
step: 1, | ||
totalStars: 5, | ||
onRatingClick() {}, | ||
disabled: false, | ||
size: 50, | ||
rating: 0 | ||
} | ||
constructor(props) { | ||
super(props); | ||
// initialize touch events | ||
React.initializeTouchEvents(); | ||
this.state = { | ||
ratingCache: { | ||
pos: 0, | ||
rating: 0 | ||
}, | ||
currentRatingVal: props.rating, | ||
currentRatingPos: this.getStarRatingPosition(props.rating), | ||
editing: props.editing || true, | ||
stars: 5, | ||
rating: 0, | ||
pos: 0, | ||
glyph: this.getStars() | ||
rating: props.rating, | ||
pos: this.getStarRatingPosition(props.rating), | ||
glyph: this.getStars(), | ||
size: props.size | ||
}; | ||
} | ||
/** | ||
* Gets the stars based on ratingAmount | ||
* @return {string} stars | ||
*/ | ||
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; | ||
this.max = this.props.totalStars || 5; | ||
if (this.props.rating) { | ||
this.state.editing = false; | ||
var ratingVal = this.props.rating; | ||
this.setState({ | ||
rating: ratingVal, | ||
pos: this.getStarRatingPosition(ratingVal) | ||
}); | ||
this.state.editing = this.props.editing || false; | ||
} | ||
@@ -69,4 +76,4 @@ } | ||
componentDidMount() { | ||
this.root = React.findDOMNode(this.refs.root); | ||
this.ratingContainer = React.findDOMNode(this.refs.ratingContainer); | ||
this.root = ReactDOM.findDOMNode(this.refs.root); | ||
this.ratingContainer = ReactDOM.findDOMNode(this.refs.ratingContainer); | ||
} | ||
@@ -79,15 +86,24 @@ | ||
getPosition(e) { | ||
return e.pageX - this.root.getBoundingClientRect().left; | ||
/** | ||
* Gets the stars based on totalStars | ||
* @return {string} stars | ||
*/ | ||
getStars() { | ||
var stars = ''; | ||
var numRating = this.props.totalStars; | ||
for(var i = 0; i < numRating; i++) { | ||
stars += '\u2605'; | ||
} | ||
return stars; | ||
} | ||
applyPrecision(val, precision) { | ||
return parseFloat(val.toFixed(precision)); | ||
/** | ||
* Gets the mouse position | ||
* @param {event} e | ||
* @return {number} delta | ||
*/ | ||
getPosition(e) { | ||
return e.clientX - this.root.getBoundingClientRect().left; | ||
} | ||
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(val) { | ||
@@ -104,3 +120,12 @@ var min = this.min, | ||
} | ||
applyPrecision(val, precision) { | ||
return parseFloat(val.toFixed(precision)); | ||
} | ||
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)); | ||
} | ||
getValueFromPosition(pos) { | ||
@@ -111,5 +136,5 @@ var precision = this.getDecimalPlaces(this.props.step); | ||
var factor = (diff * pos) / (maxWidth * this.props.step); | ||
factor = Math.ceil(factor); | ||
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); | ||
val = Math.max(Math.min(val, this.max), this.min); | ||
return val; | ||
@@ -121,3 +146,3 @@ } | ||
width = this.getWidthFromValue(val); | ||
width += '%'; | ||
@@ -128,4 +153,3 @@ return {width, val}; | ||
getStarRatingPosition(val) { | ||
var width = this.getWidthFromValue(val) + '%'; | ||
return width; | ||
return this.getWidthFromValue(val) + '%'; | ||
} | ||
@@ -138,7 +162,42 @@ | ||
getSvg() { | ||
/** | ||
* Get Star SVG | ||
*/ | ||
getSvg(rating) { | ||
var stars = []; | ||
for (var i = 0; i < this.props.totalStars; i++) { | ||
var attrs = {}; | ||
attrs['transform'] = `translate(${i*50}, 0)`; | ||
attrs['fill'] = (i+this.props.step <= rating) ? '#FFA91B' : '#C6C6C6'; | ||
stars.push( | ||
<path {...attrs} | ||
key={`star-${i}`} | ||
mask="url(#half-star-mask)" | ||
d="m0,18.1l19.1,0l5.9,-18.1l5.9,18.1l19.1,0l-15.4,11.2l5.9,18.1l-15.4,-11.2l-15.4,11.2l5.9,-18.1l-15.4,-11.2l0,0z" /> | ||
); | ||
} | ||
var styles = { | ||
width: `${stars.length * this.props.size}px`, | ||
height: `${this.props.size}px` | ||
}; | ||
return ( | ||
<svg className="react-star-rating__star" viewBox="0 0 286 272" version="1.1" xmlns="http://www.w3.org/2000/svg"> | ||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
<polygon id="star-flat" points="143 225 54.8322122 271.352549 71.6707613 173.176275 0.341522556 103.647451 98.9161061 89.3237254 143 0 187.083894 89.3237254 285.658477 103.647451 214.329239 173.176275 231.167788 271.352549 "></polygon> | ||
<svg className="rsr__star" | ||
style={styles} | ||
viewBox={`0 0 ${stars.length} 50`} | ||
preserveAspectRatio="xMinYMin meet" | ||
version="1.1" | ||
xmlns="http://www.w3.org/2000/svg"> | ||
{/* | ||
React Doesn't support `mask` attributes yet | ||
<defs> | ||
<mask id="half-star-mask"> | ||
<rect x="0" y="0" width="26" height="50" fill="blue"></rect> | ||
</mask> | ||
</defs>*/} | ||
<g> | ||
{stars.map((item) => { | ||
return item; | ||
})} | ||
</g> | ||
@@ -149,18 +208,7 @@ </svg> | ||
handleMouseLeave() { | ||
this.setState({ | ||
pos: this.state.ratingCache.pos, | ||
rating: this.state.ratingCache.rating | ||
}); | ||
} | ||
handleMouseMove(e) { | ||
// get hover position | ||
var ratingEvent = this.getRatingEvent(e); | ||
this.updateRating( | ||
ratingEvent.width, | ||
ratingEvent.val | ||
); | ||
} | ||
/** | ||
* Update the active rating selection | ||
* @param {number} width width based on mouse position | ||
* @param {number} val current rating amount | ||
*/ | ||
updateRating(width, val) { | ||
@@ -173,2 +221,5 @@ this.setState({ | ||
/** | ||
* Update rating state if props have changed | ||
*/ | ||
shouldComponentUpdate(nextProps, nextState) { | ||
@@ -182,9 +233,34 @@ if (nextProps !== this.props) { | ||
} else { | ||
return nextState.ratingCache.rating !== this.state.ratingCache.rating || nextState.rating !== this.state.rating; | ||
return nextState.currentRatingVal !== this.state.currentRatingVal || nextState.rating !== this.state.rating; | ||
} | ||
} | ||
/** | ||
* Set position to original state | ||
*/ | ||
handleMouseLeave() { | ||
this.setState({ | ||
pos: this.state.currentRatingPos, | ||
rating: this.state.currentRatingVal | ||
}); | ||
} | ||
/** | ||
* Update position to current event state | ||
* @param {object} event | ||
*/ | ||
handleMouseMove(e) { | ||
// get hover position | ||
var ratingEvent = this.getRatingEvent(e); | ||
this.updateRating( | ||
ratingEvent.width, | ||
ratingEvent.val | ||
); | ||
} | ||
/** | ||
* Update rating state, Trigger function handler | ||
* @param {object} event | ||
*/ | ||
handleClick(e) { | ||
// is it disabled? | ||
if (this.props.disabled) { | ||
@@ -196,5 +272,5 @@ e.stopPropagation(); | ||
var ratingCache = { | ||
pos: this.state.pos, | ||
rating: this.state.rating, | ||
var payload = { | ||
currentRatingPos: this.state.pos, | ||
currentRatingVal: this.state.rating, | ||
caption: this.props.caption, | ||
@@ -204,7 +280,10 @@ name: this.props.name | ||
this.setState({ | ||
ratingCache: ratingCache | ||
this.setState(payload); | ||
this.props.onRatingClick(e, { | ||
rating: this.state.rating, | ||
position: this.state.pos, | ||
caption: this.props.caption, | ||
name: this.props.name | ||
}); | ||
this.props.onRatingClick(e, ratingCache); | ||
} | ||
@@ -218,46 +297,51 @@ | ||
render() { | ||
var caption = null; | ||
var classes = cx({ | ||
'react-star-rating__root': true, | ||
'rating-disabled': this.props.disabled, | ||
['react-star-rating__size--' + this.props.size]: this.props.size, | ||
'rating-editing': this.state.editing | ||
getClasses() { | ||
return cx({ | ||
'rsr-root': true, | ||
'rsr--disabled': this.props.disabled, | ||
'rsr--editing': this.state.editing | ||
}); | ||
} | ||
// is there a caption? | ||
getCaption() { | ||
if (this.props.caption) { | ||
caption = (<span className="react-rating-caption">{this.props.caption}</span>); | ||
return (<span className="rsr__caption">{this.props.caption}</span>); | ||
} else { | ||
return null; | ||
} | ||
} | ||
// are we editing this rating? | ||
var starRating; | ||
setAttrs() { | ||
var attrs = {}; | ||
if (this.state.editing) { | ||
starRating = ( | ||
<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)}> | ||
<div className="rating-stars" data-content={this.state.glyph} style={{width: this.state.pos}}></div> | ||
<input type="number" name={this.props.name} value={this.state.ratingCache.rating} style={{display: 'none !important'}} min={this.min} max={this.max} readOnly /> | ||
</div> | ||
); | ||
} else { | ||
starRating = ( | ||
<div ref="ratingContainer" className="rating-container rating-gly-star" data-content={this.state.glyph}> | ||
<div className="rating-stars" data-content={this.state.glyph} style={{width: this.state.pos}}></div> | ||
<input type="number" name={this.props.name} value={this.state.ratingCache.rating} style={{display: 'none !important'}} min={this.min} max={this.max} readOnly /> | ||
</div> | ||
); | ||
attrs['onMouseMove'] = this.handleMouseMove.bind(this); | ||
attrs['onMouseLeave'] = this.handleMouseLeave.bind(this); | ||
attrs['onClick'] = this.handleClick.bind(this); | ||
} | ||
return attrs; | ||
} | ||
render() { | ||
var classes = this.getClasses(); | ||
var caption = this.getCaption(); | ||
var attrs = this.setAttrs(); | ||
return ( | ||
<span className="react-star-rating"> | ||
<span className="rsr-container"> | ||
{caption} | ||
<span ref="root" className={classes}> | ||
{starRating} | ||
</span> | ||
<div ref="root" className={classes}> | ||
<div ref="ratingContainer" | ||
className="rsr rating-gly-star" | ||
data-content={this.state.glyph} {...attrs}> | ||
{this.getSvg(this.state.rating)} | ||
<input type="number" | ||
name={this.props.name} | ||
value={this.state.currentRatingVal} | ||
style={{display: 'none !important'}} | ||
min={this.min} | ||
max={this.max} | ||
readOnly /> | ||
</div> | ||
</div> | ||
</span> | ||
@@ -268,20 +352,2 @@ ); | ||
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; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
27
1
77
1
143029
4
41
529
1
+ Addedreact@^0.14.2
+ Addedreact-dom@^0.14.2
+ Addedasap@2.0.6(transitive)
+ Addedcore-js@1.2.7(transitive)
+ Addedfbjs@0.6.1(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedpromise@7.3.1(transitive)
+ Addedreact@0.14.10(transitive)
+ Addedreact-addons-test-utils@0.14.8(transitive)
+ Addedreact-dom@0.14.10(transitive)
+ Addedua-parser-js@0.7.40(transitive)
+ Addedwhatwg-fetch@0.9.0(transitive)
- Removedreact@0.13.3(transitive)
Updatedclassnames@^2.2.0