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

Conversation

obulat
Copy link
Contributor

@obulat obulat commented May 2, 2023

Fixes

Fixes #794 by @zackkrida
Fixes #541 by @obulat

Description

This PR wraps the search results into an ordered list to make the screen reader announce it as a contentlist, and to make it possible for the users to know how many items there are.

For the list aria-label, I used "Search results for query", without the media type. I think this might be clear from previous navigation, and it's easier to implement this way. I am open to suggestions about the text.

There are also a couple of other fixes:

  • image grid adds a Skeleton loader. This is a very simple addition that makes all of the search views consistent.
  • "Openverse" text is passed to the home link to prevent it saying "Opening braces openverse closing braces"
  • Removes the incorrect grid for the VContentLinks that I added in the grid fix PR (I accidentally added the grid fixes to both the "All content" results AND the content links).

Testing Instructions

Run the app using just frontend/run dev
Open a search page localhost:8443/search/image?q=cat and turn on a screenreader (CMD + F5 for VoiceOver on Mac, for Windows I used the UI to open NVDA)
On Mac, with Voiceover:
When you navigate to the search results, you should hear "Content list Search results for cat, 20 items" when screenreader reads out the page, and "Entering Search results for cat content list" when you navigate to the results.

On Windows, with NVDA:
You should hear "Search results for cat List with 27 items Cat link" when you navigate to the first result on All content list.

Checklist

  • My pull request has a descriptive title (not a vague title likeUpdate index.md).
  • My pull request targets the default branch of the repository (main) or a parent feature branch.
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.
  • I ran the DAG documentation generator (if applicable).

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@obulat obulat requested a review from a team as a code owner May 2, 2023 10:09
@obulat obulat requested review from zackkrida and dhruvkb May 2, 2023 10:09
@obulat obulat added 🟨 priority: medium Not blocking but should be addressed soon ✨ goal: improvement Improvement to an existing user-facing feature ♿️ aspect: a11y Concerns related to the project's accessibility 🧱 stack: frontend Related to the Nuxt frontend labels May 2, 2023
@github-actions
Copy link

github-actions bot commented May 2, 2023

Size Change: -4.97 kB (-1%)

Total Size: 857 kB

