Skip to content

Commit

Permalink
Added external prop to EuiLink (#2442)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreadelrio authored Oct 17, 2019
1 parent 35e5264 commit 5437331
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Made EuiIcon a PureComponent, to speed up React re-render performance ([#2448](https://github.com/elastic/eui/pull/2448))
- Added ability for `EuiColorStops` to accept user-defined range bounds ([#2396](https://github.com/elastic/eui/pull/2396))
- Added `external` prop to `EuiLink` ([#2442](https://github.com/elastic/eui/pull/2442))

## [`14.6.0`](https://github.com/elastic/eui/tree/v14.6.0)

Expand Down
39 changes: 21 additions & 18 deletions src-docs/src/views/link/link.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
import React from 'react';

import { EuiLink, EuiText } from '../../../../src/components';
import { EuiCode, EuiLink, EuiText } from '../../../../src/components';

export default () => (
<EuiText>
<p>
Open the{' '}
{
<EuiLink href="http://www.elastic.co" target="_blank">
Elastic website
</EuiLink>
}{' '}
<EuiLink href="http://www.elastic.co" target="_blank">
Elastic website
</EuiLink>{' '}
in a new tab.
</p>
<p>
This{' '}
<EuiLink href="http://www.elastic.co" external target="_blank">
link
</EuiLink>{' '}
has the <EuiCode>external</EuiCode> prop set to true.
</p>
<p>
This link is actually a{' '}
{<EuiLink onClick={() => window.alert('Button clicked')}>button</EuiLink>}{' '}
<EuiLink onClick={() => window.alert('Button clicked')}>button</EuiLink>{' '}
with an onClick handler.
</p>
<p>
Here is an example of a{' '}
{
<EuiLink
href="https://github.com/elastic/eui"
onClick={e => {
if (!window.confirm('Are you sure you want to see the eui repo?')) {
e.preventDefault();
}
}}>
link
</EuiLink>
}{' '}
<EuiLink
href="https://github.com/elastic/eui"
onClick={e => {
if (!window.confirm('Are you sure you want to see the eui repo?')) {
e.preventDefault();
}
}}>
link
</EuiLink>{' '}
with both an href and an onClick handler.
</p>
<p>Links can be colored as well.</p>
Expand Down
18 changes: 18 additions & 0 deletions src/components/link/__snapshots__/link.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ exports[`EuiLink if href is not specified, it renders a button of type=button 1`
/>
`;

exports[`EuiLink it is an external link 1`] = `
<a
class="euiLink euiLink--primary"
href="/baz/bing"
rel="noreferrer"
>
<svg
aria-label="External link"
class="euiIcon euiIcon--small euiIcon-isLoading euiLink__externalIcon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
/>
</a>
`;

exports[`EuiLink it passes the default props through 1`] = `
<button
aria-label="aria-label"
Expand Down
4 changes: 4 additions & 0 deletions src/components/link/_link.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.euiLink {
@include euiLink;

.euiLink__externalIcon {
margin-left: $euiSizeXS;
}
}

$textColors: (
Expand Down
5 changes: 5 additions & 0 deletions src/components/link/link.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ describe('EuiLink', () => {
expect(component).toMatchSnapshot();
});

test('it is an external link', () => {
const component = render(<EuiLink external href="/baz/bing" />);
expect(component).toMatchSnapshot();
});

test('supports href', () => {
const component = render(<EuiLink href="/baz/bing" />);
expect(component).toMatchSnapshot();
Expand Down
30 changes: 27 additions & 3 deletions src/components/link/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React, {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
MouseEventHandler,
forwardRef,
} from 'react';
import classNames from 'classnames';

import { EuiIcon } from '../icon';
import { EuiI18n } from '../i18n';
import { CommonProps, ExclusiveUnion, keysOf } from '../common';
import { getSecureRelForTarget } from '../../services';

Expand Down Expand Up @@ -46,6 +46,10 @@ export type EuiLinkButtonProps = CommonProps &
export interface LinkAnchorProps {
type?: EuiLinkType;
color?: EuiLinkColor;
/**
* Set to true to show an icon indicating that it is an external link.
*/
external?: boolean;
}

export type EuiLinkAnchorProps = CommonProps &
Expand All @@ -57,13 +61,17 @@ export type EuiLinkProps = ExclusiveUnion<
EuiLinkAnchorProps
>;

const EuiLink = forwardRef<HTMLAnchorElement | HTMLButtonElement, EuiLinkProps>(
const EuiLink = React.forwardRef<
HTMLAnchorElement | HTMLButtonElement,
EuiLinkProps
>(
(
{
children,
color = 'primary',
className,
href,
external,
target,
rel,
type = 'button',
Expand All @@ -78,6 +86,21 @@ const EuiLink = forwardRef<HTMLAnchorElement | HTMLButtonElement, EuiLinkProps>(
className
);

const externalLinkIcon = external ? (
<EuiI18n token="euiLink.external.ariaLabel" default="External link">
{(ariaLabel: string) => (
<EuiIcon
aria-label={ariaLabel}
size="s"
className="euiLink__externalIcon"
type="popout"
/>
)}
</EuiI18n>
) : (
undefined
);

if (href === undefined) {
const buttonProps = {
className: classes,
Expand Down Expand Up @@ -111,6 +134,7 @@ const EuiLink = forwardRef<HTMLAnchorElement | HTMLButtonElement, EuiLinkProps>(
ref={ref as React.Ref<HTMLAnchorElement>}
{...anchorProps as EuiLinkAnchorProps}>
{children}
{externalLinkIcon}
</a>
);
}
Expand Down

0 comments on commit 5437331

Please sign in to comment.