diff options
author | ThibG <thib@sitedethib.com> | 2019-12-03 19:53:16 +0100 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2019-12-03 19:53:16 +0100 |
commit | c05ed8a6254bc82fda3ae0fd3934dc2cdcf7c82d (patch) | |
tree | 3907d5b225a240aa43611a3d0cd16471d907bc5b /app/javascript | |
parent | f1ef777d40235dc922a0b56da9fc00b98827c189 (diff) |
Fix poll options not being selectable via keyboard (#12538)
* Fix poll options not being selectable via keyboard Fixes #12384 * Improve styling of poll option checkboxes/radio buttons * Use more appropriate ARIA roles for poll options * Allow switching between single and multiple choice from keyboard * Coding style * Avoid using .bind()
Diffstat (limited to 'app/javascript')
-rw-r--r-- | app/javascript/mastodon/components/poll.js | 28 | ||||
-rw-r--r-- | app/javascript/mastodon/features/compose/components/poll_form.js | 11 | ||||
-rw-r--r-- | app/javascript/styles/mastodon/polls.scss | 17 |
3 files changed, 52 insertions, 4 deletions
diff --git a/app/javascript/mastodon/components/poll.js b/app/javascript/mastodon/components/poll.js index 0edd064e0..3a17e80e7 100644 --- a/app/javascript/mastodon/components/poll.js +++ b/app/javascript/mastodon/components/poll.js @@ -67,9 +67,7 @@ class Poll extends ImmutablePureComponent { } } - handleOptionChange = e => { - const { target: { value } } = e; - + _toggleOption = value => { if (this.props.poll.get('multiple')) { const tmp = { ...this.state.selected }; if (tmp[value]) { @@ -83,8 +81,20 @@ class Poll extends ImmutablePureComponent { tmp[value] = true; this.setState({ selected: tmp }); } + } + + handleOptionChange = ({ target: { value } }) => { + this._toggleOption(value); }; + handleOptionKeyPress = (e) => { + if (e.key === 'Enter' || e.key === ' ') { + this._toggleOption(e.target.getAttribute('data-index')); + e.stopPropagation(); + e.preventDefault(); + } + } + handleVote = () => { if (this.props.disabled) { return; @@ -135,7 +145,17 @@ class Poll extends ImmutablePureComponent { disabled={disabled} /> - {!showResults && <span className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} />} + {!showResults && ( + <span + className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} + tabIndex='0' + role={poll.get('multiple') ? 'checkbox' : 'radio'} + onKeyPress={this.handleOptionKeyPress} + aria-checked={active} + aria-label={option.get('title')} + data-index={optionIndex} + /> + )} {showResults && <span className='poll__number'> {!!voted && <Icon id='check' className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />} {Math.round(percent)}% diff --git a/app/javascript/mastodon/features/compose/components/poll_form.js b/app/javascript/mastodon/features/compose/components/poll_form.js index f4cd71a76..81ab0ec1a 100644 --- a/app/javascript/mastodon/features/compose/components/poll_form.js +++ b/app/javascript/mastodon/features/compose/components/poll_form.js @@ -13,6 +13,8 @@ const messages = defineMessages({ add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' }, remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' }, poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' }, + switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple choices' }, + switchToSingle: { id: 'compose_form.poll.switch_to_single', defaultMessage: 'Change poll to allow for a single choice' }, minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' }, hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' }, days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' }, @@ -50,6 +52,12 @@ class Option extends React.PureComponent { e.stopPropagation(); }; + handleCheckboxKeypress = e => { + if (e.key === 'Enter' || e.key === ' ') { + this.handleToggleMultiple(e); + } + } + onSuggestionsClearRequested = () => { this.props.onClearSuggestions(); } @@ -71,8 +79,11 @@ class Option extends React.PureComponent { <span className={classNames('poll__input', { checkbox: isPollMultiple })} onClick={this.handleToggleMultiple} + onKeyPress={this.handleCheckboxKeypress} role='button' tabIndex='0' + title={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)} + aria-label={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)} /> <AutosuggestInput diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index f59a9d693..833f77009 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -91,6 +91,23 @@ border-color: $valid-value-color; background: $valid-value-color; } + + &:active, + &:focus, + &:hover { + border-width: 4px; + background: none; + } + + &::-moz-focus-inner { + outline: 0 !important; + border: 0; + } + + &:focus, + &:active { + outline: 0 !important; + } } &__number { |