Skip to content
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
17 changes: 17 additions & 0 deletions src/tedi/components/form/search/search.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ describe('Search component', () => {
expect(input).toBeInTheDocument();
});

it('does not name the search region with the placeholder (avoids double announcement)', () => {
render(<Search {...defaultProps} placeholder="Search by name or keyword" />);
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(<Search {...defaultProps} ariaLabel="Search products" />);
expect(screen.getByRole('search')).toHaveAttribute('aria-label', 'Search products');
});

it('falls back to the generic label when ariaLabel is an empty string', () => {
render(<Search {...defaultProps} ariaLabel="" />);
expect(screen.getByRole('search')).toHaveAttribute('aria-label', 'search');
});

it('calls onSearch when the search button is clicked', () => {
render(<Search {...defaultProps} button={{ children: 'Search' }} />);
const button = screen.getByRole('button', { name: /search/i });
Expand Down
9 changes: 7 additions & 2 deletions src/tedi/components/form/search/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,13 @@ export const Search = forwardRef<TextFieldForwardRef, SearchProps>(
...(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 (
<div
Expand Down
Loading