The code powering m.abunchtell.com https://m.abunchtell.com
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.
 
 
 
 

94 lines
2.3 KiB

  1. import React from 'react';
  2. import Motion from 'react-motion/lib/Motion';
  3. import spring from 'react-motion/lib/spring';
  4. import PropTypes from 'prop-types';
  5. export default class IconButton extends React.PureComponent {
  6. static propTypes = {
  7. className: PropTypes.string,
  8. title: PropTypes.string.isRequired,
  9. icon: PropTypes.string.isRequired,
  10. onClick: PropTypes.func,
  11. size: PropTypes.number,
  12. active: PropTypes.bool,
  13. pressed: PropTypes.bool,
  14. style: PropTypes.object,
  15. activeStyle: PropTypes.object,
  16. disabled: PropTypes.bool,
  17. inverted: PropTypes.bool,
  18. animate: PropTypes.bool,
  19. overlay: PropTypes.bool,
  20. tabIndex: PropTypes.string,
  21. };
  22. static defaultProps = {
  23. size: 18,
  24. active: false,
  25. disabled: false,
  26. animate: false,
  27. overlay: false,
  28. tabIndex: '0',
  29. };
  30. handleClick = (e) => {
  31. e.preventDefault();
  32. if (!this.props.disabled) {
  33. this.props.onClick(e);
  34. }
  35. }
  36. render () {
  37. const style = {
  38. fontSize: `${this.props.size}px`,
  39. width: `${this.props.size * 1.28571429}px`,
  40. height: `${this.props.size * 1.28571429}px`,
  41. lineHeight: `${this.props.size}px`,
  42. ...this.props.style,
  43. ...(this.props.active ? this.props.activeStyle : {}),
  44. };
  45. const classes = ['icon-button'];
  46. if (this.props.active) {
  47. classes.push('active');
  48. }
  49. if (this.props.disabled) {
  50. classes.push('disabled');
  51. }
  52. if (this.props.inverted) {
  53. classes.push('inverted');
  54. }
  55. if (this.props.overlay) {
  56. classes.push('overlayed');
  57. }
  58. if (this.props.className) {
  59. classes.push(this.props.className);
  60. }
  61. return (
  62. <Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
  63. {({ rotate }) =>
  64. <button
  65. aria-label={this.props.title}
  66. aria-pressed={this.props.pressed}
  67. title={this.props.title}
  68. className={classes.join(' ')}
  69. onClick={this.handleClick}
  70. style={style}
  71. tabIndex={this.props.tabIndex}
  72. >
  73. <i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${this.props.icon}`} aria-hidden='true' />
  74. </button>
  75. }
  76. </Motion>
  77. );
  78. }
  79. }