]> cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/components/icon_button.js
Improve accessibility (part 4) (#4408)
[mastodon.git] / app / javascript / mastodon / components / icon_button.js
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
6 export default class IconButton extends React.PureComponent {
7
8 static propTypes = {
9 className: PropTypes.string,
10 title: PropTypes.string.isRequired,
11 icon: PropTypes.string.isRequired,
12 onClick: PropTypes.func,
13 size: PropTypes.number,
14 active: PropTypes.bool,
15 pressed: 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
25 static defaultProps = {
26 size: 18,
27 active: false,
28 disabled: false,
29 animate: false,
30 overlay: false,
31 tabIndex: '0',
32 };
33
34 handleClick = (e) => {
35 e.preventDefault();
36
37 if (!this.props.disabled) {
38 this.props.onClick(e);
39 }
40 }
41
42 render () {
43 const style = {
44 fontSize: `${this.props.size}px`,
45 width: `${this.props.size * 1.28571429}px`,
46 height: `${this.props.size * 1.28571429}px`,
47 lineHeight: `${this.props.size}px`,
48 ...this.props.style,
49 ...(this.props.active ? this.props.activeStyle : {}),
50 };
51
52 const classes = ['icon-button'];
53
54 if (this.props.active) {
55 classes.push('active');
56 }
57
58 if (this.props.disabled) {
59 classes.push('disabled');
60 }
61
62 if (this.props.inverted) {
63 classes.push('inverted');
64 }
65
66 if (this.props.overlay) {
67 classes.push('overlayed');
68 }
69
70 if (this.props.className) {
71 classes.push(this.props.className);
72 }
73
74 return (
75 <Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
76 {({ rotate }) =>
77 <button
78 aria-label={this.props.title}
79 aria-pressed={this.props.pressed}
80 title={this.props.title}
81 className={classes.join(' ')}
82 onClick={this.handleClick}
83 style={style}
84 tabIndex={this.props.tabIndex}
85 >
86 <i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${this.props.icon}`} aria-hidden='true' />
87 </button>
88 }
89 </Motion>
90 );
91 }
92
93 }
This page took 0.169112 seconds and 4 git commands to generate.