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.

89 lines
2.1 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. inverted: React.PropTypes.bool,
  14. animate: React.PropTypes.bool,
  15. overlay: React.PropTypes.bool
  16. },
  17. getDefaultProps () {
  18. return {
  19. size: 18,
  20. active: false,
  21. disabled: false,
  22. animate: false,
  23. overlay: false
  24. };
  25. },
  26. mixins: [PureRenderMixin],
  27. handleClick (e) {
  28. e.preventDefault();
  29. if (!this.props.disabled) {
  30. this.props.onClick(e);
  31. }
  32. },
  33. render () {
  34. let style = {
  35. fontSize: `${this.props.size}px`,
  36. width: `${this.props.size * 1.28571429}px`,
  37. height: `${this.props.size * 1.28571429}px`,
  38. lineHeight: `${this.props.size}px`,
  39. ...this.props.style
  40. };
  41. if (this.props.active) {
  42. style = { ...style, ...this.props.activeStyle };
  43. }
  44. const classes = ['icon-button'];
  45. if (this.props.active) {
  46. classes.push('active');
  47. }
  48. if (this.props.disabled) {
  49. classes.push('disabled');
  50. }
  51. if (this.props.inverted) {
  52. classes.push('inverted');
  53. }
  54. if (this.props.overlay) {
  55. classes.push('overlayed');
  56. }
  57. return (
  58. <Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
  59. {({ rotate }) =>
  60. <button
  61. aria-label={this.props.title}
  62. title={this.props.title}
  63. className={classes.join(' ')}
  64. onClick={this.handleClick}
  65. style={style}>
  66. <i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${this.props.icon}`} aria-hidden='true' />
  67. </button>
  68. }
  69. </Motion>
  70. );
  71. }
  72. });
  73. export default IconButton;