Filename Size Change
./frontend/.nuxt/dist/client/app.js 126 kB -15 B (0%)
./frontend/.nuxt/dist/client/components/v-all-results-grid.js 5.63 kB +38 B (+1%)
./frontend/.nuxt/dist/client/components/v-all-results-grid.modern.js 5.52 kB +61 B (+1%)
./frontend/.nuxt/dist/client/components/v-copy-license/components/v-error-image/components/v-media-reuse/components/v-search-grid/d219393b.js 10 kB +12 B (0%)
./frontend/.nuxt/dist/client/components/v-copy-license/components/v-error-image/components/v-media-reuse/components/v-search-grid/d219393b.modern.js 10 kB +15 B (0%)
./frontend/.nuxt/dist/client/components/v-image-cell.js 1.61 kB +18 B (+1%)
./frontend/.nuxt/dist/client/components/v-image-cell.modern.js 1.6 kB +22 B (+1%)
./frontend/.nuxt/dist/client/components/v-image-grid.js 3.84 kB +1.17 kB (+44%) 🚨
./frontend/.nuxt/dist/client/components/v-image-grid.modern.js 3.73 kB +1.18 kB (+46%) 🚨
./frontend/.nuxt/dist/client/components/v-related-audio.modern.js 1.29 kB +12 B (+1%)
./frontend/.nuxt/dist/client/components/v-related-images.js 1.1 kB -2.15 kB (-66%) 🏆
./frontend/.nuxt/dist/client/components/v-related-images.modern.js 1.1 kB -2.02 kB (-65%) 🏆
./frontend/.nuxt/dist/client/components/v-sources-table.js 15.1 kB -26 B (0%)
./frontend/.nuxt/dist/client/components/v-sources-table.modern.js 15.2 kB -26 B (0%)
./frontend/.nuxt/dist/client/pages/audio/_id/index.js 5.59 kB +16 B (0%)
./frontend/.nuxt/dist/client/pages/audio/_id/index.modern.js 5.03 kB +16 B (0%)
./frontend/.nuxt/dist/client/pages/image/_id/index.js 7.09 kB +535 B (+8%) 🔍
./frontend/.nuxt/dist/client/pages/image/_id/index.modern.js 6.43 kB +552 B (+9%) 🔍
./frontend/.nuxt/dist/client/pages/search/audio.js 3.66 kB +49 B (+1%)
./frontend/.nuxt/dist/client/pages/search/audio.modern.js 3.55 kB +41 B (+1%)
./frontend/.nuxt/dist/client/pages/search/image.js 544 B -2.3 kB (-81%) 🏆
./frontend/.nuxt/dist/client/pages/search/image.modern.js 548 B -2.19 kB (-80%) 🏆
ℹ️ View Unchanged
Filename Size Change
./frontend/.nuxt/dist/client/235.js 273 B 0 B
./frontend/.nuxt/dist/client/235.modern.js 278 B 0 B
./frontend/.nuxt/dist/client/236.js 1.85 kB 0 B
./frontend/.nuxt/dist/client/app.modern.js 117 kB +1 B (0%)
./frontend/.nuxt/dist/client/commons/app.js 90.3 kB -5 B (0%)
./frontend/.nuxt/dist/client/commons/app.modern.js 78.5 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/loading-icon.js 765 B -1 B (0%)
./frontend/.nuxt/dist/client/components/loading-icon.modern.js 770 B -1 B (0%)
./frontend/.nuxt/dist/client/components/table-sort-icon.js 514 B 0 B
./frontend/.nuxt/dist/client/components/table-sort-icon.modern.js 519 B 0 B
./frontend/.nuxt/dist/client/components/v-audio-cell.js 390 B -2 B (-1%)
./frontend/.nuxt/dist/client/components/v-audio-cell.modern.js 397 B 0 B
./frontend/.nuxt/dist/client/components/v-audio-details.js 2.91 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-audio-details.modern.js 2.33 kB -2 B (0%)
./frontend/.nuxt/dist/client/components/v-audio-details/components/v-content-report-form/components/v-content-report-popover/comp/e356c88c.js 3.85 kB 0 B
./frontend/.nuxt/dist/client/components/v-audio-details/components/v-content-report-popover/components/v-image-details/pages/audi/7832d35f.modern.js 4.13 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-audio-track-skeleton.js 1.02 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-audio-track-skeleton.modern.js 1.02 kB 0 B
./frontend/.nuxt/dist/client/components/v-audio-track.js 5.61 kB +5 B (0%)
./frontend/.nuxt/dist/client/components/v-audio-track.modern.js 5.54 kB +3 B (0%)
./frontend/.nuxt/dist/client/components/v-back-to-search-results-link.js 1.23 kB 0 B
./frontend/.nuxt/dist/client/components/v-back-to-search-results-link.modern.js 1.21 kB 0 B
./frontend/.nuxt/dist/client/components/v-bone.js 688 B 0 B
./frontend/.nuxt/dist/client/components/v-bone.modern.js 693 B 0 B
./frontend/.nuxt/dist/client/components/v-box-layout.js 1.28 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-box-layout.modern.js 1.27 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-content-link.js 977 B 0 B
./frontend/.nuxt/dist/client/components/v-content-link.modern.js 978 B 0 B
./frontend/.nuxt/dist/client/components/v-content-page.js 524 B 0 B
./frontend/.nuxt/dist/client/components/v-content-page.modern.js 528 B 0 B
./frontend/.nuxt/dist/client/components/v-content-report-button.js 493 B 0 B
./frontend/.nuxt/dist/client/components/v-content-report-button.modern.js 497 B 0 B
./frontend/.nuxt/dist/client/components/v-content-report-form.js 781 B 0 B
./frontend/.nuxt/dist/client/components/v-content-report-form.modern.js 4.04 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-content-report-popover.js 1.49 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-content-report-popover.modern.js 762 B 0 B
./frontend/.nuxt/dist/client/components/v-copy-button.js 4 kB 0 B
./frontend/.nuxt/dist/client/components/v-copy-button.modern.js 4 kB 0 B
./frontend/.nuxt/dist/client/components/v-copy-license.js 1.71 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-copy-license.modern.js 1.69 kB -2 B (0%)
./frontend/.nuxt/dist/client/components/v-dmca-notice.js 791 B -2 B (0%)
./frontend/.nuxt/dist/client/components/v-dmca-notice.modern.js 799 B 0 B
./frontend/.nuxt/dist/client/components/v-error-image.js 1.7 kB 0 B
./frontend/.nuxt/dist/client/components/v-error-image.modern.js 1.68 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-error-section.js 372 B -1 B (0%)
./frontend/.nuxt/dist/client/components/v-error-section.modern.js 375 B 0 B
./frontend/.nuxt/dist/client/components/v-external-search-form.js 2.45 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-external-search-form.modern.js 2.41 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-external-source-list.js 1.49 kB 0 B
./frontend/.nuxt/dist/client/components/v-external-source-list.modern.js 1.46 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-full-layout.js 2.13 kB -2 B (0%)
./frontend/.nuxt/dist/client/components/v-full-layout.modern.js 2.11 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-grid-skeleton.js 1.61 kB 0 B
./frontend/.nuxt/dist/client/components/v-grid-skeleton.modern.js 1.62 kB -2 B (0%)
./frontend/.nuxt/dist/client/components/v-home-gallery.js 5.28 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-home-gallery.modern.js 5.25 kB -2 B (0%)
./frontend/.nuxt/dist/client/components/v-homepage-content.js 1.76 kB 0 B
./frontend/.nuxt/dist/client/components/v-homepage-content.modern.js 1.73 kB 0 B
./frontend/.nuxt/dist/client/components/v-image-carousel.js 4.74 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-image-carousel.modern.js 4.7 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-image-details.js 2.53 kB +4 B (0%)
./frontend/.nuxt/dist/client/components/v-image-details.modern.js 1.96 kB -3 B (0%)
./frontend/.nuxt/dist/client/components/v-license-tab-panel.js 1.24 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-license-tab-panel.modern.js 1.21 kB 0 B
./frontend/.nuxt/dist/client/components/v-load-more.js 809 B -1 B (0%)
./frontend/.nuxt/dist/client/components/v-load-more.modern.js 707 B +1 B (0%)
./frontend/.nuxt/dist/client/components/v-media-license.js 828 B 0 B
./frontend/.nuxt/dist/client/components/v-media-license.modern.js 836 B -1 B (0%)
./frontend/.nuxt/dist/client/components/v-media-reuse.js 2.31 kB +3 B (0%)
./frontend/.nuxt/dist/client/components/v-media-reuse.modern.js 2.29 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-media-tag.js 416 B 0 B
./frontend/.nuxt/dist/client/components/v-media-tag.modern.js 420 B 0 B
./frontend/.nuxt/dist/client/components/v-modal.js 1.01 kB 0 B
./frontend/.nuxt/dist/client/components/v-modal.modern.js 995 B -1 B (0%)
./frontend/.nuxt/dist/client/components/v-no-results.js 1.42 kB 0 B
./frontend/.nuxt/dist/client/components/v-no-results.modern.js 1.39 kB 0 B
./frontend/.nuxt/dist/client/components/v-radio.js 1.54 kB 0 B
./frontend/.nuxt/dist/client/components/v-radio.modern.js 1.5 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-related-audio.js 1.29 kB +7 B (+1%)
./frontend/.nuxt/dist/client/components/v-report-desc-form.js 977 B 0 B
./frontend/.nuxt/dist/client/components/v-report-desc-form.modern.js 979 B 0 B
./frontend/.nuxt/dist/client/components/v-row-layout.js 1.68 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-row-layout.modern.js 1.68 kB +2 B (0%)
./frontend/.nuxt/dist/client/components/v-scroll-button.js 824 B 0 B
./frontend/.nuxt/dist/client/components/v-scroll-button.modern.js 828 B -1 B (0%)
./frontend/.nuxt/dist/client/components/v-search-grid.js 6.01 kB +6 B (0%)
./frontend/.nuxt/dist/client/components/v-search-grid.modern.js 5.92 kB 0 B
./frontend/.nuxt/dist/client/components/v-search-results-title.js 602 B +2 B (0%)
./frontend/.nuxt/dist/client/components/v-search-results-title.modern.js 606 B +1 B (0%)
./frontend/.nuxt/dist/client/components/v-server-timeout.js 299 B 0 B
./frontend/.nuxt/dist/client/components/v-server-timeout.modern.js 303 B 0 B
./frontend/.nuxt/dist/client/components/v-sketch-fab-viewer.js 1.01 kB -1 B (0%)
./frontend/.nuxt/dist/client/components/v-sketch-fab-viewer.modern.js 913 B 0 B
./frontend/.nuxt/dist/client/components/v-snackbar.js 1.16 kB -2 B (0%)
./frontend/.nuxt/dist/client/components/v-snackbar.modern.js 1.17 kB +1 B (0%)
./frontend/.nuxt/dist/client/components/v-warning-suppressor.js 306 B 0 B
./frontend/.nuxt/dist/client/components/v-warning-suppressor.modern.js 311 B 0 B
./frontend/.nuxt/dist/client/pages/about.js 1.4 kB 0 B
./frontend/.nuxt/dist/client/pages/about.modern.js 1.4 kB 0 B
./frontend/.nuxt/dist/client/pages/external-sources.js 1.55 kB 0 B
./frontend/.nuxt/dist/client/pages/external-sources.modern.js 1.56 kB 0 B
./frontend/.nuxt/dist/client/pages/feedback.js 1.34 kB -2 B (0%)
./frontend/.nuxt/dist/client/pages/feedback.modern.js 1.34 kB 0 B
./frontend/.nuxt/dist/client/pages/image/_id/report.js 1.84 kB +2 B (0%)
./frontend/.nuxt/dist/client/pages/image/_id/report.modern.js 4.71 kB +4 B (0%)
./frontend/.nuxt/dist/client/pages/index.js 7.33 kB 0 B
./frontend/.nuxt/dist/client/pages/index.modern.js 7.27 kB -2 B (0%)
./frontend/.nuxt/dist/client/pages/preferences.js 1.32 kB 0 B
./frontend/.nuxt/dist/client/pages/preferences.modern.js 1.32 kB 0 B
./frontend/.nuxt/dist/client/pages/privacy.js 1.01 kB 0 B
./frontend/.nuxt/dist/client/pages/privacy.modern.js 1.02 kB 0 B
./frontend/.nuxt/dist/client/pages/search-help.js 1.6 kB 0 B
./frontend/.nuxt/dist/client/pages/search-help.modern.js 1.58 kB +1 B (0%)
./frontend/.nuxt/dist/client/pages/search.js 2.2 kB 0 B
./frontend/.nuxt/dist/client/pages/search.modern.js 2.04 kB 0 B
./frontend/.nuxt/dist/client/pages/search/index.js 442 B 0 B
./frontend/.nuxt/dist/client/pages/search/index.modern.js 448 B 0 B
./frontend/.nuxt/dist/client/pages/search/model-3d.js 242 B 0 B
./frontend/.nuxt/dist/client/pages/search/model-3d.modern.js 246 B 0 B
./frontend/.nuxt/dist/client/pages/search/search-page.types.js 266 B 0 B
./frontend/.nuxt/dist/client/pages/search/search-page.types.modern.js 271 B 0 B
./frontend/.nuxt/dist/client/pages/search/video.js 240 B 0 B
./frontend/.nuxt/dist/client/pages/search/video.modern.js 243 B 0 B
./frontend/.nuxt/dist/client/pages/sources.js 1.51 kB 0 B
./frontend/.nuxt/dist/client/pages/sources.modern.js 1.51 kB 0 B
./frontend/.nuxt/dist/client/runtime.js 2.74 kB -2 B (0%)
./frontend/.nuxt/dist/client/runtime.modern.js 2.75 kB -1 B (0%)
./frontend/.nuxt/dist/client/vendors/app.js 64.6 kB +1 B (0%)
./frontend/.nuxt/dist/client/vendors/app.modern.js 63.8 kB 0 B

