You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.9 KiB

  1. import PureRenderMixin from 'react-addons-pure-render-mixin';
  2. import { Motion, spring } from 'react-motion';
  3. const IconButton = React.createClass({
  4. propTypes: {
  5. title: React.PropTypes.string.isRequired,
  6. icon: React.PropTypes.string.isRequired,
  7. onClick: React.PropTypes.func,
  8. size: React.PropTypes.number,
  9. active: React.PropTypes.bool,
  10. style: React.PropTypes.object,
  11. activeStyle: React.PropTypes.object,
  12. disabled: React.PropTypes.bool,
  13. animate: React.PropTypes.bool
  14. },
  15. getDefaultProps () {
  16. return {
  17. size: 18,
  18. active: false,
  19. disabled: false,
  20. animate: false
  21. };
  22. },
  23. mixins: [PureRenderMixin],
  24. handleClick (e) {
  25. e.preventDefault();
  26. if (!this.props.disabled) {
  27. this.props.onClick();
  28. }
  29. },
  30. render () {
  31. let style = {
  32. display: 'inline-block',
  33. border: 'none',
  34. padding: '0',
  35. background: 'transparent',
  36. fontSize: `${this.props.size}px`,
  37. width: `${this.props.size * 1.28571429}px`,
  38. height: `${this.props.size}px`,
  39. lineHeight: `${this.props.size}px`,
  40. ...this.props.style
  41. };
  42. if (this.props.active) {
  43. style = { ...style, ...this.props.activeStyle };
  44. }
  45. return (
  46. <Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
  47. {({ rotate }) =>
  48. <button
  49. aria-label={this.props.title}
  50. title={this.props.title}
  51. className={`icon-button ${this.props.active ? 'active' : ''} ${this.props.disabled ? 'disabled' : ''}`}
  52. onClick={this.handleClick}
  53. style={style}>
  54. <i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${this.props.icon}`} aria-hidden='true' />
  55. </button>
  56. }
  57. </Motion>
  58. );
  59. }
  60. });
  61. export default IconButton;