Skip to content

Commit

Permalink
feat(ExternalLink): add screen-reader text when link opens in new tab
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-gendron committed Nov 16, 2021
1 parent f7b7d61 commit f7b108d
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { shallow } from 'enzyme';
import React from 'react';
import { getByTestId } from '../../test-utils/enzyme-selectors';
import { mountWithProviders, renderWithProviders } from '../../test-utils/renderer';
import { ExternalLink } from './external-link';

Expand All @@ -13,6 +15,12 @@ describe('External Link', () => {
expect(callback).toHaveBeenCalledTimes(1);
});

test('displays screen-reader-only text when link opens in a new tab (target="_blank")', () => {
const wrapper = shallow(<ExternalLink href="#" label="External Link" target="_blank" />);

expect(getByTestId(wrapper, 'screen-reader-text').exists()).toBe(true);
});

test('matches snapshot', () => {
const tree = renderWithProviders(
<ExternalLink href="https://www.google.ca/" label="External Link" />,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ exports[`External Link matches snapshot (disabled) 1`] = `
box-shadow: 0 0 0 1px #006296,0 0 0 3px #84C6EA;
}
.c4 {
border: 0;
-webkit-clip: rect(0,0,0,0);
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c3 {
-webkit-align-self: center;
-ms-flex-item-align: center;
Expand Down Expand Up @@ -91,6 +103,12 @@ exports[`External Link matches snapshot (disabled) 1`] = `
role="img"
width="16"
/>
<span
class="c4"
data-testid="screen-reader-text"
>
(opens in a new tab)
</span>
</a>
`;

Expand Down Expand Up @@ -130,6 +148,18 @@ exports[`External Link matches snapshot (label and icon) 1`] = `
box-shadow: 0 0 0 1px #006296,0 0 0 3px #84C6EA;
}
.c5 {
border: 0;
-webkit-clip: rect(0,0,0,0);
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c2 {
margin-right: var(--spacing-1x);
}
Expand Down Expand Up @@ -201,6 +231,12 @@ exports[`External Link matches snapshot (label and icon) 1`] = `
role="img"
width="16"
/>
<span
class="c5"
data-testid="screen-reader-text"
>
(opens in a new tab)
</span>
</a>
`;

Expand Down Expand Up @@ -240,6 +276,18 @@ exports[`External Link matches snapshot (only icon) 1`] = `
box-shadow: 0 0 0 1px #006296,0 0 0 3px #84C6EA;
}
.c5 {
border: 0;
-webkit-clip: rect(0,0,0,0);
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c2 {
margin-right: var(--spacing-1x);
}
Expand Down Expand Up @@ -309,6 +357,12 @@ exports[`External Link matches snapshot (only icon) 1`] = `
role="img"
width="16"
/>
<span
class="c5"
data-testid="screen-reader-text"
>
(opens in a new tab)
</span>
</a>
`;

Expand Down Expand Up @@ -348,6 +402,18 @@ exports[`External Link matches snapshot (without href) 1`] = `
box-shadow: 0 0 0 1px #006296,0 0 0 3px #84C6EA;
}
.c5 {
border: 0;
-webkit-clip: rect(0,0,0,0);
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c2 {
margin-right: var(--spacing-1x);
}
Expand Down Expand Up @@ -419,6 +485,12 @@ exports[`External Link matches snapshot (without href) 1`] = `
role="img"
width="16"
/>
<span
class="c5"
data-testid="screen-reader-text"
>
(opens in a new tab)
</span>
</a>
`;

Expand Down Expand Up @@ -458,6 +530,18 @@ exports[`External Link matches snapshot 1`] = `
box-shadow: 0 0 0 1px #006296,0 0 0 3px #84C6EA;
}
.c4 {
border: 0;
-webkit-clip: rect(0,0,0,0);
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c3 {
-webkit-align-self: center;
-ms-flex-item-align: center;
Expand Down Expand Up @@ -517,5 +601,11 @@ exports[`External Link matches snapshot 1`] = `
role="img"
width="16"
/>
<span
class="c4"
data-testid="screen-reader-text"
>
(opens in a new tab)
</span>
</a>
`;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { MouseEvent, ReactElement, useCallback } from 'react';
import styled from 'styled-components';
import { useDeviceContext } from '../device-context-provider/device-context-provider';

import { Icon, IconName } from '../icon/icon';
import { StyledLink } from '../route-link/styles/styled-link';
import { ScreenReaderOnlyText } from '../screen-reader-only-text/ScreenReaderOnlyText';
import { useTranslation } from '../../i18n/use-translation';

const LeftIcon = styled(Icon)`
margin-right: var(--spacing-1x);
Expand Down Expand Up @@ -55,6 +56,8 @@ export function ExternalLink({
className, disabled, href = '', iconName, label, onClick, target = '_blank',
}: ExternalLinkProps): ReactElement {
const { isMobile } = useDeviceContext();
const { t } = useTranslation('common');
const opensInNewTab = target === '_blank';
const handleClick: (event: MouseEvent<HTMLAnchorElement>) => void = useCallback((event) => {
if (!href) {
event.preventDefault();
Expand All @@ -77,6 +80,9 @@ export function ExternalLink({
{iconName && <LeftIcon aria-hidden="true" name={iconName} size="16" />}
<StyledLabel>{label}</StyledLabel>
<ExternalIcon aria-label="open in new window" name="externalLink" role="img" size="16" />
{opensInNewTab && (
<ScreenReaderOnlyText data-testid="screen-reader-text" label={t('opensInNewTabScreenReader')} />
)}
</Link>
);
}

0 comments on commit f7b108d

Please sign in to comment.