A search input without an associated label fails WCAG 2.2 SC 4.1.2 (Name, Role, Value) — screen readers announce the field as "edit text" with no context, making it unusable for blind users. Autocomplete dropdowns that don't use aria-live or role="listbox" are invisible to assistive technology: suggestions appear visually but are never announced, so keyboard and screen reader users cannot benefit from them. WCAG 2.2 SC 4.1.3 (Status Messages) further requires that dynamic content changes like suggestion updates be communicated without requiring focus movement.
Medium because the failure eliminates search usability for screen reader users while stopping short of a critical data or security exposure.
Label the search input explicitly and annotate the suggestions container with ARIA roles. In components/SearchInput.tsx:
<label htmlFor="search-input">Search listings</label>
<input
id="search-input"
type="text"
role="combobox"
aria-expanded={suggestions.length > 0}
aria-autocomplete="list"
aria-controls="suggestions-list"
/>
{suggestions.length > 0 && (
<ul
id="suggestions-list"
role="listbox"
aria-live="polite"
>
{suggestions.map((s, i) => (
<li key={i} role="option">{s.name}</li>
))}
</ul>
)}
aria-live="polite" causes screen readers to announce new suggestions without interrupting the user's current context. Test with VoiceOver (macOS) or NVDA (Windows) to verify announcements fire on each suggestion update.
ID: directory-search-discovery.pagination-url.search-a11y
Severity: medium
What to look for: Enumerate all relevant files and Inspect the search input. Check for an associated <label> element or aria-label/aria-labelledby on the input. For autocomplete suggestions, check whether there's an aria-live="polite" or role="listbox" on the suggestions container so screen readers announce new suggestions.
Pass criteria: At least 1 implementation must be present. Search input has a label (visible or via aria-label). Autocomplete suggestions container uses aria-live="polite" or role="combobox" + aria-expanded, allowing screen readers to announce new suggestions.
Fail criteria: Search input has no label. Autocomplete suggestions are not announced to screen readers.
Skip (N/A) when: Search is not implemented. Signal: no search input found.
Detail on fail: "Search input has no label or aria-label." or "Autocomplete dropdown has no aria-live. Screen readers won't announce suggestions."
Remediation: Add accessibility attributes to search and autocomplete:
// components/SearchInput.tsx
export function SearchInput({ onSuggestionSelect }) {
const [suggestions, setSuggestions] = useState([])
return (
<div className="relative">
<label htmlFor="search-input">Search listings</label>
<input
id="search-input"
type="text"
onChange={e => handleSearchChange(e.target.value)}
aria-describedby="suggestions-list"
role="combobox"
aria-expanded={suggestions.length > 0}
aria-autocomplete="list"
/>
{suggestions.length > 0 && (
<ul
id="suggestions-list"
role="listbox"
aria-live="polite"
className="absolute top-full left-0 right-0 bg-white border"
>
{suggestions.map((s, i) => (
<li key={i} role="option" onClick={() => onSuggestionSelect(s)}>
{s.name}
</li>
))}
</ul>
)}
</div>
)
}