Glin UI

Accessibility QA

Screen Reader Testing

Run this pass before each release to check how forms, dialogs, and data views sound, not just how they look.

Test matrix

Cover at least one desktop and one mobile screen reader.

Recommended screen reader and browser pairings
PlatformScreen readerBrowser
macOSVoiceOverSafari
WindowsNVDAChrome or Firefox
iOSVoiceOverSafari
AndroidTalkBackChrome

Release Checklist

Mark each item during manual QA.

Starter shortcuts

Enough to navigate a page by headings, landmarks, and forms.

Screen reader navigation shortcuts
KeysExpected behaviorWhere
CtrlOptionCmdHNext headingVoiceOver (macOS)
HNext headingNVDA browse mode
DNext landmarkNVDA browse mode
FNext form fieldNVDA browse mode
InsertSpaceToggle browse and focus modeNVDA

Announced search results pattern

Use aria-live="polite" for async updates that should be spoken without interrupting what the user is doing.

import { useEffect, useState } from "react"
import { Input } from "@glinui/ui"
export function SearchAnnounce() {
const [query, setQuery] = useState("")
const [count, setCount] = useState(0)
useEffect(() => {
const timeout = setTimeout(() => {
// Replace with real search call
setCount(query ? 12 : 0)
}, 120)
return () => clearTimeout(timeout)
}, [query])
return (
<div className="space-y-2">
<Input
aria-label="Search components"
placeholder="Search components"
value={query}
onChange={(event) => setQuery(event.target.value)}
/>
<p aria-live="polite" className="text-sm text-muted">
{count} results
</p>
</div>
)
}