diff --git a/.changeset/early-crabs-help.md b/.changeset/early-crabs-help.md new file mode 100644 index 0000000000..a1464e0338 --- /dev/null +++ b/.changeset/early-crabs-help.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Announce external links to screen readers diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index a1af06ae3b..d1b9e2b7db 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -18,12 +18,28 @@ import { useAnalytics } from '@backstage/core-plugin-api'; import MaterialLink, { LinkProps as MaterialLinkProps, } from '@material-ui/core/Link'; +import { makeStyles } from '@material-ui/core/styles'; import React, { ElementType } from 'react'; import { Link as RouterLink, LinkProps as RouterLinkProps, } from 'react-router-dom'; +const useStyles = makeStyles( + { + visuallyHidden: { + clip: 'rect(0 0 0 0)', + clipPath: 'inset(50%)', + overflow: 'hidden', + position: 'absolute', + whiteSpace: 'nowrap', + height: 1, + width: 1, + }, + }, + { name: 'Link' }, +); + export const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri); export type LinkProps = MaterialLinkProps & @@ -62,6 +78,7 @@ const getNodeText = (node: React.ReactNode): string => { */ export const Link = React.forwardRef( ({ onClick, noTrack, ...props }, ref) => { + const classes = useStyles(); const analytics = useAnalytics(); const to = String(props.to); const linkText = getNodeText(props.children) || to; @@ -83,7 +100,10 @@ export const Link = React.forwardRef( onClick={handleClick} {...(newWindow ? { target: '_blank', rel: 'noopener' } : {})} {...props} - /> + > + {props.children} + , Opens in a new window + ) : ( // Interact with React Router for internal links { to="https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository" > Git releases + + , Opens in a new window + .