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.

95 lines
2.3 KiB

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