diff --git a/index.js b/index.js
index 4f9c423..f77abb6 100644
--- a/index.js
+++ b/index.js
@@ -1,75 +1,145 @@
-/** @jsx React.DOM */
-var React = require('react');
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
-var Icon = React.createClass({displayName: "Icon",
- render : function(){
- var iStyle = {
- cursor : 'pointer'
+const Icon = ({ toggled, toggledClassName, untoggledClassName, onMouseEnter, onClickRating }) => {
+ const iStyle = {
+ cursor: 'pointer',
+ };
+
+ const className = toggled ? toggledClassName : untoggledClassName;
+
+ return (
+ {
+ e.preventDefault();
+ onClickRating();
+ }}
+ onMouseMove={onMouseEnter}>
+
+
+ );
+};
+
+Icon.propTypes = {
+ toggled: PropTypes.bool,
+ toggledClassName: PropTypes.string,
+ untoggledClassName: PropTypes.string,
+ onMouseEnter: PropTypes.func,
+ onClickRating: PropTypes.func,
+};
+
+Icon.defaultProps = {
+ toggled: false,
+ toggledClassName: null,
+ untoggledClassName: null,
+ onMouseEnter: null,
+ onClickRating: null,
+};
+
+class IconRating extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ currentRating: props.currentRating,
+ max: props.max,
+ currentRatingHover: 0,
+ hovering: false,
};
- var className = this.props.toggled ? this.props.toggledClassName : this.props.untoggledClassName;
- return (
- React.createElement("i", {className: className, onMouseMove: this.props.onMouseEnter, style: iStyle, onClick: this.props.onClickRating})
- );
+
+ this.onMouseEnter = this.onMouseEnter.bind(this);
+ this.onMouseLeave = this.onMouseLeave.bind(this);
+ this.onClickRating = this.onClickRating.bind(this);
}
-});
-
-var IconRating = React.createClass({displayName: "IconRating",
- getInitialState : function(){
- return {
- currentRating : this.props.currentRating || 0,
- max : this.props.max || 5,
- currentRating_hover : 0,
- hovering : false
- };
- },
- onMouseEnter : function(currentRating, e, id){
- var rating = currentRating;
- if((e.nativeEvent.clientX) < (e.target.offsetLeft + (e.target.offsetWidth / 2))){
- rating -= .5;
+
+ onMouseEnter(e, currentRating) {
+ let rating = currentRating;
+ if ((e.nativeEvent.clientX) < (e.target.offsetLeft + (e.target.offsetWidth / 2))) {
+ rating -= 0.5;
}
+
this.setState({
- currentRating_hover : rating,
- hovering : true
+ currentRatingHover: rating,
+ hovering: true,
});
- },
- onMouseLeave : function(currentRating, e, id){
+ }
+
+ onMouseLeave() {
this.setState({
- hovering : false
+ hovering: false,
});
- },
- onClickRating : function(currentRating, e, id){
+ }
+
+ onClickRating() {
+ const { currentRating, currentRatingHover } = this.state;
+ const newRating = (currentRatingHover === currentRating) ? 0 : currentRatingHover;
this.setState({
- currentRating : this.state.currentRating_hover
+ currentRating: newRating,
});
- if(this.props.onChange){
- this.props.onChange(currentRating);
+
+ if (this.props.onChange) {
+ this.props.onChange(newRating);
}
- },
- render: function() {
- var ratings = [];
- var toggled = false, rating, halfClassName,
- f = function() {},
- onMouseEnter = this.props.viewOnly ? f : this.onMouseEnter,
- onClickRating = this.props.viewOnly ? f : this.onClickRating;
- for(var i=1;i<=this.state.max;++i){
- rating = this.state['currentRating' + (this.state.hovering ? '_hover':'')];
- toggled = i <= Math.round(rating) ? true : false;
- halfClassName = null;
- if(this.props.halfClassName &&
- Math.round(rating) == i &&
- Math.floor(rating) != rating){
- halfClassName = this.props.halfClassName;
+ }
+
+ render() {
+ const { viewOnly, halfClassName, toggledClassName, untoggledClassName, className } = this.props;
+ const ratings = [];
+ let toggled = false;
+ let rating = 0;
+ let usedHalfClassName = null;
+ const f = () => {};
+ const onMouseEnter = viewOnly ? f : this.onMouseEnter;
+ const onClickRating = viewOnly ? f : this.onClickRating;
+ for (let i = 1; i <= this.state.max; ++i) {
+ rating = this.state[`currentRating${(this.state.hovering ? 'Hover' : '')}`];
+ toggled = i <= Math.round(rating);
+ usedHalfClassName = null;
+ if (halfClassName &&
+ Math.round(rating) === i &&
+ Math.floor(rating) !== rating) {
+ usedHalfClassName = halfClassName;
}
ratings.push(
- React.createElement(Icon, {key: i, toggledClassName: halfClassName || this.props.toggledClassName, untoggledClassName: this.props.untoggledClassName, onMouseEnter: onMouseEnter.bind(this,i), onClickRating: onClickRating.bind(this,i), toggled: toggled})
+ onMouseEnter(e, i)}
+ onClickRating={e => onClickRating(e, i)}
+ toggled={toggled} />
);
}
return (
- React.createElement("div", {className: this.props.className, onMouseLeave: this.onMouseLeave},
- ratings
- )
+
+ {ratings}
+
);
}
-});
+}
+
+IconRating.propTypes = {
+ currentRating: PropTypes.number,
+ max: PropTypes.number,
+ onChange: PropTypes.func,
+ viewOnly: PropTypes.bool,
+ halfClassName: PropTypes.string,
+ toggledClassName: PropTypes.string,
+ untoggledClassName: PropTypes.string,
+ className: PropTypes.string,
+};
+
+IconRating.defaultProps = {
+ currentRating: 0,
+ max: 5,
+ onChange: () => {},
+ viewOnly: false,
+ halfClassName: null,
+ toggledClassName: null,
+ untoggledClassName: null,
+ className: null,
+};
-module.exports = IconRating;
+export default IconRating;
diff --git a/index.jsx b/index.jsx
deleted file mode 100644
index 7799db4..0000000
--- a/index.jsx
+++ /dev/null
@@ -1,76 +0,0 @@
-/** @jsx React.DOM */
-var React = require('react');
-
-var Icon = React.createClass({
- render : function(){
- var iStyle = {
- cursor : 'pointer'
- };
- var className = this.props.toggled ? this.props.toggledClassName : this.props.untoggledClassName;
- return (
-
- );
- }
-});
-
-var IconRating = React.createClass({
- getInitialState : function(){
- return {
- currentRating : this.props.currentRating || 0,
- max : this.props.max || 5,
- currentRating_hover : 0,
- hovering : false
- };
- },
- onMouseEnter : function(currentRating, e, id){
- var rating = currentRating;
- if((e.nativeEvent.clientX) < (e.target.offsetLeft + (e.target.offsetWidth / 2))){
- rating -= .5;
- }
- this.setState({
- currentRating_hover : rating,
- hovering : true
- });
- },
- onMouseLeave : function(currentRating, e, id){
- this.setState({
- hovering : false
- });
- },
- onClickRating : function(currentRating, e, id){
- var newRating = this.state.currentRating_hover
- this.setState({
- currentRating : newRating
- });
- if(this.props.onChange){
- this.props.onChange(newRating);
- }
- },
- render: function() {
- var ratings = [];
- var toggled = false, rating, halfClassName,
- f = function() {},
- onMouseEnter = this.props.viewOnly ? f : this.onMouseEnter,
- onClickRating = this.props.viewOnly ? f : this.onClickRating;
- for(var i=1;i<=this.state.max;++i){
- rating = this.state['currentRating' + (this.state.hovering ? '_hover':'')];
- toggled = i <= Math.round(rating) ? true : false;
- halfClassName = null;
- if(this.props.halfClassName &&
- Math.round(rating) == i &&
- Math.floor(rating) != rating){
- halfClassName = this.props.halfClassName;
- }
- ratings.push(
-
- );
- }
- return (
-
- {ratings}
-
- );
- }
-});
-
-module.exports = IconRating;
diff --git a/package.json b/package.json
index 8c4e57e..87b6098 100644
--- a/package.json
+++ b/package.json
@@ -16,10 +16,11 @@
],
"author": "Daryl Lau",
"license": "MIT",
- "peerDependencies": {
- "react": ">=0.10.x || 15.x"
- },
+ "peerDependencies": {},
"devDependencies": {
- "react": "^15.3.0"
+ "react": "^15.6.1"
+ },
+ "dependencies": {
+ "prop-types": "^15.5.10"
}
}
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..aeaf150
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,108 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+asap@~2.0.3:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
+
+core-js@^1.0.0:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
+
+create-react-class@^15.6.0:
+ version "15.6.0"
+ resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
+ dependencies:
+ fbjs "^0.8.9"
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
+encoding@^0.1.11:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
+ dependencies:
+ iconv-lite "~0.4.13"
+
+fbjs@^0.8.9:
+ version "0.8.12"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
+ dependencies:
+ core-js "^1.0.0"
+ isomorphic-fetch "^2.1.1"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.9"
+
+iconv-lite@~0.4.13:
+ version "0.4.18"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
+
+is-stream@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+isomorphic-fetch@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
+js-tokens@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
+
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
+ dependencies:
+ js-tokens "^3.0.0"
+
+node-fetch@^1.0.1:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5"
+ dependencies:
+ encoding "^0.1.11"
+ is-stream "^1.0.1"
+
+object-assign@^4.1.0, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ dependencies:
+ asap "~2.0.3"
+
+prop-types@^15.5.10:
+ version "15.5.10"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
+ dependencies:
+ fbjs "^0.8.9"
+ loose-envify "^1.3.1"
+
+react@^15.6.1:
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
+ dependencies:
+ create-react-class "^15.6.0"
+ fbjs "^0.8.9"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.0"
+ prop-types "^15.5.10"
+
+setimmediate@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
+
+ua-parser-js@^0.7.9:
+ version "0.7.13"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.13.tgz#cd9dd2f86493b3f44dbeeef3780fda74c5ee14be"
+
+whatwg-fetch@>=0.10.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"