<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #35328 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved link hover and `:focus-visible` underline/outline behavior for more consistent accessibility across tables, buttons, and modals. * Fixed script name hover underline clipping in the run script modal. * **Style** * Refreshed `CustomLink` styling with an emphasized variant and improved underline behavior, plus updated related link/table/button styling for a unified look. * Updated “Connect Fleet” info-banner messaging and CTAs for calendar and conditional access automations; refreshed “No scripts available” empty state. * **Tests** * Updated modal tests to match revised link text and accessible names. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
113 lines
2.7 KiB
TypeScript
113 lines
2.7 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;
|
|
/** Emphasizes the link appearance by changing the color to an accent color */
|
|
emphasized?: 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,
|
|
emphasized = false,
|
|
disableKeyboardNavigation = false,
|
|
variant = "default",
|
|
}: ICustomLinkProps): JSX.Element => {
|
|
const getIconColor = (): Colors => {
|
|
switch (variant) {
|
|
case "tooltip-link":
|
|
return "core-fleet-white";
|
|
case "flash-message-link":
|
|
return "core-fleet-black";
|
|
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,
|
|
[`${baseClass}--emphasized`]: emphasized,
|
|
});
|
|
|
|
// 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`}>
|
|
<span className={`${baseClass}__last-word`}>{lastWord}</span>
|
|
{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;
|