Skip to content

Commit

Permalink
fix keyboard nav for home page (#12966)
Browse files Browse the repository at this point in the history
* fix keyboard nav for home page

* minor fixes based on another PR comment

* add aria-sort to table column headers + remove space key bindings for links

* revert small change on Checkbox

* revert small change on Checkbox

* clear key space to trigger links

* change role for links that are in fact buttons + keep space key
  • Loading branch information
aalves08 authored Jan 7, 2025
1 parent bf91d22 commit 9553614
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 7 deletions.
12 changes: 12 additions & 0 deletions pkg/rancher-components/src/components/Banner/Banner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export default defineComponent({
:class="{
[color]: true,
}"
role="banner"
>
<div
v-if="icon"
Expand Down Expand Up @@ -102,7 +103,12 @@ export default defineComponent({
<div
v-if="closable"
class="banner__content__closer"
tabindex="0"
role="button"
:aria-label="t('generic.close')"
@click="$emit('close')"
@keyup.enter="$emit('close')"
@keyup.space="$emit('close')"
>
<i
data-testid="banner-close"
Expand Down Expand Up @@ -226,6 +232,7 @@ $icon-size: 24px;
width: $icon-size;
line-height: $icon-size;
text-align: center;
outline: none;
.closer-icon {
opacity: 0.7;
Expand All @@ -235,6 +242,11 @@ $icon-size: 24px;
color: var(--link);
}
}
&:focus-visible i {
@include focus-outline;
outline-offset: 2px;
}
}
&.icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export default defineComponent({
tabindex="-1"
:name="id"
@click.stop.prevent
@keyup.enter.stop.prevent
>
<span
class="checkbox-custom"
Expand Down Expand Up @@ -342,6 +343,12 @@ $fontColor: var(--input-label);
z-index: -1;
}
input:focus-visible ~ .checkbox-custom {
@include focus-outline;
outline-offset: 2px;
border-radius: 0;
}
input:checked ~ .checkbox-custom {
background-color:var(--primary);
-webkit-transform: rotate(0deg) scale(1);
Expand Down
5 changes: 5 additions & 0 deletions shell/assets/styles/global/_button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ button,
border: 0;
}
}

&:focus-visible {
@include focus-outline;
outline-offset: 2px;
}
}

.role-tertiary {
Expand Down
2 changes: 2 additions & 0 deletions shell/assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
generic:
add: Add
all: All
ascending: ascending
and: ' and '
back: Back
cancel: Cancel
Expand All @@ -19,6 +20,7 @@ generic:
customize: Customize
dashboard: Dashboard
default: Default
descending: descending
disabled: Disabled
done: Done
enabled: Enabled
Expand Down
8 changes: 8 additions & 0 deletions shell/components/ActionMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,10 @@ export default {
:disabled="opt.disabled ? true : null"
:class="{divider: opt.divider}"
:data-testid="componentTestid + '-' + i + '-item'"
:tabindex="opt.divider ? -1 : 0"
@click="execute(opt, $event)"
@keyup.enter="execute(opt, $event)"
@keyup.space="execute(opt, $event)"
>
<IconOrSvg
v-if="opt.icon || opt.svg"
Expand Down Expand Up @@ -311,6 +314,11 @@ export default {
padding: 8px 10px;
margin: 0;
&:focus-visible {
@include focus-outline;
outline-offset: -2px;
}
&[disabled] {
cursor: not-allowed !important;
color: var(--disabled-text);
Expand Down
10 changes: 10 additions & 0 deletions shell/components/BannerGraphic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ export default {
v-if="pref"
class="close-button"
data-testid="graphic-banner-close"
tabindex="0"
:aria-label="t('generic.close')"
role="button"
@click="hide()"
@keyup.enter="hide()"
@keyup.space="hide()"
>
<i class="icon icon-close" />
</div>
Expand All @@ -72,6 +77,11 @@ export default {
.close-button {
position: absolute;
visibility: hidden;
&:focus-visible {
@include focus-outline;
outline-offset: 2px;
}
}
&:hover .close-button {
Expand Down
6 changes: 6 additions & 0 deletions shell/components/ButtonMultiAction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ const buttonClass = computed(() => {
.borderless {
background-color: transparent;
border: none;
&:focus-visible {
@include focus-outline;
outline-offset: -2px;
}
&:hover, &:focus {
background-color: var(--accent-btn);
box-shadow: none;
Expand Down
13 changes: 13 additions & 0 deletions shell/components/CommunityLinks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export default {
<router-link
v-if="link.value.startsWith('/') "
:to="link.value"
role="link"
:aria-label="link.label"
>
{{ link.label }}
</router-link>
Expand All @@ -118,6 +120,8 @@ export default {
:href="link.value"
rel="noopener noreferrer nofollow"
target="_blank"
role="link"
:aria-label="link.label"
> {{ link.label }} </a>
</div>
<slot />
Expand All @@ -127,7 +131,11 @@ export default {
>
<a
class="link"
tabindex="0"
:aria-label="t('footer.wechat.title')"
role="link"
@click="show"
@keyup.enter="show"
>
{{ t('footer.wechat.title') }}
</a>
Expand All @@ -147,7 +155,12 @@ export default {
<div>
<button
class="btn role-primary"
tabindex="0"
:aria-label="t('generic.close')"
role="button"
@click="close"
@keyup.enter="close"
@keyup.space="close"
>
{{ t('generic.close') }}
</button>
Expand Down
18 changes: 18 additions & 0 deletions shell/components/SortableTable/THead.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ export default {
return col.name === this.sortBy;
},
ariaSort(col) {
if (this.isCurrent(col)) {
return this.descending ? this.t('generic.descending') : this.t('generic.ascending');
}
return this.t('generic.none');
},
tableColsOptionsClick(ev) {
// set menu position
const menu = document.querySelector('.table-options-container');
Expand Down Expand Up @@ -235,7 +243,12 @@ export default {
:align="col.align || 'left'"
:width="col.width"
:class="{ sortable: col.sort, [col.breakpoint]: !!col.breakpoint}"
:tabindex="col.sort ? 0 : -1"
class="sortable-table-head-element"
:aria-sort="ariaSort(col)"
@click.prevent="changeSort($event, col)"
@keyup.enter="changeSort($event, col)"
@keyup.space="changeSort($event, col)"
>
<div
class="table-header-container"
Expand Down Expand Up @@ -428,6 +441,11 @@ export default {
border: 0;
color: var(--body-text);
&.sortable-table-head-element:focus-visible {
@include focus-outline;
outline-offset: -4px;
}
.table-header-container {
display: inline-flex;
Expand Down
3 changes: 3 additions & 0 deletions shell/components/SortableTable/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,7 @@ export default {
class="sortable-table"
:class="classObject"
width="100%"
role="table"
>
<THead
v-if="showHeaders"
Expand Down Expand Up @@ -1451,6 +1452,8 @@ export default {
:data-testid="componentTestid + '-' + i + '-action-button'"
:borderless="true"
@click="handleActionButtonClick(i, $event)"
@keyup.enter="handleActionButtonClick(i, $event)"
@keyup.space="handleActionButtonClick(i, $event)"
/>
</slot>
</td>
Expand Down
24 changes: 19 additions & 5 deletions shell/components/SortableTable/selection.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { mapGetters } from 'vuex';
import { isMore, isRange, suppressContextMenu, isAlternate } from '@shell/utils/platform';
import { get } from '@shell/utils/object';
import { filterBy } from '@shell/utils/array';
Expand Down Expand Up @@ -29,6 +30,13 @@ export default {
},

computed: {
...mapGetters({
// Use either these Vuex getters
// OR the props to set the action menu state,
// but don't use both.
targetElem: 'action-menu/elem',
shouldShow: 'action-menu/showing',
}),
// Used for the table-level selection check-box to show checked (all selected)/intermediate (some selected)/unchecked (none selected)
howMuchSelected() {
const total = this.pagedRows.length;
Expand Down Expand Up @@ -270,11 +278,17 @@ export default {
}
}

this.$store.commit(`action-menu/show`, {
resources,
event: e,
elem: actionElement
});
if (!this.targetElem && !this.shouldShow) {
this.$store.commit(`action-menu/show`, {
resources,
event: e,
elem: actionElement
});
} else if (this.targetElem === actionElement && this.shouldShow) {
// this condition is needed so that we can "toggle" the action menu with
// the keyboard for accessibility (row action menu)
this.$store.commit('action-menu/hide');
}

return;
}
Expand Down
25 changes: 23 additions & 2 deletions shell/pages/home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -504,16 +504,18 @@ export default defineComponent({
{{ t('landing.seeWhatsNew') }}
</div>
<a
class="hand"
class="hand banner-link"
:href="releaseNotesUrl"
role="link"
target="_blank"
rel="noopener noreferrer nofollow"
:aria-label="t('landing.whatsNewLink')"
@click.stop="showWhatsNew"
@keyup.stop.enter="showWhatsNew"
><span v-clean-html="t('landing.whatsNewLink')" /></a>
</Banner>
</div>
</div>

<div class="row home-panels">
<div class="col main-panel">
<div
Expand All @@ -532,7 +534,11 @@ export default defineComponent({
</div>
<a
class="hand mr-20"
tabindex="0"
:aria-label="t('landing.landingPrefs.userPrefs')"
@click.prevent.stop="showUserPrefs"
@keyup.prevent.stop.enter="showUserPrefs"
@keyup.prevent.stop.space="showUserPrefs"
><span v-clean-html="t('landing.landingPrefs.userPrefs')" /></a>
</Banner>
</div>
Expand Down Expand Up @@ -583,6 +589,9 @@ export default defineComponent({
:to="manageLocation"
class="btn btn-sm role-secondary"
data-testid="cluster-management-manage-button"
role="button"
:aria-label="t('cluster.manageAction')"
@keyup.space="$router.push(manageLocation)"
>
{{ t('cluster.manageAction') }}
</router-link>
Expand All @@ -591,6 +600,9 @@ export default defineComponent({
:to="importLocation"
class="btn btn-sm role-primary"
data-testid="cluster-create-import-button"
role="button"
:aria-label="t('cluster.importAction')"
@keyup.space="$router.push(importLocation)"
>
{{ t('cluster.importAction') }}
</router-link>
Expand All @@ -599,6 +611,9 @@ export default defineComponent({
:to="createLocation"
class="btn btn-sm role-primary"
data-testid="cluster-create-button"
role="button"
:aria-label="t('generic.create')"
@keyup.space="$router.push(createLocation)"
>
{{ t('generic.create') }}
</router-link>
Expand All @@ -614,6 +629,8 @@ export default defineComponent({
<router-link
v-if="row.mgmt.isReady && !row.hasError"
:to="{ name: 'c-cluster-explorer', params: { cluster: row.mgmt.id }}"
role="link"
:aria-label="row.nameDisplay"
>
{{ row.nameDisplay }}
</router-link>
Expand Down Expand Up @@ -687,6 +704,10 @@ export default defineComponent({
</template>

<style lang='scss' scoped>
.banner-link:focus-visible {
@include focus-outline;
}
.home-panels {
display: flex;
align-items: stretch;
Expand Down

0 comments on commit 9553614

Please sign in to comment.