Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve accessibility of FreeTube input elements #2709

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0841bf3
improve accessibility of FreeTube input elements
ChunkyProgrammer Oct 11, 2022
7ff59cb
make focus visible for prompt
ChunkyProgrammer Oct 11, 2022
2eb9b61
add close button to ft-prompt
ChunkyProgrammer Oct 12, 2022
3d4d4b4
Update src/renderer/components/ft-icon-button/ft-icon-button.vue
ChunkyProgrammer Oct 12, 2022
669839e
make suggested changes
ChunkyProgrammer Oct 13, 2022
1d44b4e
move eslint plugin to devdepedencies
ChunkyProgrammer Oct 14, 2022
0e21f2c
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Oct 14, 2022
52dbdd5
dont hide ft-prompt on focus out
ChunkyProgrammer Oct 31, 2022
ecd22ed
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Oct 31, 2022
0628d78
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Nov 3, 2022
55ad447
add aria-describeby
ChunkyProgrammer Nov 6, 2022
4062537
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Nov 6, 2022
413796e
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Nov 14, 2022
3251b81
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Nov 14, 2022
3ae3b7c
update eslint-plugin-vuejs-accessibility
ChunkyProgrammer Nov 14, 2022
3d2a940
Update yarn.lock
ChunkyProgrammer Nov 16, 2022
5199ff5
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Nov 16, 2022
b699e9c
Update yarn.lock
ChunkyProgrammer Nov 16, 2022
d06b2ba
Fix lint issues
ChunkyProgrammer Nov 16, 2022
935903b
only escape whitespace in ids
ChunkyProgrammer Nov 30, 2022
9383022
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Nov 30, 2022
9b40faf
Merge branch 'development' into accessibility-inputs
ChunkyProgrammer Dec 7, 2022
5611cc5
use computed properties
ChunkyProgrammer Dec 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ module.exports = {
'eslint:recommended',
'plugin:vue/recommended',
'standard'
// 'plugin:vuejs-accessibility/recommended' // uncomment once issues are fixed
],

// https://eslint.org/docs/user-guide/configuring#configuring-plugins
plugins: ['vue'],
plugins: ['vue', 'vuejs-accessibility'],

