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

Use contentlist role for search results for a11y #1979

Merged
merged 6 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 10 additions & 10 deletions frontend/src/components/VAudioDetails/VRelatedAudio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
{{ $t("audio-details.related-audios") }}
</h2>
<!-- Negative margin compensates for the `p-4` padding in row layout. -->
<div
<ol
v-if="!fetchState.fetchingError"
:aria-label="$t('audio-details.related-audios')"
class="-mx-2 mb-12 flex flex-col gap-4 md:-mx-4"
>
<VAudioTrack
v-for="audio in media"
:key="audio.id"
:audio="audio"
layout="row"
:size="audioTrackSize"
/>
<LoadingIcon v-show="fetchState.isFetching" />
</div>
<li v-for="audio in media" :key="audio.id">
<VAudioTrack :audio="audio" layout="row" :size="audioTrackSize" />
</li>
</ol>
<LoadingIcon
v-if="!fetchState.fetchingError"
v-show="fetchState.isFetching"
/>
<p v-show="!!fetchState.fetchingError">
{{ $t("media-details.related-error") }}
</p>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VHeader/VLogoButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<VButton
as="VLink"
href="/"
:aria-label="$t('header.home-link')"
:aria-label="$t('header.home-link', { openverse: 'Openverse' }).toString()"
variant="plain"
size="disabled"
class="text-dark-charcoal hover:bg-yellow"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/VImageDetails/VRelatedImages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:images="media"
:is-single-page="true"
:fetch-state="fetchState"
:image-grid-label="$t('image-details.related-images').toString()"
/>
</aside>
</template>
Expand Down
28 changes: 12 additions & 16 deletions frontend/src/components/VSearchResultsGrid/VAllResultsGrid.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
<template>
<div>
<div
v-if="!noResults"
class="results-grid mb-4 grid gap-4"
:class="
isSidebarVisible
? 'grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4'
: 'grid-cols-2 lg:grid-cols-5 2xl:grid-cols-6'
"
>
<div v-if="!noResults" class="results-grid mb-4 grid grid-cols-2 gap-x-4">
<VContentLink
v-for="[mediaType, count] in resultCounts"
:key="mediaType"
:media-type="mediaType"
:results-count="count"
:to="contentLinkPath(mediaType)"
class="lg:col-span-2"
/>
</div>
<VSnackbar size="large" :is-visible="isSnackbarVisible">
Expand All @@ -29,33 +20,34 @@
v-if="resultsLoading && allMedia.length === 0"
is-for-tab="all"
/>
<div
<ol
v-else
class="results-grid grid grid-cols-2 gap-4"
:class="
isSidebarVisible
? 'lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5'
: 'sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6'
"
:aria-label="$t('browse-page.aria.results', { query: searchTerm })"
>
<div v-for="item in allMedia" :key="item.id">
<li v-for="item in allMedia" :key="item.id">
<VImageCell
v-if="item.frontendMediaType === 'image'"
v-if="isDetail.image(item)"
:key="item.id"
:image="item"
:search-term="searchTerm"
aspect-ratio="square"
/>
<VAudioCell
v-if="item.frontendMediaType === 'audio'"
v-if="isDetail.audio(item)"
:key="item.id"
:audio="item"
:search-term="searchTerm"
@interacted="hideSnackbar"
@focus.native="showSnackbar"
/>
</div>
</div>
</li>
</ol>

<VLoadMore class="mt-4" />
</div>
Expand All @@ -68,6 +60,8 @@ import { useMediaStore } from "~/stores/media"
import { useSearchStore } from "~/stores/search"
import { useUiStore } from "~/stores/ui"

import { isDetail } from "~/types/media"

import { useI18n } from "~/composables/use-i18n"

