From 8a5ab092fe4a6b77a3895456d1ee547b0af01eba Mon Sep 17 00:00:00 2001 From: Olga Bulat Date: Wed, 15 Feb 2023 07:15:56 +0300 Subject: [PATCH 1/2] Make the sidebar appear after the header in the DOM --- .../VAllResultsGrid/VAllResultsGrid.vue | 18 +---- .../VExternalSearch/VExternalSearchForm.vue | 17 ----- src/components/VFilters/VSearchGridFilter.vue | 68 +------------------ src/components/VHeader/VHeaderDesktop.vue | 13 ---- src/components/VImageGrid/VImageGrid.vue | 19 +----- src/composables/use-focus-filters.ts | 29 -------- src/layouts/content-layout.vue | 66 ++++++++++-------- src/pages/search.vue | 9 --- src/pages/search/audio.vue | 14 +--- src/pages/search/image.vue | 9 +-- 10 files changed, 46 insertions(+), 216 deletions(-) delete mode 100644 src/composables/use-focus-filters.ts diff --git a/src/components/VAllResultsGrid/VAllResultsGrid.vue b/src/components/VAllResultsGrid/VAllResultsGrid.vue index 3decd57048..2a5b0473b4 100644 --- a/src/components/VAllResultsGrid/VAllResultsGrid.vue +++ b/src/components/VAllResultsGrid/VAllResultsGrid.vue @@ -5,13 +5,12 @@ class="results-grid mb-4 grid grid-cols-2 gap-4 lg:grid-cols-5 2xl:grid-cols-6" > @@ -58,11 +57,8 @@ import { useMediaStore } from "~/stores/media" import { useSearchStore } from "~/stores/search" import { useUiStore } from "~/stores/ui" -import { useFocusFilters } from "~/composables/use-focus-filters" import { useI18n } from "~/composables/use-i18n" -import { Focus } from "~/utils/focus-management" - import VSnackbar from "~/components/VSnackbar.vue" import VImageCellSquare from "~/components/VAllResultsGrid/VImageCellSquare.vue" import VAudioCell from "~/components/VAllResultsGrid/VAudioCell.vue" @@ -112,17 +108,6 @@ export default defineComponent({ const noResults = computed( () => fetchState.value.isFinished && allMedia.value.length === 0 ) - const focusFilters = useFocusFilters() - /** - * Move focus to the filters sidebar if shift-tab is pressed on the first content link. - * @param i - the index of the content link. - * @param event - keydown event - */ - const handleShiftTab = (event: KeyboardEvent, i: number) => { - if (i === 0) { - focusFilters.focusFilterSidebar(event, Focus.Last) - } - } const uiStore = useUiStore() const isSnackbarVisible = computed(() => uiStore.areInstructionsVisible) @@ -142,7 +127,6 @@ export default defineComponent({ resultsLoading, resultCounts, noResults, - handleShiftTab, contentLinkPath, diff --git a/src/components/VExternalSearch/VExternalSearchForm.vue b/src/components/VExternalSearch/VExternalSearchForm.vue index 7cf8b60627..cac6e2fb99 100644 --- a/src/components/VExternalSearch/VExternalSearchForm.vue +++ b/src/components/VExternalSearch/VExternalSearchForm.vue @@ -4,7 +4,6 @@ ref="sectionRef" class="external-sources flex flex-row place-items-center justify-center py-4" data-testid="external-sources-form" - @keydown.tab.exact="handleTab" > (() => { - const focusable = getFocusableElements(sectionRef.value) - return focusable[focusable.length - 1] - }) - - const handleTab = (event: KeyboardEvent) => { - if (event.target === lastFocusableElement.value) { - emit("tab", event) - } - } return { sectionRef, triggerRef, triggerElement, - handleTab, isMd, closeDialog, diff --git a/src/components/VFilters/VSearchGridFilter.vue b/src/components/VFilters/VSearchGridFilter.vue index da03765b20..e9cc18c4a0 100644 --- a/src/components/VFilters/VSearchGridFilter.vue +++ b/src/components/VFilters/VSearchGridFilter.vue @@ -13,17 +13,11 @@ variant="plain" class="label-bold absolute py-1 px-4 text-pink end-0 hover:ring hover:ring-pink" @click="clearFilters" - @keydown.shift.tab.exact="focusFilterButton" > {{ $t("filter-list.clear") }} -
+ - getFocusableElements(filtersFormRef.value) - ) - /** - * Find the last focusable element in VSearchGridFilter to add a 'Tab' keydown event - * handler to it. - * We could actually hard-code this because 'searchBy' is always the last now. - */ - const lastFocusableElement = computed(() => { - return focusableElements.value[focusableElements.value.length - 1] - }) - - /** - * We add the `Shift-Tab` handler to the first focusable checkbox so that focus can go back - * to the filter button - */ - const firstFocusableElement = computed( - () => focusableElements.value[0] - ) - - /** - * When the user presses 'Tab' on the last focusable element, we need to - * move focus to the first focusable element in main. - * @param event - */ - const handleTabKey = (event: KeyboardEvent) => { - if (!props.changeTabOrder) return - if (lastFocusableElement.value === event.target) { - event.preventDefault() - focusIn(document.querySelector("main"), Focus.First) - } - } - /** - * Move focus to the filter button only when this checkbox is the first focusable - * element in the search grid filter, i.e. the 'Clear filters' button is hidden. - * @param event - The keydown event - */ - const handleShiftTabKey = (event: KeyboardEvent) => { - if (!props.changeTabOrder) return - if ( - firstFocusableElement.value === event.target && - !isAnyFilterApplied.value - ) { - focusFilterButton(event) - } - } - - const focusFilters = useFocusFilters() - const focusFilterButton = (event?: KeyboardEvent) => { - focusFilters.focusFilterButton(event) - } - return { - firstFocusableElement, filtersFormRef, isAnyFilterApplied, filters, @@ -185,9 +124,6 @@ export default defineComponent({ filterTypeTitle, clearFilters: searchStore.clearFilters, toggleFilter: searchStore.toggleFilter, - handleTabKey, - handleShiftTabKey, - focusFilterButton, } }, }) diff --git a/src/components/VHeader/VHeaderDesktop.vue b/src/components/VHeader/VHeaderDesktop.vue index 549ee8528e..c6ad2291e7 100644 --- a/src/components/VHeader/VHeaderDesktop.vue +++ b/src/components/VHeader/VHeaderDesktop.vue @@ -42,7 +42,6 @@ aria-haspopup="dialog" :aria-expanded="isSidebarVisible" @toggle="toggleSidebar" - @tab="onTab" /> @@ -55,10 +54,8 @@ import { useUiStore } from "~/stores/ui" import { IsHeaderScrolledKey, IsSidebarVisibleKey } from "~/types/provides" -import { useFocusFilters } from "~/composables/use-focus-filters" import { useSearch } from "~/composables/use-search" -import { Focus } from "~/utils/focus-management" import { ensureFocus } from "~/utils/reakit-utils/focus" import VFilterButton from "~/components/VHeader/VFilterButton.vue" @@ -113,15 +110,6 @@ export default defineComponent({ const toggleSidebar = () => uiStore.toggleFilters() - const focusFilters = useFocusFilters() - /** - * Focus the first element in the sidebar when navigating from the VFilterButton - * using keyboard `Tab` key. - */ - const onTab = (event: KeyboardEvent) => { - focusFilters.focusFilterSidebar(event, Focus.First) - } - const isXl = computed(() => uiStore.isBreakpoint("xl")) return { @@ -140,7 +128,6 @@ export default defineComponent({ searchStatus, searchTerm, toggleSidebar, - onTab, } }, }) diff --git a/src/components/VImageGrid/VImageGrid.vue b/src/components/VImageGrid/VImageGrid.vue index e83386006e..f213a40e8a 100644 --- a/src/components/VImageGrid/VImageGrid.vue +++ b/src/components/VImageGrid/VImageGrid.vue @@ -2,11 +2,10 @@
@@ -33,8 +32,6 @@ import { useSearchStore } from "~/stores/search" import type { FetchState } from "~/types/fetch-state" import type { ImageDetail } from "~/types/media" -import { defineEvent } from "~/types/emits" - import VLoadMore from "~/components/VLoadMore.vue" import VImageCell from "~/components/VImageGrid/VImageCell.vue" @@ -61,23 +58,13 @@ export default defineComponent({ required: true, }, }, - emits: { - "shift-tab": defineEvent(), - }, - setup(props, { emit }) { + setup(props) { const searchStore = useSearchStore() const searchTerm = computed(() => searchStore.searchTerm) const isError = computed(() => Boolean(props.fetchState.fetchingError)) - const handleShiftTab = (event: KeyboardEvent, index: number) => { - if (index === 0) { - event.preventDefault() - emit("shift-tab") - } - } - - return { isError, handleShiftTab, searchTerm } + return { isError, searchTerm } }, }) diff --git a/src/composables/use-focus-filters.ts b/src/composables/use-focus-filters.ts deleted file mode 100644 index 49fbb0a0ca..0000000000 --- a/src/composables/use-focus-filters.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Focus, focusIn } from "~/utils/focus-management" -import { useUiStore } from "~/stores/ui" - -export const useFocusFilters = () => { - const focusFilterSidebar = (event?: KeyboardEvent, focus = Focus.Last) => { - const uiStore = useUiStore() - if (uiStore.isDesktopLayout && uiStore.isFilterVisible) { - if (event) event.preventDefault() - // Prevent over-tabbing to the element after the target one - // Cannot use refs when using portals (for sidebar) - const filtersSidebarElement = document.getElementById("filters") - if (filtersSidebarElement) { - focusIn(filtersSidebarElement, focus) - } - } - } - const focusFilterButton = (event?: KeyboardEvent) => { - const uiStore = useUiStore() - if (uiStore.isDesktopLayout && uiStore.isFilterVisible) { - if (event) event.preventDefault() - const filterButton = document.getElementById("filter-button") - if (filterButton) { - filterButton.focus() - } - } - } - - return { focusFilterSidebar, focusFilterButton } -} diff --git a/src/layouts/content-layout.vue b/src/layouts/content-layout.vue index 73b78b9a76..47a4104926 100644 --- a/src/layouts/content-layout.vue +++ b/src/layouts/content-layout.vue @@ -1,9 +1,16 @@