capacitor-accessibility

安装量: 44
排名: #16662

安装

npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-accessibility

Accessibility in Capacitor Apps Build inclusive apps that work for everyone. When to Use This Skill User needs accessibility User wants screen reader support User asks about WCAG User needs focus management Quick Checklist Semantic HTML Alt text for images Touch targets 44x44pt Color contrast 4.5:1 Focus indicators Screen reader labels Keyboard navigation Screen Reader Support Labels and Hints // Accessible button < button aria-label = " Delete item " aria-describedby = " delete-hint "

< TrashIcon /> </ button

< span id = " delete-hint " className = " sr-only "

Permanently removes this item </ span

// Accessible input < label htmlFor = " email "

Email </ label

< input id = " email " type = " email " aria-required = " true " aria-invalid = { hasError } aria-describedby = { hasError ? "email-error" : undefined } /> { hasError && < span id = " email-error "

Invalid email </ span

} Live Regions // Announce dynamic content < div aria-live = " polite " aria-atomic = " true "

{ message } </ div

// Urgent announcements < div aria-live = " assertive " role = " alert "

{ error } </ div

Touch Targets / Minimum 44x44pt / button , a , input { min-height : 44 px ; min-width : 44 px ; } / Icon buttons need padding / .icon-button { padding : 12 px ; } Color Contrast / Good contrast (4.5:1 for text) / .text { color :

333333

; background :

ffffff

; } / Don't rely on color alone / .error { color :

d32f2f

; border-left : 4 px solid

d32f2f

; / Visual indicator / } .error ::before { content : "⚠ " ; / Icon indicator / } Focus Management // Move focus after navigation useEffect ( ( ) => { const heading = document . querySelector ( 'h1' ) ; heading ?. focus ( ) ; } , [ page ] ) ; // Trap focus in modals function trapFocus ( element : HTMLElement ) { const focusable = element . querySelectorAll ( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ) ; const first = focusable [ 0 ] as HTMLElement ; const last = focusable [ focusable . length - 1 ] as HTMLElement ; element . addEventListener ( 'keydown' , ( e ) => { if ( e . key === 'Tab' ) { if ( e . shiftKey && document . activeElement === first ) { e . preventDefault ( ) ; last . focus ( ) ; } else if ( ! e . shiftKey && document . activeElement === last ) { e . preventDefault ( ) ; first . focus ( ) ; } } } ) ; } Native Accessibility iOS VoiceOver // Custom accessibility in native code element . isAccessibilityElement = true element . accessibilityLabel = "Play video" element . accessibilityHint = "Double tap to play" element . accessibilityTraits = . button Android TalkBack // Custom accessibility ViewCompat . setAccessibilityDelegate ( view , object : AccessibilityDelegateCompat ( ) { override fun onInitializeAccessibilityNodeInfo ( host : View , info : AccessibilityNodeInfoCompat ) { super . onInitializeAccessibilityNodeInfo ( host , info ) info . contentDescription = "Play video" } } ) Testing

iOS: Enable VoiceOver in Simulator

Settings > Accessibility > VoiceOver

Android: Enable TalkBack

Settings > Accessibility > TalkBack

Web: Use axe-core

bunx @axe-core/cli https://localhost:3000 Resources WCAG Guidelines: https://www.w3.org/WAI/WCAG21/quickref iOS Accessibility: https://developer.apple.com/accessibility Android Accessibility: https://developer.android.com/accessibility

返回排行榜