feat(a11y): Implement keyboard shortcuts and accessibility (Task 13)
- Create AccessibilityContext for global focus management and expanded state - Add roving tabindex to sidebar with Up/Down/Enter/Home/End navigation - Focus management: after login, after view change, after item expansion - Global Escape closes expanded items across all views - Add scope='col' to SummaryView table headers - Add focus-after-expand to ConsultationsView - Update ARIA roles: role='menu', role='menuitem', aria-current
This commit is contained in:
@@ -58,6 +58,7 @@ function ConsultationEntry({
|
||||
prefersReducedMotion,
|
||||
}: ConsultationEntryProps) {
|
||||
const contentRef = useRef<HTMLDivElement>(null)
|
||||
const expandedContentRef = useRef<HTMLDivElement>(null)
|
||||
const [height, setHeight] = useState<number | undefined>(isExpanded ? undefined : 0)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -75,6 +76,12 @@ function ConsultationEntry({
|
||||
setHeight(0)
|
||||
}, [isExpanded, prefersReducedMotion])
|
||||
|
||||
useEffect(() => {
|
||||
if (isExpanded && expandedContentRef.current) {
|
||||
expandedContentRef.current.focus()
|
||||
}
|
||||
}, [isExpanded])
|
||||
|
||||
const keyCodedEntry = consultation.codedEntries[0]
|
||||
|
||||
return (
|
||||
@@ -134,6 +141,7 @@ function ConsultationEntry({
|
||||
<ExpandedContent
|
||||
consultation={consultation}
|
||||
prefersReducedMotion={prefersReducedMotion}
|
||||
contentRef={expandedContentRef}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -162,15 +170,18 @@ function StatusDot({ isCurrent }: StatusDotProps) {
|
||||
interface ExpandedContentProps {
|
||||
consultation: Consultation
|
||||
prefersReducedMotion: boolean
|
||||
contentRef: React.RefObject<HTMLDivElement>
|
||||
}
|
||||
|
||||
function ExpandedContent({ consultation, prefersReducedMotion }: ExpandedContentProps) {
|
||||
function ExpandedContent({ consultation, prefersReducedMotion, contentRef }: ExpandedContentProps) {
|
||||
const opacity = prefersReducedMotion ? 1 : undefined
|
||||
const transition = prefersReducedMotion ? 'none' : 'opacity 150ms ease-out'
|
||||
|
||||
return (
|
||||
<div
|
||||
className="px-4 pb-4"
|
||||
ref={contentRef}
|
||||
tabIndex={-1}
|
||||
className="px-4 pb-4 outline-none"
|
||||
style={{ opacity, transition }}
|
||||
>
|
||||
<div className="pl-5 border-l border-gray-200 ml-1">
|
||||
|
||||
Reference in New Issue
Block a user