diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c20d1a6..b625b112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to - ♿️(frontend) improve version history list accessibility #2033 - ♿️(frontend) fix more options menu feedback for screen readers #2071 - ♿(frontend) focus skip link on headings and skip grid dropzone #1983 +- ♿️(frontend) fix search modal accessibility issues #2054 ## [v4.8.2] - 2026-03-19 diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts index ecfbf517..36cebff7 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts @@ -29,7 +29,7 @@ test.describe('Document search', () => { await page.getByTestId('search-docs-button').click(); await expect( - page.getByRole('img', { name: 'No active search' }), + page.getByLabel('Search modal').locator('img[alt=""]'), ).toBeVisible(); await expect( @@ -107,7 +107,7 @@ test.describe('Document search', () => { await searchButton.click(); await expect( - page.getByRole('combobox', { name: 'Quick search input' }), + page.getByRole('combobox', { name: 'Search documents' }), ).toBeVisible(); await expect(filters).toBeHidden(); @@ -120,7 +120,7 @@ test.describe('Document search', () => { await searchButton.click(); await expect( - page.getByRole('combobox', { name: 'Quick search input' }), + page.getByRole('combobox', { name: 'Search documents' }), ).toBeVisible(); await expect(filters).toBeHidden(); @@ -164,9 +164,9 @@ test.describe('Document search', () => { const searchButton = page.getByTestId('search-docs-button'); await searchButton.click(); - await page.getByRole('combobox', { name: 'Quick search input' }).click(); + await page.getByRole('combobox', { name: 'Search documents' }).click(); await page - .getByRole('combobox', { name: 'Quick search input' }) + .getByRole('combobox', { name: 'Search documents' }) .fill('sub page search'); // Expect to find the first and second docs in the results list @@ -188,7 +188,7 @@ test.describe('Document search', () => { ); await searchButton.click(); await page - .getByRole('combobox', { name: 'Quick search input' }) + .getByRole('combobox', { name: 'Search documents' }) .fill('second'); // Now there is a sub page - expect to have the focus on the current doc diff --git a/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchContent.tsx b/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchContent.tsx index 6ab9ac75..6db68830 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchContent.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchContent.tsx @@ -1,3 +1,4 @@ +import { announce } from '@react-aria/live-announcer'; import { t } from 'i18next'; import { useEffect, useState } from 'react'; import { InView } from 'react-intersection-observer'; @@ -73,10 +74,12 @@ export const DocSearchContent = ({ docs = docs.filter(filterResults); } + const elements = search || isSearchNotMandatory ? docs : []; + setDocsData({ groupName: docs.length > 0 ? groupName : '', groupKey: 'docs', - elements: search || isSearchNotMandatory ? docs : [], + elements, emptyString: t('No document found'), endActions: hasNextPage ? [ @@ -90,6 +93,13 @@ export const DocSearchContent = ({ ] : [], }); + + if (search) { + announce( + t('{{count}} result(s) available', { count: elements.length }), + 'polite', + ); + } }, [ search, data?.pages, diff --git a/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx b/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx index 74db8dc9..a43c3874 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx @@ -64,6 +64,7 @@ const DocSearchModalGlobal = ({ aria-describedby="doc-search-modal-title" >