rules: {
'space-before-function-paren': 'off',
Expand All @@ -40,6 +41,12 @@ module.exports = {
'no-undef': 'warn',
'vue/no-template-key': 'warn',
'vue/no-useless-template-attributes': 'off',
'vue/multi-word-component-names': 'off'
'vue/multi-word-component-names': 'off',
'vuejs-accessibility/no-onchange': 'off',
'vuejs-accessibility/label-has-for': ['error', {
required: {
some: ['nesting', 'id']
}
}]
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-standard": "^5.0.0",
"eslint-plugin-vue": "^9.7.0",
"eslint-plugin-vuejs-accessibility": "^2.0.0",
"html-webpack-plugin": "^5.3.2",
"js-yaml": "^4.1.0",
"json-minimizer-webpack-plugin": "^4.0.0",
Expand Down
10 changes: 7 additions & 3 deletions src/renderer/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
v-if="showUpdatesBanner"
class="banner"
:message="updateBannerMessage"
role="link"
@click="handleUpdateBannerClick"
/>
<ft-notification-banner
v-if="showBlogBanner"
class="banner"
:message="blogBannerMessage"
role="link"
@click="handleNewBlogBannerClick"
/>
</div>
Expand All @@ -46,11 +48,9 @@

<ft-prompt
v-if="showReleaseNotes"
:label="changeLogTitle"
@click="showReleaseNotes = !showReleaseNotes"
>
<h2>
{{ changeLogTitle }}
</h2>
<span
id="changeLogText"
v-html="updateChangelog"
Expand All @@ -60,6 +60,10 @@
:label="$t('Download From Site')"
@click="openDownloadsPage"
/>
<ft-button
:label="$t('Close')"
@click="showReleaseNotes = !showReleaseNotes"
/>
</ft-flex-box>
</ft-prompt>
<ft-prompt
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/components/ft-button/ft-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export default Vue.extend({
backgroundColor: {
type: String,
default: 'var(--accent-color)'
},
id: {
type: String,
default: ''
}
}
})
1 change: 1 addition & 0 deletions src/renderer/components/ft-button/ft-button.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<button
:id="id.length > 0 ? id : null"
class="btn ripple"
:style="{
color: textColor,
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/components/ft-icon-button/ft-icon-button.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Vue from 'vue'
import { sanitizeForHtmlId } from '../../helpers/accessibility'

export default Vue.extend({
name: 'FtIconButton',
Expand Down Expand Up @@ -59,6 +60,7 @@ export default Vue.extend({
}
},
methods: {
sanitizeForHtmlId,
// used by the share menu
hideDropdown: function () {
this.dropdownShown = false
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/ft-icon-button/ft-icon-button.sass
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
cursor: pointer
transition: background 0.2s ease-out

&:hover
&:hover, &:focus
background-color: var(--side-nav-hover-color)
transition: background 0.2s ease-in

Expand Down
14 changes: 13 additions & 1 deletion src/renderer/components/ft-icon-button/ft-icon-button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
padding: padding + 'px',
fontSize: size + 'px'
}"
tabindex="0"
role="button"
@click="handleIconClick"
@mousedown="handleIconMouseDown"
@keydown.enter.prevent="handleIconClick"
@keydown.space.prevent="handleIconClick"
/>
<div
v-show="dropdownShown"
Expand All @@ -33,12 +37,20 @@
<ul
v-if="dropdownOptions.length > 0"
class="list"
role="listbox"
:aria-expanded="dropdownShown"
>
<li
v-for="(option, index) in dropdownOptions"
:id="sanitizeForHtmlId(title + '-' + index)"
:key="index"
role="option"
aria-selected="false"
tabindex="-1"
:class="option.type === 'divider' ? 'listItemDivider' : 'listItem'"
@click="handleDropdownClick({url: option.value, index: index})"
@click="handleDropdownClick({url: option.value, index: index}, $event)"
@keydown.enter="handleDropdownClick({url: option.value, index: index}, $event)"
@keydown.space="handleDropdownClick({url: option.value, index: index}, $event)"
>
{{ option.type === 'divider' ? '' : option.label }}
</li>
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/components/ft-input/ft-input.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- eslint-disable vuejs-accessibility/mouse-events-have-key-events -->
<template>
<div
class="ft-input-component"
Expand Down Expand Up @@ -70,6 +71,7 @@
@mouseenter="searchState.isPointerInList = true"
@mouseleave="searchState.isPointerInList = false"
>
<!-- eslint-disable vuejs-accessibility/click-events-have-key-events -->
<li
v-for="(list, index) in visibleDataList"
:key="index"
Expand All @@ -79,6 +81,7 @@
>
{{ list }}
</li>
<!-- skipped -->
</ul>
</div>
</div>
Expand Down
18 changes: 9 additions & 9 deletions src/renderer/components/ft-list-dropdown/ft-list-dropdown.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.dropDown {
.dropdown {
position: relative;
text-align: center;
text-transform: uppercase;
margin: 0 5px;
}

.dropDown ul {
.dropdown ul {
display: none;
position: absolute;
list-style: none;
Expand All @@ -15,19 +15,19 @@
z-index: 100;
}

.dropDown ul li {
.dropdown ul li.buttonOption {
width: 100%;
float: none;
box-sizing: border-box;
}

.dropDown:hover ul {
display: block;
.dropdown:hover ul, .dropdown:focus-within ul {
display: block;
}

.dropDown ul li a {
text-decoration: none;
color: inherit;
.dropdown ul li a {
text-decoration: none;
color: inherit;
}

.buttonTitle {
Expand Down Expand Up @@ -60,7 +60,7 @@
transition: background 0.2s ease-out;
}

.buttonOption:hover {
.buttonOption:hover, .buttonOption:focus {
background-color: var(--side-nav-hover-color);
-moz-transition: background 0.2s ease-in;
-o-transition: background 0.2s ease-in;
Expand Down
23 changes: 22 additions & 1 deletion src/renderer/components/ft-list-dropdown/ft-list-dropdown.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Vue from 'vue'

import { sanitizeForHtmlId, handleDropdownKeyboardEvent } from '../../helpers/accessibility'
export default Vue.extend({
name: 'FtListDropdown',
props: {
Expand Down Expand Up @@ -31,5 +31,26 @@ export default Vue.extend({
listType: function () {
return this.$store.getters.getListType
}
},
methods: {
sanitizeForHtmlId,
handleIconKeyPress() {
const firstOption = document.getElementById('buttonOption0')
if (firstOption) {
firstOption.setAttribute('tabIndex', 1)
firstOption.focus()
}
},
handleDropdownClick: function(index, event) {
if (!handleDropdownKeyboardEvent(event, event?.target)) {
return
}

const unspacedTitle = CSS.escape(sanitizeForHtmlId(this.title))
const allOptions = document.querySelector(`#${unspacedTitle} + ul`)
allOptions.setAttribute('tabindex', '-1')
event.target.setAttribute('tabindex', '0')
this.$emit('click', this.labelValues[index])
}
}
})
19 changes: 16 additions & 3 deletions src/renderer/components/ft-list-dropdown/ft-list-dropdown.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
<template>
<div class="dropDown">
<div class="buttonTitle">
<div class="dropdown">
<div
:id="sanitizeForHtmlId(title)"
class="buttonTitle"
tabindex="0"
role="listbox"
@keydown.space.prevent="handleIconKeyPress($event)"
@keydown.enter.prevent="handleIconKeyPress($event)"
@keydown.down.prevent="handleIconKeyPress($event)"
>
{{ title }}
<font-awesome-icon
class="angleDownIcon"
Expand All @@ -10,9 +18,14 @@
<ul>
<li
v-for="(label, index) in labelNames"
:id="'buttonOption' + index"
:key="index"
class="buttonOption"
@click="$emit('click', labelValues[index])"
role="option"
tabindex="-1"
aria-selected="false"
@click="handleDropdownClick(index, $event)"
@keydown="handleDropdownClick(index, $event)"
>
{{ label }}
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
cursor: pointer;
}

.ftNotificationBanner:focus {
box-shadow: 20px 20px 20px rgba(0,0,0,.1);
}

.message {
margin-right: 25px;
cursor: pointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ export default Vue.extend({
this.$emit('click', response)
},

handleClose: function (event) {
event.stopPropagation()
handleClose: function () {
this.handleClick(false)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
<template>
<div
class="ftNotificationBanner"
tabindex="0"
role="link"
:title="message"
:aria-describedby="message"
@click="handleClick(true)"
@keydown.enter.prevent="handleClick(true)"
@keydown.space.prevent="handleClick(true)"
>
<div
class="message"
Expand All @@ -15,7 +21,10 @@
<font-awesome-icon
class="bannerIcon"
:icon="['fas', 'times']"
@click="handleClose"
tabindex="0"
:title="$t('Close Banner')"
@click.stop="handleClose"
@keydown.enter.stop.prevent="handleClose"
/>
</div>
</template>
Expand Down
Loading