From ec094f74f94c92bf0ef891853a572694e308e841 Mon Sep 17 00:00:00 2001 From: Michael Garfinkle <103146151+mikegarfinkle@users.noreply.github.com> Date: Sun, 12 Feb 2023 10:46:29 -0800 Subject: [PATCH] fix: added close drawer accessibility tap area (#11184) **Motivation** Currently, a user can tap the `Overlay` next to an open drawer to close the drawer. This is useful in an Accessibility setting when swipe actions are not obvious to the user. Unfortunately, it is not obvious to someone with a visual deficit that this area can be tapped to close the drawer, as this overlay does not have an accessibilityLabel prop exposed. This PR exposes an `accessibilityLabel` prop on this overlay component and modifies existing accessibility props to allow for accessibility tap permissions on the overlay component. It then surfaces this prop at the `Drawer` level as `closeAccessibilityLabel`. **Test plan** Open up the example app with TalkBack (Android) or VoiceOver (iOS) enabled. Tap on the overlay next to the drawer and observe that it will now read out as "Close drawer". --- packages/drawer/src/types.tsx | 7 +++++++ packages/drawer/src/views/DrawerView.tsx | 2 ++ .../react-native-drawer-layout/src/types.tsx | 6 ++++++ .../src/views/legacy/Drawer.tsx | 3 ++- .../src/views/legacy/Overlay.tsx | 16 ++++++++++++++-- .../src/views/modern/Drawer.tsx | 3 ++- .../src/views/modern/Overlay.tsx | 16 ++++++++++++++-- 7 files changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/drawer/src/types.tsx b/packages/drawer/src/types.tsx index 679013fb92..6c69aaa196 100644 --- a/packages/drawer/src/types.tsx +++ b/packages/drawer/src/types.tsx @@ -171,6 +171,12 @@ export type DrawerNavigationOptions = HeaderOptions & { */ overlayColor?: string; + /** + * Accessibility label for the overlay. This is read by the screen reader when the user taps the overlay. + * Defaults to "Close drawer". + */ + overlayAccessibilityLabel?: string; + /** * Style object for the component wrapping the screen content. */ @@ -310,4 +316,5 @@ export type DrawerProps = { swipeEdgeWidth: number; swipeEnabled: boolean; swipeVelocityThreshold: number; + overlayAccessibilityLabel?: string; }; diff --git a/packages/drawer/src/views/DrawerView.tsx b/packages/drawer/src/views/DrawerView.tsx index 575c11c1de..4f6db272a8 100644 --- a/packages/drawer/src/views/DrawerView.tsx +++ b/packages/drawer/src/views/DrawerView.tsx @@ -65,6 +65,7 @@ function DrawerViewBase({ Platform.OS !== 'windows' && Platform.OS !== 'macos', swipeMinDistance, + overlayAccessibilityLabel, } = descriptors[focusedRouteKey].options; const [loaded, setLoaded] = React.useState([focusedRouteKey]); @@ -248,6 +249,7 @@ function DrawerViewBase({ statusBarAnimation={drawerStatusBarAnimation} keyboardDismissMode={keyboardDismissMode} drawerType={drawerType} + overlayAccessibilityLabel={overlayAccessibilityLabel} drawerPosition={drawerPosition} drawerStyle={[ { backgroundColor: colors.card }, diff --git a/packages/react-native-drawer-layout/src/types.tsx b/packages/react-native-drawer-layout/src/types.tsx index 8313623626..5df7c1fa9f 100644 --- a/packages/react-native-drawer-layout/src/types.tsx +++ b/packages/react-native-drawer-layout/src/types.tsx @@ -58,6 +58,12 @@ export type DrawerProps = { */ overlayStyle?: StyleProp; + /** + * Accessibility label for the overlay. This is read by the screen reader when the user taps the overlay. + * Defaults to "Close drawer". + */ + overlayAccessibilityLabel?: string; + /** * Whether the keyboard should be dismissed when the swipe gesture begins. * Defaults to `'on-drag'`. Set to `'none'` to disable keyboard handling. diff --git a/packages/react-native-drawer-layout/src/views/legacy/Drawer.tsx b/packages/react-native-drawer-layout/src/views/legacy/Drawer.tsx index 28e1684c0b..04d0a2bdcd 100644 --- a/packages/react-native-drawer-layout/src/views/legacy/Drawer.tsx +++ b/packages/react-native-drawer-layout/src/views/legacy/Drawer.tsx @@ -502,6 +502,7 @@ export default class Drawer extends React.Component { renderDrawerContent, children, gestureHandlerProps, + overlayAccessibilityLabel, } = this.props; const isOpen = drawerType === 'permanent' ? true : open; @@ -592,6 +593,7 @@ export default class Drawer extends React.Component { this.toggleDrawer(false)} + accessibilityLabel={overlayAccessibilityLabel} style={overlayStyle as any} accessibilityElementsHidden={!isOpen} importantForAccessibility={ @@ -619,7 +621,6 @@ export default class Drawer extends React.Component { /> )} & { progress: Animated.Node; onPress: () => void; + accessibilityLabel?: string; }; const Overlay = React.forwardRef(function Overlay( - { progress, onPress, style, ...props }: Props, + { + progress, + onPress, + style, + accessibilityLabel = 'Close drawer', + ...props + }: Props, ref: React.Ref ) { const animatedStyle = { @@ -48,7 +55,12 @@ const Overlay = React.forwardRef(function Overlay( ref={ref} style={[styles.overlay, overlayStyle, animatedStyle, style]} > - + ); }); diff --git a/packages/react-native-drawer-layout/src/views/modern/Drawer.tsx b/packages/react-native-drawer-layout/src/views/modern/Drawer.tsx index 5527e75107..77e8e84e5a 100644 --- a/packages/react-native-drawer-layout/src/views/modern/Drawer.tsx +++ b/packages/react-native-drawer-layout/src/views/modern/Drawer.tsx @@ -55,6 +55,7 @@ export default function Drawer({ onOpen, open, overlayStyle, + overlayAccessibilityLabel, statusBarAnimation, swipeEnabled, swipeEdgeWidth, @@ -366,11 +367,11 @@ export default function Drawer({ progress={progress} onPress={() => toggleDrawer(false)} style={overlayStyle} + accessibilityLabel={overlayAccessibilityLabel} /> ) : null} & { progress: Animated.SharedValue; onPress: () => void; + accessibilityLabel?: string; }; const Overlay = React.forwardRef(function Overlay( - { progress, onPress, style, ...props }: Props, + { + progress, + onPress, + style, + accessibilityLabel = 'Close drawer', + ...props + }: Props, ref: React.Ref ) { const animatedStyle = useAnimatedStyle(() => { @@ -42,7 +49,12 @@ const Overlay = React.forwardRef(function Overlay( style={[styles.overlay, overlayStyle, animatedStyle, style]} animatedProps={animatedProps} > - + ); });