diff --git a/src/tedi/components/form/search/search.spec.tsx b/src/tedi/components/form/search/search.spec.tsx
index f1dee1bc9..8d3710e31 100644
--- a/src/tedi/components/form/search/search.spec.tsx
+++ b/src/tedi/components/form/search/search.spec.tsx
@@ -25,6 +25,23 @@ describe('Search component', () => {
expect(input).toBeInTheDocument();
});
+ it('does not name the search region with the placeholder (avoids double announcement)', () => {
+ render();
+ const region = screen.getByRole('search');
+ expect(region).toHaveAttribute('aria-label', 'search');
+ expect(region.getAttribute('aria-label')).not.toBe('Search by name or keyword');
+ });
+
+ it('uses the provided ariaLabel as the search region name', () => {
+ render();
+ expect(screen.getByRole('search')).toHaveAttribute('aria-label', 'Search products');
+ });
+
+ it('falls back to the generic label when ariaLabel is an empty string', () => {
+ render();
+ expect(screen.getByRole('search')).toHaveAttribute('aria-label', 'search');
+ });
+
it('calls onSearch when the search button is clicked', () => {
render();
const button = screen.getByRole('button', { name: /search/i });
diff --git a/src/tedi/components/form/search/search.tsx b/src/tedi/components/form/search/search.tsx
index 7de2cfdad..16bee3a08 100644
--- a/src/tedi/components/form/search/search.tsx
+++ b/src/tedi/components/form/search/search.tsx
@@ -73,8 +73,13 @@ export const Search = forwardRef(
...(button ? {} : { icon: resolvedSearchIcon }),
};
- const defaultAriaLabel = placeholder || getLabel('search');
- const searchAriaLabel = ariaLabel ?? defaultAriaLabel;
+ // Name the search landmark with the generic "search" label rather than the
+ // placeholder. The input already surfaces the placeholder, so reusing it as
+ // the region name makes screen readers announce it twice. Consumers should
+ // set `ariaLabel` to give the region a distinct name (e.g. "Search products").
+ // `||` (not `??`) so an empty-string `ariaLabel` also falls back — otherwise
+ // the landmark would render with an empty accessible name.
+ const searchAriaLabel = ariaLabel || getLabel('search');
return (