Skip to content

Commit

Permalink
Support the target prop on the Link anchor
Browse files Browse the repository at this point in the history
  • Loading branch information
kmjennison committed Mar 30, 2021
1 parent 15a9253 commit 026b7e3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
20 changes: 15 additions & 5 deletions src/components/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ const useStyles = makeStyles(() => ({
}))

const Link = (props) => {
const { children, className, to } = props
const { children, className, target, to } = props
const classes = useStyles()
const [destInternal, setDestInternal] = useState(true)

// Explicitly set target="_top" for external links, because our
// app may be served in an iframe.
// We won't always server-render the "target" prop correctly.
// If that causes problems, use the URL from the request when
// server-side rendering.
Expand All @@ -31,12 +33,18 @@ const Link = (props) => {
}
}, [to])

// Always use the anchor prop, if provided; otherwise, fall
// back to the default.
let anchorTarget
if (target) {
anchorTarget = target
} else {
anchorTarget = destInternal ? undefined : '_top'
}

return (
<NextJsLink href={to}>
<a
target={destInternal ? undefined : '_top'}
className={clsx(classes.anchor, className)}
>
<a target={anchorTarget} className={clsx(classes.anchor, className)}>
{children}
</a>
</NextJsLink>
Expand All @@ -52,10 +60,12 @@ Link.propTypes = {
]).isRequired,
className: PropTypes.string,
to: PropTypes.string.isRequired,
target: PropTypes.string,
}

Link.defaultProps = {
className: '',
target: undefined,
}

export default Link
24 changes: 23 additions & 1 deletion src/components/__tests__/Link.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const getMockProps = () => ({
children: 'hi',
className: 'some-class',
to: 'https://tab.gladly.io/newtab/blah/',
target: undefined,
})

beforeEach(() => {
Expand Down Expand Up @@ -61,7 +62,7 @@ describe('Link component', () => {
className: 'some-class-here',
}
const wrapper = shallow(<Link {...mockProps} />)
const anchor = wrapper.childAt(0)
const anchor = wrapper.find('a').first()
expect(anchor.prop('className')).toContain('some-class-here')
})

Expand Down Expand Up @@ -96,4 +97,25 @@ describe('Link component', () => {
mount(<Link {...mockProps} />)
expect(isURLForDifferentApp).toHaveBeenCalledWith(`/my-base-path/my/thing`)
})

it('assigns the "target" prop to the anchor if it is provided', () => {
const Link = require('src/components/Link').default
const mockProps = {
...getMockProps(),
target: '_blank',
}
const wrapper = shallow(<Link {...mockProps} />)
expect(wrapper.find('a').first().prop('target')).toEqual('_blank')
})

it('uses the "target" prop when provided, rather than target="_top", when it is an external link', () => {
const Link = require('src/components/Link').default
const mockProps = {
...getMockProps(),
url: 'https://blahblah.com',
target: '_blank',
}
const wrapper = shallow(<Link {...mockProps} />)
expect(wrapper.find('a').first().prop('target')).toEqual('_blank')
})
})

0 comments on commit 026b7e3

Please sign in to comment.