Skip to content

Commit 72cf358

Browse files
author
Artur Bien
committed
feat: accessibility improvements
1 parent 324c821 commit 72cf358

File tree

11 files changed

+50
-15
lines changed

11 files changed

+50
-15
lines changed

src/Button/Button.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type ButtonProps = React.ComponentPropsWithRef<typeof View> & {
3333
};
3434

3535
const Button = ({
36+
accessible,
3637
accessibilityLabel,
3738
active = false,
3839
children,
@@ -91,11 +92,16 @@ const Button = ({
9192
onPress={onPress}
9293
onLongPress={onLongPress}
9394
disabled={disabled}
95+
// TODO: use onHideUnderlay or onPressIn?
9496
onHideUnderlay={() => setIsPressed(false)}
9597
onShowUnderlay={() => setIsPressed(true)}
9698
underlayColor='none'
97-
accessibilityRole='button'
9899
accessibilityLabel={accessibilityLabel}
100+
accessibilityTraits={disabled ? ['button', 'disabled'] : 'button'}
101+
accessibilityComponentType='button'
102+
accessibilityRole='button'
103+
accessibilityState={{ disabled }}
104+
accessible={accessible}
99105
>
100106
<View pointerEvents='none'>
101107
{typeof children === 'string' ? (

src/Cutout/Cutout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const Cutout = ({
3636
const styles = StyleSheet.create({
3737
wrapper: {
3838
position: 'relative',
39+
// TODO: add another element to compensate for borders?
3940
// to compensate for borders
4041
padding: 4,
4142
},

src/List/ListAccordion.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Props = React.ComponentPropsWithRef<typeof View> & {
2727
titleStyle?: StyleProp<TextStyle>;
2828
};
2929

30+
// TODO: add accessibilityState=expanded ?
3031
const ListAccordion = ({
3132
children,
3233
defaultExpanded,

src/List/ListItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const ListItem = ({
3636
return (
3737
<View style={style} {...rest}>
3838
<TouchableOpacity onPress={onPress} accessibilityRole='button'>
39-
<View style={[styles.content]} pointerEvents='none'>
39+
<View style={[styles.content]}>
4040
{left && <View style={[styles.left]}>{left}</View>}
4141
{title && (
4242
<Text style={[styles.title, { color: theme.progress }, titleStyle]}>

src/Menu/MenuItem.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { Text } from '..';
1414

1515
// TODO: add icon prop
1616

17-
type Props = React.ComponentPropsWithRef<typeof View> & {
17+
type Props = {
1818
disabled?: boolean;
1919
onPress: () => void;
2020
primary?: boolean;
@@ -55,7 +55,8 @@ export const Item = ({
5555
onShowUnderlay={() => setIsPressed(true)}
5656
underlayColor='none'
5757
// TODO: which accessibilityRole put in here?
58-
accessibilityRole='button'
58+
accessibilityRole='menuitem'
59+
accessibilityState={{ disabled }}
5960
>
6061
<View pointerEvents='none' style={[styles.content]}>
6162
<Text

src/Progress/Progress.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ const Progress = ({
4949
},
5050
style,
5151
]}
52+
accessible
53+
accessibilityRole='progressbar'
54+
accessibilityValue={{
55+
min: 0,
56+
max: 100,
57+
now: percent,
58+
}}
5259
>
5360
<View style={[styles.progressWrapper]}>
5461
{variant === 'tile' ? (

src/ScrollView/ScrollView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ const ScrollView = ({
154154
</View>
155155
{(!contentFullyVisible || alwaysShowScrollbars) && (
156156
<View
157+
accessibilityRole='scrollbar'
157158
style={[
158159
{
159160
flexDirection: horizontal ? 'row' : 'column',

src/Select/SelectBase.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const SelectItem = ({ option, onPress, isSelected }: SelectItemProps) => {
2626
onPress={() => onPress(option)}
2727
onHideUnderlay={() => setIsPressed(false)}
2828
onShowUnderlay={() => setIsPressed(true)}
29-
accessibilityRole='menuitem'
3029
underlayColor='none'
3130
// delay to prevent item highlighting on scroll
3231
delayPressIn={70}

src/Slider/Slider.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,17 @@ const Slider = ({
123123
).current;
124124

125125
return (
126-
<View style={[styles.wrapper, style]} {...rest}>
126+
<View
127+
style={[styles.wrapper, style]}
128+
{...rest}
129+
accessibilityRole='adjustable'
130+
accessibilityState={{ disabled }}
131+
accessibilityValue={{
132+
min,
133+
max,
134+
now: value,
135+
}}
136+
>
127137
<View
128138
style={[
129139
styles.inner,

src/SwitchBase/SwitchBase.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ export const SwitchBase = ({
4747
const theme = useContext(ThemeContext);
4848
const [isPressed, setIsPressed] = React.useState(false);
4949
const isRadio = component === 'radio';
50-
const switchSize = component === 'checkbox' ? checkboxSize : radioSize;
50+
const switchSize = !isRadio ? checkboxSize : radioSize;
5151
const boxSize = variant === 'flat' ? switchSize - 4 : switchSize;
5252
const borderRadius = isRadio ? boxSize / 2 : 0;
5353

54+
const checked = status === 'checked';
55+
5456
const renderCheckmark = () => {
55-
if (status === 'checked') {
56-
return component === 'checkbox' ? (
57-
<CheckmarkIcon disabled={disabled} />
58-
) : (
57+
if (checked) {
58+
return isRadio ? (
5959
<View
6060
style={{
6161
borderRadius: 6,
@@ -66,6 +66,8 @@ export const SwitchBase = ({
6666
: theme.checkmark,
6767
}}
6868
/>
69+
) : (
70+
<CheckmarkIcon disabled={disabled} />
6971
);
7072
}
7173
if (status === 'indeterminate') {
@@ -97,6 +99,13 @@ export const SwitchBase = ({
9799
return disabled ? theme.material : theme.canvas;
98100
};
99101

102+
const getAccessibilityComponentType = () => {
103+
if (isRadio) {
104+
return checked ? 'radiobutton_checked' : 'radiobutton_unchecked';
105+
}
106+
return 'button';
107+
};
108+
100109
return (
101110
<TouchableHighlight
102111
style={[styles.wrapper]}
@@ -107,13 +116,14 @@ export const SwitchBase = ({
107116
onShowUnderlay={() => setIsPressed(true)}
108117
// TODO: check if those accessibility properties are correct
109118
accessibilityTraits={disabled ? ['button', 'disabled'] : 'button'}
110-
accessibilityComponentType='button'
119+
accessibilityComponentType={getAccessibilityComponentType()}
111120
accessibilityRole={component}
112-
accessibilityState={{ disabled, checked: status === 'checked' }}
121+
accessibilityState={{ disabled, checked }}
122+
accessibilityLiveRegion='polite'
113123
underlayColor='none'
114124
{...rest}
115125
>
116-
<View style={[styles.content, style]} pointerEvents='none'>
126+
<View style={[styles.content, style]}>
117127
<View
118128
style={[
119129
styles.switchSymbol,

0 commit comments

Comments
 (0)