compressed-size-action

@github-actions
Copy link

github-actions bot commented May 2, 2023

Full-stack documentation: https://docs.openverse.org/_preview/1979

Please note that GitHub pages takes a little time to deploy newly pushed code, if the links above don't work or you see old versions, wait 5 minutes and try again.

You can check the GitHub pages deployment action list to see the current status of the deployments.

Copy link
Collaborator

@AetherUnbound AetherUnbound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for the thorough testing instructions!! I haven't done screenreader testing, so this was quite informative. I ended up trying to get orca working on Linux, and while I was getting screenreader results, I wasn't hearing the text you mentioned about the number of search results. I was also seeing the following in my console running the frontend:


 WARN  [vue-i18n] Value of key 'browse-page.aria.results' is not a string or function !                                                                                                                   13:00:14


 WARN  [vue-i18n] Cannot translate the value of keypath 'browse-page.aria.results'. Use the value of keypath as default. 

Could that be related? Is there an extra step I'm missing in terms of setup?

@obulat
Copy link
Contributor Author

obulat commented May 10, 2023

Thanks so much for the thorough testing instructions!! I haven't done screenreader testing, so this was quite informative. I ended up trying to get orca working on Linux, and while I was getting screenreader results, I wasn't hearing the text you mentioned about the number of search results. I was also seeing the following in my console running the frontend:


 WARN  [vue-i18n] Value of key 'browse-page.aria.results' is not a string or function !                                                                                                                   13:00:14


 WARN  [vue-i18n] Cannot translate the value of keypath 'browse-page.aria.results'. Use the value of keypath as default. 

