Skip to content

Commit

Permalink
Merge pull request #57 from CovidShield/external-link-accessibility
Browse files Browse the repository at this point in the history
Add accessibility props for external buttons
  • Loading branch information
jordanAtShopify authored Jun 3, 2020
2 parents 2d054ec + 6b59e65 commit 207bb9f
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/assets/icon-external-arrow-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 39 additions & 6 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import React from 'react';
import {useTheme} from '@shopify/restyle';
import {Platform, StyleSheet, Text, TextStyle, TouchableOpacity, ViewStyle, ActivityIndicator} from 'react-native';
import {Theme} from 'shared/theme';
import {
Platform,
StyleSheet,
Text,
TextStyle,
TouchableOpacity,
ViewStyle,
ActivityIndicator,
AccessibilityRole,
} from 'react-native';
import {Theme, palette} from 'shared/theme';
import {useI18n} from '@shopify/react-i18n';

import {Box} from './Box';
import {Ripple} from './Ripple';
import {Icon} from './Icon';

export interface ButtonProps {
text?: string;
Expand All @@ -13,9 +24,19 @@ export interface ButtonProps {
color?: keyof Theme['colors'];
disabled?: boolean;
loading?: boolean;
externalLink?: boolean;
}

export const Button = ({text, onPress, variant, color: buttonColorName, disabled, loading}: ButtonProps) => {
export const Button = ({
text,
onPress,
variant,
color: buttonColorName,
disabled,
loading,
externalLink,
}: ButtonProps) => {
const [i18n] = useI18n();
const theme = useTheme<Theme>();
const variantProps = theme.buttonVariants[variant];
const disabledProps = disabled ? variantProps.disabled || {} : {};
Expand All @@ -26,6 +47,14 @@ export const Button = ({text, onPress, variant, color: buttonColorName, disabled
const buttonColor = buttonColorName && theme.colors[buttonColorName];

const onPressHandler = loading ? () => {} : onPress;
const externalLinkProps = externalLink
? {
accessibilityLabel: text,
accessibilityHint: i18n.translate('Home.ExternalLinkHint'),
accessibilityRole: 'link' as AccessibilityRole,
}
: {};
const externalArrowIcon = textColor === palette.white ? 'icon-external-arrow-light' : 'icon-external-arrow';

const content = (
<Box
Expand All @@ -34,24 +63,28 @@ export const Button = ({text, onPress, variant, color: buttonColorName, disabled
justifyContent="center"
style={{backgroundColor: color, minHeight: height, borderWidth, borderColor: buttonColor}}
paddingHorizontal="m"
flexDirection="row"
>
{loading ? (
<ActivityIndicator color={textColor} size="large" />
) : (
<Text style={{color: textColor || buttonColor, fontWeight, fontFamily, fontSize}}>{text}</Text>
<>
<Text style={{color: textColor || buttonColor, fontWeight, fontFamily, fontSize}}>{text}</Text>
{externalLink && <Icon name={externalArrowIcon} />}
</>
)}
</Box>
);

if (Platform.OS === 'android') {
return (
<Ripple rippleContainerBorderRadius={4} rippleDuration={500} onPress={onPressHandler}>
<Ripple rippleContainerBorderRadius={4} rippleDuration={500} onPress={onPressHandler} {...externalLinkProps}>
{content}
</Ripple>
);
}
return (
<TouchableOpacity onPress={onPressHandler} style={styles.stretch} disabled={disabled}>
<TouchableOpacity onPress={onPressHandler} style={styles.stretch} disabled={disabled} {...externalLinkProps}>
{content}
</TouchableOpacity>
);
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import IconChevron from 'assets/icon-chevron.svg';
import IconClose from 'assets/icon-close.svg';
import IconEnterCode from 'assets/icon-enter-code.svg';
import IconExternalArrow from 'assets/icon-external-arrow.svg';
import IconExternalArrowLight from 'assets/icon-external-arrow-light.svg';
import IconImportant from 'assets/icon-important.svg';
import IconMessages from 'assets/icon-messages.svg';
import IconNotify from 'assets/icon-notify.svg';
Expand Down Expand Up @@ -38,6 +39,7 @@ const ICONS = {
'icon-enter-code': IconEnterCode,
'icon-ellipsis': Ellipsis,
'icon-external-arrow': IconExternalArrow,
'icon-external-arrow-light': IconExternalArrowLight,
'icon-important': IconImportant,
'icon-messages': IconMessages,
'icon-notify': IconNotify,
Expand Down
1 change: 1 addition & 0 deletions src/locale/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"NoConnectivity": "No internet connection",
"NoConnectivityDetailed": "COVID Shield needs internet access to continue checking for potential exposure.",
"AppName": "COVID Shield",
"ExternalLinkHint": "Opens in a new window",
"LastCheckedMinutes": {
"One": "Last checked {number} minute ago",
"Other": "Last checked {number} minutes ago"
Expand Down
1 change: 1 addition & 0 deletions src/locale/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"NoConnectivity": "Aucune connexion Internet",
"NoConnectivityDetailed": "COVID Shield a besoin d'un accès Internet pour continuer de vérifier les expositions potentielles à la COVID-19.",
"AppName": "COVID Shield",
"ExternalLinkHint": "Ouvre dans une nouvelle fenêtre",
"LastCheckedMinutes": {
"One": "Dernière vérification il y a {number} minute",
"Other": "Dernière vérification il y a {number} minutes"
Expand Down
2 changes: 1 addition & 1 deletion src/locale/translations/index.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/screens/home/views/DiagnosedShareView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const DiagnosedShareView = () => {
text={i18n.translate('Home.SignalDataSharedCTA')}
variant="bigHollow"
color="bodyText"
externalLink
onPress={toSymptomTracker}
/>
</Box>
Expand Down
2 changes: 1 addition & 1 deletion src/screens/home/views/DiagnosedView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const DiagnosedView = () => {
{i18n.translate(pluralizeKey('Home.SignalDataSharedDetailed', daysDiff), {number: daysDiff})}
</Text>
<Box alignSelf="stretch">
<Button text={i18n.translate('Home.SignalDataSharedCTA')} variant="bigFlat" onPress={onAction} />
<Button text={i18n.translate('Home.SignalDataSharedCTA')} variant="bigFlat" externalLink onPress={onAction} />
</Box>
</BaseHomeView>
);
Expand Down
2 changes: 1 addition & 1 deletion src/screens/home/views/ExposureView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const ExposureView = () => {
</Text>
<LastCheckedDisplay />
<Box alignSelf="stretch" marginTop="l">
<Button text={i18n.translate('Home.SeeGuidance')} variant="bigFlat" onPress={onAction} />
<Button text={i18n.translate('Home.SeeGuidance')} variant="bigFlat" externalLink onPress={onAction} />
</Box>
</BaseHomeView>
);
Expand Down
17 changes: 12 additions & 5 deletions src/screens/home/views/InfoShareView.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React, {useCallback} from 'react';
import {TouchableOpacity, Linking} from 'react-native';
import {TouchableOpacity, TouchableOpacityProps, Linking} from 'react-native';
import {Box, Text, Icon, IconProps} from 'components';
import {useNavigation} from '@react-navigation/native';
import {useI18n} from '@shopify/react-i18n';

interface InfoShareItemProps {
interface InfoShareItemProps extends TouchableOpacityProps {
onPress: () => void;
text: string;
icon: IconProps['name'];
}
const InfoShareItem = ({onPress, text, icon}: InfoShareItemProps) => (
const InfoShareItem = ({onPress, text, icon, ...touchableProps}: InfoShareItemProps) => (
<>
<TouchableOpacity onPress={onPress}>
<TouchableOpacity onPress={onPress} {...touchableProps}>
<Box paddingVertical="s" flexDirection="row" alignContent="center" justifyContent="space-between">
<Text variant="bodyText" marginVertical="s" color="overlayBodyText">
{text}
Expand Down Expand Up @@ -39,7 +39,14 @@ export const InfoShareView = () => {
return (
<>
<Box paddingHorizontal="m" borderRadius={10} backgroundColor="infoBlockNeutralBackground">
<InfoShareItem onPress={onSymptomps} text={i18n.translate('Info.CheckSymptoms')} icon="icon-external-arrow" />
<InfoShareItem
onPress={onSymptomps}
text={i18n.translate('Info.CheckSymptoms')}
icon="icon-external-arrow"
accessibilityLabel={i18n.translate('Info.CheckSymptoms')}
accessibilityRole="link"
accessibilityHint={i18n.translate('Home.ExternalLinkHint')}
/>
<InfoShareItem onPress={onShare} text={i18n.translate('Info.TellAFriend')} icon="icon-share" />
<InfoShareItem onPress={onLearnMore} text={i18n.translate('Info.LearnMore')} icon="icon-chevron" />
</Box>
Expand Down

0 comments on commit 207bb9f

Please sign in to comment.