11import { Link } from "@remix-run/react" ;
22import { cn } from "~/utils/cn" ;
33import { Icon , type RenderIcon } from "./Icon" ;
4+ import { useRef } from "react" ;
5+ import { type ShortcutDefinition , useShortcutKeys } from "~/hooks/useShortcutKeys" ;
6+ import { ShortcutKey } from "./ShortcutKey" ;
7+ import { Tooltip , TooltipContent , TooltipProvider , TooltipTrigger } from "./Tooltip" ;
48
59const variations = {
610 primary :
@@ -17,6 +21,9 @@ type TextLinkProps = {
1721 trailingIconClassName ?: string ;
1822 variant ?: keyof typeof variations ;
1923 children : React . ReactNode ;
24+ shortcut ?: ShortcutDefinition ;
25+ hideShortcutKey ?: boolean ;
26+ tooltip ?: React . ReactNode ;
2027} & React . AnchorHTMLAttributes < HTMLAnchorElement > ;
2128
2229export function TextLink ( {
@@ -27,20 +34,61 @@ export function TextLink({
2734 trailingIcon,
2835 trailingIconClassName,
2936 variant = "primary" ,
37+ shortcut,
38+ hideShortcutKey,
39+ tooltip,
3040 ...props
3141} : TextLinkProps ) {
42+ const innerRef = useRef < HTMLAnchorElement > ( null ) ;
3243 const classes = variations [ variant ] ;
33- return to ? (
34- < Link to = { to } className = { cn ( classes , className ) } { ...props } >
44+
45+ if ( shortcut ) {
46+ useShortcutKeys ( {
47+ shortcut : shortcut ,
48+ action : ( ) => {
49+ if ( innerRef . current ) {
50+ innerRef . current . click ( ) ;
51+ }
52+ } ,
53+ } ) ;
54+ }
55+
56+ const renderShortcutKey = ( ) =>
57+ shortcut &&
58+ ! hideShortcutKey && < ShortcutKey className = "ml-1.5" shortcut = { shortcut } variant = "small" /> ;
59+
60+ const linkContent = (
61+ < >
3562 { children } { " " }
3663 { trailingIcon && < Icon icon = { trailingIcon } className = { cn ( "size-4" , trailingIconClassName ) } /> }
64+ { shortcut && ! tooltip && renderShortcutKey ( ) }
65+ </ >
66+ ) ;
67+
68+ const linkElement = to ? (
69+ < Link ref = { innerRef } to = { to } className = { cn ( classes , className ) } { ...props } >
70+ { linkContent }
3771 </ Link >
3872 ) : href ? (
39- < a href = { href } className = { cn ( classes , className ) } { ...props } >
40- { children } { " " }
41- { trailingIcon && < Icon icon = { trailingIcon } className = { cn ( "size-4" , trailingIconClassName ) } /> }
73+ < a ref = { innerRef } href = { href } className = { cn ( classes , className ) } { ...props } >
74+ { linkContent }
4275 </ a >
4376 ) : (
4477 < span > Need to define a path or href</ span >
4578 ) ;
79+
80+ if ( tooltip ) {
81+ return (
82+ < TooltipProvider >
83+ < Tooltip >
84+ < TooltipTrigger asChild > { linkElement } </ TooltipTrigger >
85+ < TooltipContent className = "text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs" >
86+ { tooltip } { shortcut && renderShortcutKey ( ) }
87+ </ TooltipContent >
88+ </ Tooltip >
89+ </ TooltipProvider >
90+ ) ;
91+ }
92+
93+ return linkElement ;
4694}
0 commit comments