From a1951e2ab9115fbf179cd56afee8b4e3b71b6d5c Mon Sep 17 00:00:00 2001 From: Olga Bulat Date: Thu, 28 Apr 2022 11:44:29 +0300 Subject: [PATCH 01/10] Focus the filter sidebar when tabbing from FiltersButton --- src/components/VFilters/VSearchGridFilter.vue | 20 +++++------ src/components/VHeader/VFilterButton.vue | 1 + src/components/VHeader/VHeaderFilter.vue | 36 +++++++++++++++++-- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/components/VFilters/VSearchGridFilter.vue b/src/components/VFilters/VSearchGridFilter.vue index 57a47e59dd..6499eb1331 100644 --- a/src/components/VFilters/VSearchGridFilter.vue +++ b/src/components/VFilters/VSearchGridFilter.vue @@ -8,15 +8,15 @@

{{ $t('filter-list.filter-by') }}

- +
-
- +
@@ -54,10 +50,12 @@ import { useSearchStore } from '~/stores/search' import { areQueriesEqual } from '~/utils/search-query-transform' import VFilterChecklist from '~/components/VFilters/VFilterChecklist.vue' +import VButton from '~/components/VButton.vue' export default { name: 'VSearchGridFilter', components: { + VButton, VFilterChecklist, }, setup() { diff --git a/src/components/VHeader/VFilterButton.vue b/src/components/VHeader/VFilterButton.vue index 637bd8c1ee..8861a3a7e8 100644 --- a/src/components/VHeader/VFilterButton.vue +++ b/src/components/VHeader/VFilterButton.vue @@ -12,6 +12,7 @@ aria-controls="filters" :aria-label="mdMinLabel" @click="$emit('toggle')" + @keydown="$emit('keydown', $event)" > @@ -31,6 +32,9 @@ import { import { useFilterSidebarVisibility } from '~/composables/use-filter-sidebar-visibility' import { useBodyScrollLock } from '~/composables/use-body-scroll-lock' +import { keycodes } from '~/constants/key-codes' +import { Focus, focusIn } from '~/utils/focus-management' + import VTeleport from '~/components/VTeleport/VTeleport.vue' import VFilterButton from '~/components/VHeader/VFilterButton.vue' import VSearchGridFilter from '~/components/VFilters/VSearchGridFilter.vue' @@ -106,20 +110,47 @@ export default { } } + /** + * Focus the first element in the sidebar when navigating from the VFilterButton + * using keyboard `Tab` key. + * @param { KeyboardEvent } event + */ + const onKeyDown = (event) => { + if ( + isMinScreenMd.value && + event.key === keycodes.Tab && + filterSidebar.isVisible.value + ) { + // Prevent over-tabbing to the element after the target one + event.preventDefault() + // Cannot use refs when using portals (for sidebar) + focusIn(document.querySelector('#filters'), Focus.First) + } + } + + /** + * @typedef {{mode?: string, 'trigger-element'?: import('@nuxtjs/composition-api').ComputedRef, hide?: close, visible: import('@nuxtjs/composition-api').Ref, 'aria-label'?: string}} FilterOptions + */ + + /** @type {FilterOptions} */ const mobileOptions = { visible: visibleRef, - 'trigger-element': computed(() => nodeRef?.value?.firstChild), + 'trigger-element': + /** @type {import('@nuxtjs/composition-api').ComputedRef}*/ ( + computed(() => nodeRef?.value?.firstChild) + ), hide: close, 'aria-label': i18n.t('header.filter-button.simple').toString(), mode: 'mobile', } + /** @type {FilterOptions} */ const desktopOptions = { to: 'sidebar', visible: visibleRef, } /** - * @type { import('@nuxtjs/composition-api').Ref<{'trigger-element'?: import('@nuxtjs/composition-api').ComputedRef, hide?: () => void, visible: import('@nuxtjs/composition-api').Ref, 'aria-label'?: string, to?: string, mode?: string, hideOnClickOutside?: boolean }> } + * @type {Ref} */ const options = ref(mobileOptions) onMounted(() => { @@ -151,6 +182,7 @@ export default { open, close, onTriggerClick, + onKeyDown, triggerA11yProps, isMinScreenMd, options, From b71ad839ee4e2788849a82aad1a7ab2595b04881 Mon Sep 17 00:00:00 2001 From: Olga Bulat Date: Fri, 6 May 2022 09:11:50 +0300 Subject: [PATCH 02/10] Move focus from Filters button to the filters sidebar on 'Tab' press --- src/components/VFilters/VFilterChecklist.vue | 85 ++++++++++++------- src/components/VFilters/VSearchGridFilter.vue | 62 +++++++++++--- src/constants/filters.ts | 1 + src/utils/focus-management.ts | 2 +- 4 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/components/VFilters/VFilterChecklist.vue b/src/components/VFilters/VFilterChecklist.vue index 5153580ef6..066dc2f60c 100644 --- a/src/components/VFilters/VFilterChecklist.vue +++ b/src/components/VFilters/VFilterChecklist.vue @@ -24,7 +24,7 @@ - diff --git a/src/components/VFilters/VSearchGridFilter.vue b/src/components/VFilters/VSearchGridFilter.vue index 6499eb1331..794cf89a19 100644 --- a/src/components/VFilters/VSearchGridFilter.vue +++ b/src/components/VFilters/VSearchGridFilter.vue @@ -18,7 +18,7 @@ {{ $t('filter-list.clear') }} -
+ -