import VSnackbar from "~/components/VSnackbar.vue"
Expand Down Expand Up @@ -148,6 +142,8 @@ export default defineComponent({
isSnackbarVisible,
showSnackbar,
hideSnackbar,

isDetail,
}
},
})
Expand Down
60 changes: 33 additions & 27 deletions frontend/src/components/VSearchResultsGrid/VImageCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,36 @@
:aria-label="image.title"
:style="styles.container"
>
<figure
itemprop="image"
itemscope
itemtype="https://schema.org/ImageObject"
class="absolute w-full rounded-sm"
:class="{ 'relative aspect-square': isSquare }"
:style="styles.figure"
>
<img
ref="img"
loading="lazy"
class="block w-full rounded-sm object-cover"
:class="isSquare ? 'h-full' : 'margin-auto'"
:alt="image.title"
:src="imageUrl"
:width="imgWidth"
:height="imgHeight"
itemprop="thumbnailUrl"
@load="getImgDimension"
@error="onImageLoadError($event)"
/>
<figcaption
class="invisible absolute bottom-0 left-0 bg-white p-1 text-dark-charcoal group-hover:visible group-focus:visible"
<Component :is="as">
<figure
itemprop="image"
itemscope
itemtype="https://schema.org/ImageObject"
class="absolute w-full rounded-sm"
:class="{ 'relative aspect-square': isSquare }"
:style="styles.figure"
>
<h2 class="sr-only">{{ image.title }}</h2>
<VLicense :license="image.license" :hide-name="true" />
</figcaption>
</figure>
<img
ref="img"
loading="lazy"
class="block w-full rounded-sm object-cover"
:class="isSquare ? 'h-full' : 'margin-auto'"
:alt="image.title"
:src="imageUrl"
:width="imgWidth"
:height="imgHeight"
itemprop="thumbnailUrl"
@load="getImgDimension"
@error="onImageLoadError($event)"
/>
<figcaption
class="invisible absolute bottom-0 left-0 bg-white p-1 text-dark-charcoal group-hover:visible group-focus:visible"
>
<h2 class="sr-only">{{ image.title }}</h2>
<VLicense :license="image.license" :hide-name="true" />
</figcaption>
</figure>
</Component>
<i v-if="!isSquare" :style="styles.iPadding" class="block" aria-hidden />
</VLink>
</template>
Expand Down Expand Up @@ -80,6 +82,10 @@ export default defineComponent({
type: String as PropType<AspectRatio>,
default: "square",
},
as: {
type: String as PropType<"li" | "div">,
default: "li",
},
},
setup(props) {
const isSquare = computed(() => props.aspectRatio === "square")
Expand Down
16 changes: 13 additions & 3 deletions frontend/src/components/VSearchResultsGrid/VImageGrid.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<template>
<section>
<div class="image-grid flex flex-wrap gap-4">
<VGridSkeleton
v-if="!images.length && !fetchState.isFinished"
is-for-tab="image"
/>
<ol class="image-grid flex flex-wrap gap-4" :aria-label="imageGridLabel">
<VImageCell
v-for="image in images"
:key="image.id"
as="li"
:image="image"
:search-term="searchTerm"
aspect-ratio="intrinsic"
/>
</div>
</ol>
<h5 v-if="isError && !fetchState.isFinished" class="py-4">
{{ fetchState.fetchingError }}
</h5>
Expand All @@ -33,12 +38,13 @@ import { useSearchStore } from "~/stores/search"
import type { FetchState } from "~/types/fetch-state"
import type { ImageDetail } from "~/types/media"

import VGridSkeleton from "~/components/VSkeleton/VGridSkeleton.vue"
import VLoadMore from "~/components/VLoadMore.vue"
import VImageCell from "~/components/VSearchResultsGrid/VImageCell.vue"

export default defineComponent({
name: "ImageGrid",
components: { VLoadMore, VImageCell },
components: { VGridSkeleton, VLoadMore, VImageCell },
props: {
images: {
type: Array as PropType<ImageDetail[]>,
Expand All @@ -58,6 +64,10 @@ export default defineComponent({
type: Object as PropType<FetchState>,
required: true,
},
imageGridLabel: {
type: String,
required: true,
},
},
setup(props) {
const searchStore = useSearchStore()
Expand Down
1 change: 1 addition & 0 deletions frontend/src/locales/scripts/en.json5
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@
"remove-filter": "remove filter",
"license-explanation": "license explanation",
creator: "search by creator",
results: "Search results for {query}.",
},
},
"media-details": {
Expand Down
26 changes: 14 additions & 12 deletions frontend/src/pages/search/audio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@
v-if="results.length === 0 && !fetchState.isFinished"
is-for-tab="audio"
/>
<VAudioTrack
v-for="audio in results"
:key="audio.id"
class="mb-2 md:mb-1"
:audio="audio"
:size="audioTrackSize"
layout="row"
:search-term="searchTerm"
@interacted="hideSnackbar"
@mousedown.native="handleMouseDown"
@focus.native="showSnackbar"
/>
<ol :aria-label="$t('browse-page.aria.results', { query: searchTerm })">
<li v-for="audio in results" :key="audio.id">
<VAudioTrack
class="mb-2 md:mb-1"
:audio="audio"
:size="audioTrackSize"
layout="row"
:search-term="searchTerm"
@interacted="hideSnackbar"
@mousedown.native="handleMouseDown"
@focus.native="showSnackbar"
/>
</li>
</ol>
<VLoadMore />
</section>
</template>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/search/image.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
:images="results"
:is-single-page="false"
:fetch-state="fetchState"
:image-grid-label="$t('browse-page.aria.results', { query: searchTerm })"
/>
</template>

Expand Down
9 changes: 9 additions & 0 deletions frontend/src/types/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,12 @@ export interface ImageDimensions {
}

export type AspectRatio = "square" | "intrinsic"

export const isDetail = {
audio: (media: Media): media is AudioDetail => {
return media.frontendMediaType === "audio"
},
image: (media: Media): media is ImageDetail => {
return media.frontendMediaType === "image"
},
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/test/unit/specs/components/v-image-grid.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const propsData = {
fetchingError: null,
},
isSinglePage: false,
imageGridLabel: "Image Results",
}

describe("VImageGrid", () => {
Expand Down