Skip to content

Commit a727ad0

Browse files
committed
Add visually hidden info ('opens in a new tab') to external links for screen readers
1 parent f2e8814 commit a727ad0

File tree

5 files changed

+30
-10
lines changed

5 files changed

+30
-10
lines changed

public/locales/en/translation.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
"code": "Code",
8080
"organisationCode": "Organisation code",
8181
"startDate": "Start date",
82-
"endDate": "End date"
82+
"endDate": "End date",
83+
"opensInNewTab": ", opens in a new tab"
8384
},
8485
"validationErrors": {
8586
"required": "This field is required",

public/locales/fi/translation.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
"code": "Koodi",
8080
"organisationCode": "Organisaatiokoodi",
8181
"startDate": "Aloituspvm",
82-
"endDate": "Lopetuspvm"
82+
"endDate": "Lopetuspvm",
83+
"opensInNewTab": ", avautuu uudelle välilehdelle"
8384
},
8485
"validationErrors": {
8586
"required": "Tämä kenttä vaaditaan",

public/locales/sv/translation.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@
7474
"descending": "fallande",
7575
"notEditable": "Inställningen kan inte ändras, då den har offentligjorts på en högre nivå.",
7676
"feedbacksGivenRatio": "Givna återkopplingar / Antal anmälda studenter",
77-
"additional": "Ytterligare"
77+
"additional": "Ytterligare",
78+
"opensInNewTab": ", öppnas i en ny flik"
7879
},
7980
"validationErrors": {
8081
"required": "Fältet krävs",
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React from 'react'
2+
import { useTranslation } from 'react-i18next'
23
import { Link } from '@mui/material'
34
import ExternalLinkIcon from '@mui/icons-material/OpenInNew'
5+
import { visuallyHidden } from '@mui/utils'
46

57
const styles = {
68
icon: {
@@ -9,11 +11,16 @@ const styles = {
911
},
1012
}
1113

12-
const ExternalLink = ({ children, ...props }) => (
13-
<Link target="_blank" rel="noopener" {...props} underline="always">
14-
{children}
15-
<ExternalLinkIcon sx={styles.icon} />
16-
</Link>
17-
)
14+
const ExternalLink = ({ children, ...props }) => {
15+
const { t } = useTranslation()
16+
17+
return (
18+
<Link target="_blank" rel="noopener" {...props} underline="always">
19+
{children}
20+
<ExternalLinkIcon sx={styles.icon} aria-hidden="true" />
21+
<span style={visuallyHidden}>{t('common:opensInNewTab')}</span>
22+
</Link>
23+
)
24+
}
1825

1926
export default ExternalLink

src/client/components/common/LinkButton.jsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
import React from 'react'
2+
import { useTranslation } from 'react-i18next'
23
import { Link } from 'react-router-dom'
34
import { Button, Link as MuiLink } from '@mui/material'
45
import { OpenInNew } from '@mui/icons-material'
6+
import { visuallyHidden } from '@mui/utils'
57

68
const LinkButton = ({ title, to, external = false, ...rest }) => {
9+
const { t } = useTranslation()
710
const buttonProps = {
811
...(external
9-
? { component: MuiLink, href: to, rel: 'noopener noreferrer', target: '_blank', endIcon: <OpenInNew /> }
12+
? {
13+
component: MuiLink,
14+
href: to,
15+
rel: 'noopener noreferrer',
16+
target: '_blank',
17+
endIcon: <OpenInNew aria-hidden="true" />,
18+
}
1019
: { component: Link, to }),
1120
}
1221

@@ -18,6 +27,7 @@ const LinkButton = ({ title, to, external = false, ...rest }) => {
1827
sx={{ textDecoration: 'underline', '&:hover': { textDecoration: 'underline' } }}
1928
>
2029
{title}
30+
{external && <span style={visuallyHidden}>{t('common:opensInNewTab')}</span>}
2131
</Button>
2232
)
2333
}

0 commit comments

Comments
 (0)