Fix poll options not being selectable via keyboard
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
00aacc5e33
commit
e6f30abd91
|
@ -36,9 +36,7 @@ class Poll extends ImmutablePureComponent {
|
||||||
selected: {},
|
selected: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
handleOptionChange = e => {
|
_toggleOption = value => {
|
||||||
const { target: { value } } = e;
|
|
||||||
|
|
||||||
if (this.props.poll.get('multiple')) {
|
if (this.props.poll.get('multiple')) {
|
||||||
const tmp = { ...this.state.selected };
|
const tmp = { ...this.state.selected };
|
||||||
if (tmp[value]) {
|
if (tmp[value]) {
|
||||||
|
@ -52,8 +50,20 @@ class Poll extends ImmutablePureComponent {
|
||||||
tmp[value] = true;
|
tmp[value] = true;
|
||||||
this.setState({ selected: tmp });
|
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 = () => {
|
handleVote = () => {
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
return;
|
return;
|
||||||
|
@ -105,7 +115,17 @@ class Poll extends ImmutablePureComponent {
|
||||||
disabled={disabled}
|
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'>
|
{showResults && <span className='poll__number'>
|
||||||
{!!voted && <Icon src={require('@tabler/icons/icons/check.svg')} className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
|
{!!voted && <Icon src={require('@tabler/icons/icons/check.svg')} className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
|
||||||
{Math.round(percent)}%
|
{Math.round(percent)}%
|
||||||
|
|
|
@ -16,10 +16,11 @@ const messages = defineMessages({
|
||||||
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
|
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
|
||||||
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
|
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
|
||||||
poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
|
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}}' },
|
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
|
||||||
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
|
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
|
||||||
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
|
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
|
||||||
hint: { id: 'compose_form.poll.type.hint', defaultMessage: 'Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@injectIntl
|
@injectIntl
|
||||||
|
@ -63,6 +64,12 @@ class Option extends React.PureComponent {
|
||||||
this.props.onClearSuggestions();
|
this.props.onClearSuggestions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleCheckboxKeypress = e => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
this.handleToggleMultiple(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSuggestionsFetchRequested = (token) => {
|
onSuggestionsFetchRequested = (token) => {
|
||||||
this.props.onFetchSuggestions(token);
|
this.props.onFetchSuggestions(token);
|
||||||
}
|
}
|
||||||
|
@ -80,9 +87,11 @@ class Option extends React.PureComponent {
|
||||||
<span
|
<span
|
||||||
className={classNames('poll__input', { checkbox: isPollMultiple })}
|
className={classNames('poll__input', { checkbox: isPollMultiple })}
|
||||||
onClick={this.handleToggleMultiple}
|
onClick={this.handleToggleMultiple}
|
||||||
|
onKeyPress={this.handleCheckboxKeypress}
|
||||||
role='button'
|
role='button'
|
||||||
tabIndex='0'
|
tabIndex='0'
|
||||||
title={intl.formatMessage(messages.hint)}
|
title={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)}
|
||||||
|
aria-label={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AutosuggestInput
|
<AutosuggestInput
|
||||||
|
|
|
@ -96,6 +96,23 @@
|
||||||
border-color: $valid-value-color;
|
border-color: $valid-value-color;
|
||||||
background: $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 {
|
&__number {
|
||||||
|
|
Loading…
Reference in New Issue