Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

now EuiBadge render anchor tags too #3009

Merged
merged 11 commits into from
Mar 16, 2020
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- `EuiBadge` allows for `href` ([#3009](https://github.com/elastic/eui/pull/3009))
- Exported `dateFormatAliases` as a part of the public API ([#3043](https://github.com/elastic/eui/pull/3043))
- Exported `EuiTextProps` type definition ([#3039](https://github.com/elastic/eui/pull/3039))
- Removed `role` attribute from `EuiImage`([#3036](https://github.com/elastic/eui/pull/3036))
Expand Down
10 changes: 5 additions & 5 deletions src/components/badge/__snapshots__/badge.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@ exports[`EuiBadge is rendered with iconOnClick and onClick provided 1`] = `

exports[`EuiBadge is rendered with iconOnClick provided 1`] = `
<span
aria-label="aria-label"
class="euiBadge euiBadge--iconLeft testClass1 testClass2"
data-test-subj="test subject string"
style="background-color:#d3dae6;color:#000"
>
<span
class="euiBadge__content"
>
<span
class="euiBadge__text"
<button
aria-label="aria-label"
class="euiBadge__childButton"
data-test-subj="test subject string"
>
Content
</span>
</button>
</span>
</span>
`;
Expand Down
48 changes: 36 additions & 12 deletions src/components/badge/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {
HTMLAttributes,
MouseEventHandler,
ReactNode,
Ref,
} from 'react';
import classNames from 'classnames';
import { CommonProps, ExclusiveUnion, keysOf, PropsOf } from '../common';
Expand All @@ -26,6 +27,11 @@ type WithButtonProps = {
onClickAriaLabel: AriaAttributes['aria-label'];
} & Omit<HTMLAttributes<HTMLButtonElement>, 'onClick' | 'color'>;

interface WithAnchorProps {
href: string;
target?: string;
}

type WithSpanProps = Omit<HTMLAttributes<HTMLSpanElement>, 'onClick' | 'color'>;

interface WithIconOnClick {
Expand Down Expand Up @@ -66,7 +72,10 @@ export type EuiBadgeProps = {
closeButtonProps?: Partial<PropsOf<EuiIcon>>;
} & CommonProps &
ExclusiveUnion<WithIconOnClick, {}> &
ExclusiveUnion<WithSpanProps, WithButtonProps>;
ExclusiveUnion<
ExclusiveUnion<WithButtonProps, WithAnchorProps>,
WithSpanProps
>;

// TODO - replace with variables once https://github.com/elastic/eui/issues/2731 is closed
const colorInk = '#000';
Expand Down Expand Up @@ -108,6 +117,8 @@ export const EuiBadge: FunctionComponent<EuiBadgeProps> = ({
onClickAriaLabel,
iconOnClickAriaLabel,
closeButtonProps,
href,
target,
...rest
}) => {
checkValidColor(color);
Expand Down Expand Up @@ -172,6 +183,19 @@ export const EuiBadge: FunctionComponent<EuiBadgeProps> = ({
'euiBadge__icon',
closeButtonProps && closeButtonProps.className
);
const Element = href && !isDisabled ? 'a' : 'button';
const relObj: {
href?: string;
target?: string;
onClick?: MouseEventHandler<HTMLButtonElement>;
} = {};

if (href && !isDisabled) {
relObj.href = href;
relObj.target = target;
} else if (onClick) {
relObj.onClick = onClick;
}

let optionalIcon: ReactNode = null;
if (iconType) {
Expand Down Expand Up @@ -209,46 +233,46 @@ export const EuiBadge: FunctionComponent<EuiBadgeProps> = ({
);
}

if (onClick && iconOnClick) {
if (iconOnClick) {
return (
<span className={classes} style={optionalCustomStyles}>
<span className="euiBadge__content">
<EuiInnerText>
{(ref, innerText) => (
<button
<Element
className="euiBadge__childButton"
disabled={isDisabled}
aria-label={onClickAriaLabel}
onClick={onClick}
ref={ref}
title={innerText}
{...rest}>
{...relObj as HTMLAttributes<HTMLElement>}
{...rest as HTMLAttributes<HTMLElement>}>
{children}
</button>
</Element>
)}
</EuiInnerText>
{optionalIcon}
</span>
</span>
);
} else if (onClick) {
} else if (onClick || href) {
return (
<EuiInnerText>
{(ref, innerText) => (
<button
<Element
disabled={isDisabled}
aria-label={onClickAriaLabel}
className={classes}
onClick={onClick}
style={optionalCustomStyles}
ref={ref}
ref={ref as Ref<HTMLButtonElement & HTMLAnchorElement>}
title={innerText}
{...rest}>
{...relObj as HTMLAttributes<HTMLElement>}
{...rest as HTMLAttributes<HTMLElement>}>
<span className="euiBadge__content">
<span className="euiBadge__text">{children}</span>
{optionalIcon}
</span>
</button>
</Element>
)}
</EuiInnerText>
);
Expand Down