Could that be related? Is there an extra step I'm missing in terms of setup?

Thank you so much for testing, @AetherUnbound ! I'm sure the set up was quite time and effort consuming. Having a Linux machine for testing, too, is great for breadth of different setups.

Yes, the two points you mention are related. We save all of the texts as json5 in locales/en.json5. There is a step during the frontend build that converts the json5 file into a json file that is actually used in the app. That step usually runs when you do just frontend/run dev, but it seems that it didn't for some reason. To specifically copy the new strings to the json file, you can run just frontend/run i18n:en. This should fix it. There is also a way to do it manually: copy the string from en.json5 to en.json with the same key (so, adding a key "results" nested under browse-page.aria), but it shouldn't be necessary.

@AetherUnbound
Copy link
Collaborator

Got it! That made those errors go away. Now what I'm hearing when I click on the "Cat" header in the search results is:

Cat heading level one
Search results for cat
Load more results not finding what you're looking for?

I'm still not hearing the specific result count 😮 is there a better way for me to navigate to the search results? If I use TAB I have to hit it a lot to iterate through all the filters before getting to the search results.

Copy link
Collaborator

@AetherUnbound AetherUnbound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes generally make sense to me! Took me a sec to grok v-for 😄

I suspect the not-counting-results may be a difference between screen reader implementations, since your changes only include reading out the "search results for" label. So I think this is working as expected!

