diff --git a/changelog.d/poll-kbd-accessibility.fix b/changelog.d/poll-kbd-accessibility.fix new file mode 100644 index 00000000..e351601d --- /dev/null +++ b/changelog.d/poll-kbd-accessibility.fix @@ -0,0 +1 @@ +Make poll accessible diff --git a/src/App.scss b/src/App.scss index ef68ac50..eb96ddeb 100644 --- a/src/App.scss +++ b/src/App.scss @@ -540,7 +540,9 @@ textarea, } &[type="radio"] { - display: none; + &:not(.visible-for-screenreader-only) { + display: none; + } &:checked + label::before { box-shadow: 0 0 2px black inset, 0 0 0 4px $fallback--fg inset; @@ -597,6 +599,7 @@ textarea, flex-shrink: 0; display: inline-block; content: "✓"; + content: "✓" / ""; transition: color 200ms; width: 1.1em; height: 1.1em; diff --git a/src/components/poll/poll.js b/src/components/poll/poll.js index f6001f56..31e7f39e 100644 --- a/src/components/poll/poll.js +++ b/src/components/poll/poll.js @@ -1,7 +1,6 @@ import Timeago from 'components/timeago/timeago.vue' import genRandomSeed from '../../services/random_seed/random_seed.service.js' import RichContent from 'components/rich_content/rich_content.jsx' -import { forEach, map } from 'lodash' export default { name: 'Poll', @@ -81,25 +80,17 @@ export default { this.$store.dispatch('refreshPoll', { id: this.statusId, pollId: this.poll.id }) }, activateOption (index) { - // forgive me father: doing checking the radio/checkboxes - // in code because of customized input elements need either - // a) an extra element for the actual graphic, or b) use a - // pseudo element for the label. We use b) which mandates - // using "for" and "id" matching which isn't nice when the - // same poll appears multiple times on the site (notifs and - // timeline for example). With code we can make sure it just - // works without altering the pseudo element implementation. - const allElements = this.$el.querySelectorAll('input') - const clickedElement = this.$el.querySelector(`input[value="${index}"]`) if (this.poll.multiple) { - // Checkboxes, toggle only the clicked one - clickedElement.checked = !clickedElement.checked + // Multiple choice: toggle the current index + const nextChoices = [...this.choices] + nextChoices[index] = !nextChoices[index] + this.choices = nextChoices } else { // Radio button, uncheck everything and check the clicked one - forEach(allElements, element => { element.checked = false }) - clickedElement.checked = true + const nextChoices = new Array(this.choices.length).fill(false) + nextChoices[index] = true + this.choices = nextChoices } - this.choices = map(allElements, e => e.checked) }, optionId (index) { return `poll${this.poll.id}-${index}` diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue index b3a74c49..70342eae 100644 --- a/src/components/poll/poll.vue +++ b/src/components/poll/poll.vue @@ -31,36 +31,41 @@ :style="{ 'width': `${percentageForOption(option.votes_count)}%` }" /> -