mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
107 lines
2.5 KiB
TypeScript
107 lines
2.5 KiB
TypeScript
import React from "react";
|
|
|
|
import Icon from "components/Icon";
|
|
import classnames from "classnames";
|
|
import { Colors } from "styles/var/colors";
|
|
|
|
interface ICustomLinkProps {
|
|
url: string;
|
|
text: string;
|
|
className?: string;
|
|
/** open the link in a new tab
|
|
* @default false
|
|
*/
|
|
newTab?: boolean;
|
|
/** Icon wraps on new line with last word */
|
|
multiline?: boolean;
|
|
/** Restricts access via keyboard when CustomLink is part of disabled UI */
|
|
disableKeyboardNavigation?: boolean;
|
|
/**
|
|
* Changes the appearance of the link.
|
|
*
|
|
* @default "default"
|
|
*/
|
|
variant?: "tooltip-link" | "banner-link" | "flash-message-link" | "default";
|
|
}
|
|
|
|
const baseClass = "custom-link";
|
|
|
|
const CustomLink = ({
|
|
url,
|
|
text,
|
|
className,
|
|
newTab = false,
|
|
multiline = false,
|
|
disableKeyboardNavigation = false,
|
|
variant = "default",
|
|
}: ICustomLinkProps): JSX.Element => {
|
|
const getIconColor = (): Colors => {
|
|
switch (variant) {
|
|
case "tooltip-link":
|
|
case "flash-message-link":
|
|
return "core-fleet-white";
|
|
case "banner-link":
|
|
return "core-fleet-black";
|
|
default:
|
|
return "ui-fleet-black-75";
|
|
}
|
|
};
|
|
|
|
const customLinkClass = classnames(baseClass, className, {
|
|
[`${baseClass}--${variant}`]: variant !== "default",
|
|
[`${baseClass}--multiline`]: multiline,
|
|
});
|
|
|
|
// Needed to not trigger clickable parent elements
|
|
// e.g. cell/row handlers with a tooltip that has a custom link inside
|
|
const handleClick = (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
};
|
|
|
|
const target = newTab ? "_blank" : "";
|
|
|
|
const multilineText = text.substring(0, text.lastIndexOf(" ") + 1);
|
|
const lastWord = text.substring(text.lastIndexOf(" ") + 1, text.length);
|
|
|
|
const content = multiline ? (
|
|
<>
|
|
{multilineText}
|
|
<span className={`${baseClass}__no-wrap`}>
|
|
{lastWord}
|
|
{newTab && (
|
|
<Icon
|
|
name="external-link"
|
|
className={`${baseClass}__external-icon`}
|
|
color={getIconColor()}
|
|
/>
|
|
)}
|
|
</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
{text}
|
|
{newTab && (
|
|
<Icon
|
|
name="external-link"
|
|
className={`${baseClass}__external-icon`}
|
|
color={getIconColor()}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
|
|
return (
|
|
<a
|
|
href={url}
|
|
target={target}
|
|
rel="noopener noreferrer"
|
|
className={customLinkClass}
|
|
tabIndex={disableKeyboardNavigation ? -1 : 0}
|
|
onClick={handleClick}
|
|
>
|
|
{content}
|
|
</a>
|
|
);
|
|
};
|
|
|
|
export default CustomLink;
|