React Native accessibility (#539)
* React Native accessibility * First round of changes * Latest update * Checkpoint * Wrap up * Lint * Remove unhelpful image hints * Fix navigation * Fix rebase and lint * Mitigate an known issue with the password entry in login * Fix composer dismiss * Remove focus on input elements for web * Remove i and npm * pls work * Remove stray declaration * Regenerate yarn.lock --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>
This commit is contained in:
parent
c75c888de2
commit
83959c595d
86 changed files with 2479 additions and 1827 deletions
|
@ -26,6 +26,7 @@ export type ButtonType =
|
|||
| 'secondary-light'
|
||||
| 'default-light'
|
||||
|
||||
// TODO: Enforce that button always has a label
|
||||
export function Button({
|
||||
type = 'primary',
|
||||
label,
|
||||
|
@ -131,7 +132,8 @@ export function Button({
|
|||
<Pressable
|
||||
style={[typeOuterStyle, styles.outer, style]}
|
||||
onPress={onPressWrapped}
|
||||
testID={testID}>
|
||||
testID={testID}
|
||||
accessibilityRole="button">
|
||||
{label ? (
|
||||
<Text type="button" style={[typeLabelStyle, labelStyle]}>
|
||||
{label}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, {useRef} from 'react'
|
||||
import React, {PropsWithChildren, useMemo, useRef} from 'react'
|
||||
import {
|
||||
Dimensions,
|
||||
StyleProp,
|
||||
|
@ -39,6 +39,19 @@ type MaybeDropdownItem = DropdownItem | false | undefined
|
|||
|
||||
export type DropdownButtonType = ButtonType | 'bare'
|
||||
|
||||
interface DropdownButtonProps {
|
||||
testID?: string
|
||||
type?: DropdownButtonType
|
||||
style?: StyleProp<ViewStyle>
|
||||
items: MaybeDropdownItem[]
|
||||
label?: string
|
||||
menuWidth?: number
|
||||
children?: React.ReactNode
|
||||
openToRight?: boolean
|
||||
rightOffset?: number
|
||||
bottomOffset?: number
|
||||
}
|
||||
|
||||
export function DropdownButton({
|
||||
testID,
|
||||
type = 'bare',
|
||||
|
@ -50,18 +63,7 @@ export function DropdownButton({
|
|||
openToRight = false,
|
||||
rightOffset = 0,
|
||||
bottomOffset = 0,
|
||||
}: {
|
||||
testID?: string
|
||||
type?: DropdownButtonType
|
||||
style?: StyleProp<ViewStyle>
|
||||
items: MaybeDropdownItem[]
|
||||
label?: string
|
||||
menuWidth?: number
|
||||
children?: React.ReactNode
|
||||
openToRight?: boolean
|
||||
rightOffset?: number
|
||||
bottomOffset?: number
|
||||
}) {
|
||||
}: PropsWithChildren<DropdownButtonProps>) {
|
||||
const ref1 = useRef<TouchableOpacity>(null)
|
||||
const ref2 = useRef<View>(null)
|
||||
|
||||
|
@ -105,6 +107,18 @@ export function DropdownButton({
|
|||
)
|
||||
}
|
||||
|
||||
const numItems = useMemo(
|
||||
() =>
|
||||
items.filter(item => {
|
||||
if (item === undefined || item === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
return isBtn(item)
|
||||
}).length,
|
||||
[items],
|
||||
)
|
||||
|
||||
if (type === 'bare') {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
|
@ -112,7 +126,10 @@ export function DropdownButton({
|
|||
style={style}
|
||||
onPress={onPress}
|
||||
hitSlop={HITSLOP}
|
||||
ref={ref1}>
|
||||
ref={ref1}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Opens ${numItems} options`}
|
||||
accessibilityHint={`Opens ${numItems} options`}>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
)
|
||||
|
@ -283,9 +300,20 @@ const DropdownItems = ({
|
|||
const separatorColor =
|
||||
theme.colorScheme === 'dark' ? pal.borderDark : pal.border
|
||||
|
||||
const numItems = items.filter(isBtn).length
|
||||
|
||||
return (
|
||||
<>
|
||||
<TouchableWithoutFeedback onPress={onOuterPress}>
|
||||
<TouchableWithoutFeedback
|
||||
onPress={onOuterPress}
|
||||
// TODO: Refactor dropdown components to:
|
||||
// - (On web, if not handled by React Native) use semantic <select />
|
||||
// and <option /> elements for keyboard navigation out of the box
|
||||
// - (On mobile) be buttons by default, accept `label` and `nativeID`
|
||||
// props, and always have an explicit label
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Toggle dropdown"
|
||||
accessibilityHint="">
|
||||
<View style={[styles.bg]} />
|
||||
</TouchableWithoutFeedback>
|
||||
<View
|
||||
|
@ -301,7 +329,9 @@ const DropdownItems = ({
|
|||
testID={item.testID}
|
||||
key={index}
|
||||
style={[styles.menuItem]}
|
||||
onPress={() => onPressItem(index)}>
|
||||
onPress={() => onPressItem(index)}
|
||||
accessibilityLabel={item.label}
|
||||
accessibilityHint={`Option ${index + 1} of ${numItems}`}>
|
||||
{item.icon && (
|
||||
<FontAwesomeIcon
|
||||
style={styles.icon}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue