Add eslint-plugin-jsx-a11y (#1651)
* Add eslint-plugin-jsx-a11y. * Fix npm script. * Adjust npm scripts so test also runs lint. * Fix existing lint errors. * Don't break on a11y issues. * Add role and tabIndex. * Add vim and Mac files to .gitignore and .dockerignore. * Handle htmlFor (partially), a that's actually a button. * Fix missing tabIndex. * Add cursor:pointer to load-more * Revert change to load_more. * Fixes based on review. * Update yarn.lock. * Don't try to install fsevents on Linux (hides warning noise).
This commit is contained in:
parent
df4ff9a8e1
commit
f4045ba3d9
32 changed files with 155 additions and 57 deletions
|
@ -178,7 +178,12 @@ const AutosuggestTextarea = React.createClass({
|
|||
|
||||
<div style={{ display: (suggestions.size > 0 && !suggestionsHidden) ? 'block' : 'none' }} className='autosuggest-textarea__suggestions'>
|
||||
{suggestions.map((suggestion, i) => (
|
||||
<div key={suggestion} className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} onClick={this.onSuggestionClick.bind(this, suggestion)}>
|
||||
<div
|
||||
role='button'
|
||||
tabIndex='0'
|
||||
key={suggestion}
|
||||
className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`}
|
||||
onClick={this.onSuggestionClick.bind(this, suggestion)}>
|
||||
<AutosuggestAccountContainer id={suggestion} />
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -9,6 +9,7 @@ const Button = React.createClass({
|
|||
block: React.PropTypes.bool,
|
||||
secondary: React.PropTypes.bool,
|
||||
size: React.PropTypes.number,
|
||||
style: React.PropTypes.object,
|
||||
children: React.PropTypes.node
|
||||
},
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@ const ColumnBackButton = React.createClass({
|
|||
mixins: [PureRenderMixin],
|
||||
|
||||
handleClick () {
|
||||
if (window.history && window.history.length == 1) this.context.router.push("/");
|
||||
if (window.history && window.history.length === 1) this.context.router.push("/");
|
||||
else this.context.router.goBack();
|
||||
},
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div onClick={this.handleClick} className='column-back-button'>
|
||||
<div role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button'>
|
||||
<i className='fa fa-fw fa-chevron-left' style={iconStyle} />
|
||||
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||
</div>
|
||||
|
|
|
@ -31,7 +31,7 @@ const ColumnBackButtonSlim = React.createClass({
|
|||
render () {
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div style={outerStyle} onClick={this.handleClick} className='column-back-button'>
|
||||
<div role='button' tabIndex='0' style={outerStyle} onClick={this.handleClick} className='column-back-button'>
|
||||
<i className='fa fa-fw fa-chevron-left' style={iconStyle} />
|
||||
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||
</div>
|
||||
|
|
|
@ -46,7 +46,9 @@ const ColumnCollapsable = React.createClass({
|
|||
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div title={`${title}`} style={{...iconStyle }} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}><i className={`fa fa-${icon}`} /></div>
|
||||
<div role='button' tabIndex='0' title={`${title}`} style={{...iconStyle }} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}>
|
||||
<i className={`fa fa-${icon}`} />
|
||||
</div>
|
||||
|
||||
<Motion defaultStyle={{ opacity: 0, height: 0 }} style={{ opacity: spring(collapsed ? 0 : 100), height: spring(collapsed ? 0 : fullHeight, collapsed ? undefined : { stiffness: 150, damping: 9 }) }}>
|
||||
{({ opacity, height }) =>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const LoadMore = ({ onClick }) => (
|
||||
<a href='#' className='load-more' onClick={onClick}>
|
||||
<a href="#" className='load-more' role='button' onClick={onClick}>
|
||||
<FormattedMessage id='status.load_more' defaultMessage='Load more' />
|
||||
</a>
|
||||
);
|
||||
|
|
|
@ -220,7 +220,7 @@ const MediaGallery = React.createClass({
|
|||
}
|
||||
|
||||
children = (
|
||||
<div style={spoilerStyle} className='media-spoiler' onClick={this.handleOpen}>
|
||||
<div role='button' tabIndex='0' style={spoilerStyle} className='media-spoiler' onClick={this.handleOpen}>
|
||||
<span style={spoilerSpanStyle}>{warning}</span>
|
||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,8 @@ const Permalink = React.createClass({
|
|||
|
||||
propTypes: {
|
||||
href: React.PropTypes.string.isRequired,
|
||||
to: React.PropTypes.string.isRequired
|
||||
to: React.PropTypes.string.isRequired,
|
||||
children: React.PropTypes.node.isRequired
|
||||
},
|
||||
|
||||
handleClick (e) {
|
||||
|
|
|
@ -119,7 +119,7 @@ const StatusContent = React.createClass({
|
|||
return (
|
||||
<div className='status__content' style={{ cursor: 'pointer' }} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
|
||||
<p style={{ marginBottom: hidden && status.get('mentions').size === 0 ? '0px' : '' }} >
|
||||
<span dangerouslySetInnerHTML={spoilerContent} /> <a className='status__content__spoiler-link' onClick={this.handleSpoilerClick}>{toggleText}</a>
|
||||
<span dangerouslySetInnerHTML={spoilerContent} /> <a tabIndex='0' className='status__content__spoiler-link' role='button' onClick={this.handleSpoilerClick}>{toggleText}</a>
|
||||
</p>
|
||||
|
||||
{mentionsPlaceholder}
|
||||
|
|
|
@ -194,7 +194,7 @@ const VideoPlayer = React.createClass({
|
|||
if (!this.state.visible) {
|
||||
if (sensitive) {
|
||||
return (
|
||||
<div style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
||||
<div role='button' tabIndex='0' style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
||||
{spoilerButton}
|
||||
<span style={spoilerSpanStyle}><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
|
@ -202,7 +202,7 @@ const VideoPlayer = React.createClass({
|
|||
);
|
||||
} else {
|
||||
return (
|
||||
<div style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
||||
<div role='button' tabIndex='0' style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
||||
{spoilerButton}
|
||||
<span style={spoilerSpanStyle}><FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' /></span>
|
||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
|
@ -213,7 +213,7 @@ const VideoPlayer = React.createClass({
|
|||
|
||||
if (this.state.preview && !autoplay) {
|
||||
return (
|
||||
<div style={{ cursor: 'pointer', position: 'relative', marginTop: '8px', width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }} onClick={this.handleOpen}>
|
||||
<div role='button' tabIndex='0' style={{ cursor: 'pointer', position: 'relative', marginTop: '8px', width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }} onClick={this.handleOpen}>
|
||||
{spoilerButton}
|
||||
<div style={{ position: 'absolute', top: '50%', left: '50%', fontSize: '36px', transform: 'translate(-50%, -50%)', padding: '5px', borderRadius: '100px', color: 'rgba(255, 255, 255, 0.8)' }}><i className='fa fa-play' /></div>
|
||||
</div>
|
||||
|
@ -225,7 +225,7 @@ const VideoPlayer = React.createClass({
|
|||
{spoilerButton}
|
||||
{muteButton}
|
||||
{expandButton}
|
||||
<video ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} />
|
||||
<video role='button' tabIndex='0' ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Reference in a new issue