-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathTextLink.tsx
More file actions
94 lines (85 loc) · 2.54 KB
/
TextLink.tsx
File metadata and controls
94 lines (85 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { Link } from "@remix-run/react";
import { cn } from "~/utils/cn";
import { Icon, type RenderIcon } from "./Icon";
import { useRef } from "react";
import { type ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKeys";
import { ShortcutKey } from "./ShortcutKey";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./Tooltip";
const variations = {
primary:
"text-indigo-500 transition hover:text-indigo-400 inline-flex gap-0.5 items-center group focus-visible:focus-custom",
secondary:
"text-text-dimmed transition hover:text-text-bright inline-flex gap-0.5 items-center group focus-visible:focus-custom",
} as const;
type TextLinkProps = {
href?: string;
to?: string;
className?: string;
trailingIcon?: RenderIcon;
trailingIconClassName?: string;
variant?: keyof typeof variations;
children: React.ReactNode;
shortcut?: ShortcutDefinition;
hideShortcutKey?: boolean;
tooltip?: React.ReactNode;
} & React.AnchorHTMLAttributes<HTMLAnchorElement>;
export function TextLink({
href,
to,
children,
className,
trailingIcon,
trailingIconClassName,
variant = "primary",
shortcut,
hideShortcutKey,
tooltip,
...props
}: TextLinkProps) {
const innerRef = useRef<HTMLAnchorElement>(null);
const classes = variations[variant];
if (shortcut) {
useShortcutKeys({
shortcut: shortcut,
action: () => {
if (innerRef.current) {
innerRef.current.click();
}
},
});
}
const renderShortcutKey = () =>
shortcut &&
!hideShortcutKey && <ShortcutKey className="ml-1.5" shortcut={shortcut} variant="small" />;
const linkContent = (
<>
{children}{" "}
{trailingIcon && <Icon icon={trailingIcon} className={cn("size-4", trailingIconClassName)} />}
{shortcut && !tooltip && renderShortcutKey()}
</>
);
const linkElement = to ? (
<Link ref={innerRef} to={to} className={cn(classes, className)} {...props}>
{linkContent}
</Link>
) : href ? (
<a ref={innerRef} href={href} className={cn(classes, className)} {...props}>
{linkContent}
</a>
) : (
<span>Need to define a path or href</span>
);
if (tooltip) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{linkElement}</TooltipTrigger>
<TooltipContent className="text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs">
{tooltip} {shortcut && renderShortcutKey()}
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
return linkElement;
}