@zackkrida
Copy link
Member

@AetherUnbound we have some docs on general screen reader testing here that might prove useful!

https://docs.openverse.org/frontend/reference/testing_guidelines.html#accessibility

Copy link
Member

@zackkrida zackkrida left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@obulat I am also not hearing result counts, just being told that I am in a group and then read the aria label "Search results for {query}."

@obulat
Copy link
Contributor Author

obulat commented May 13, 2023

@obulat I am also not hearing result counts, just being told that I am in a group and then read the aria label "Search results for {query}."

I think this is how VoiceOver implements it. When you navigate to the results using Tab, you don't hear the number of items, but if you navigate to the page, you will hear:
Firefox, Cat | Openverse, window, heading level 1, Cat, content list Search results for cat. 32 items, Search results for cat., content list, Load more results, button, group with ...

I also tried other lists on other sites, and they do not announce the number of items in the contentlist.

I also tested this change with NVDA on windows, and it says "Search results for "Cat". List with 32 items. Cat cafe in Seol link" when I navigate to the first result using keyboard.

The audio results don't say anything about the contentlist in NVDA because they have to have role="application" applied to them to get controls like space bar and arrows to work well with NVDA. So I don't know what the best solution for audio would be.

@obulat obulat force-pushed the add/list_for_results_a11y branch from b9c66a4 to 217f349 Compare May 13, 2023 13:28
@obulat obulat requested a review from zackkrida May 14, 2023 04:45
@obulat obulat force-pushed the add/list_for_results_a11y branch from 217f349 to 655f7f1 Compare May 14, 2023 04:48
@openverse-bot
Copy link
Collaborator

Based on the medium urgency of this PR, the following reviewers are being gently reminded to review this PR:

@zackkrida
@dhruvkb
This reminder is being automatically generated due to the urgency configuration.

Excluding weekend1 days, this PR was ready for review 8 day(s) ago. PRs labelled with medium urgency are expected to be reviewed within 4 weekday(s)2.

@obulat, if this PR is not ready for a review, please draft it to prevent reviewers from getting further unnecessary pings.

Footnotes

  1. Specifically, Saturday and Sunday.

  2. For the purpose of these reminders we treat Monday - Friday as weekdays. Please note that the operation that generates these reminders runs at midnight UTC on Monday - Friday. This means that depending on your timezone, you may be pinged outside of the expected range.

@obulat obulat merged commit 930a2ec into main May 15, 2023
@obulat obulat deleted the add/list_for_results_a11y branch May 15, 2023 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
♿️ aspect: a11y Concerns related to the project's accessibility ✨ goal: improvement Improvement to an existing user-facing feature 🟨 priority: medium Not blocking but should be addressed soon 🧱 stack: frontend Related to the Nuxt frontend
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Move search results to an ordered list Add loading skeleton to VImageGrid
4 participants