Graphical PDS migrator for AT Protocol
at main 1.8 kB view raw
1import { JSX } from "preact"; 2 3/** 4 * Props for the Link component 5 */ 6type Props = Omit<JSX.HTMLAttributes<HTMLAnchorElement>, "href"> & { 7 /** URL for the link */ 8 href: string; 9 /** Whether this is an external link that should show an outbound icon */ 10 isExternal?: boolean; 11 /** Link text content */ 12 children: JSX.Element | string; 13}; 14 15/** 16 * A link component that handles external links with appropriate styling and accessibility. 17 * Automatically adds external link icon and proper attributes for external links. 18 */ 19export function Link(props: Props) { 20 const { 21 isExternal = false, 22 class: className = "", 23 children, 24 href, 25 ...rest 26 } = props; 27 28 // SVG for external link icon 29 const externalLinkIcon = ( 30 <svg 31 xmlns="http://www.w3.org/2000/svg" 32 viewBox="0 0 20 20" 33 fill="currentColor" 34 className="w-4 h-4 inline-block ml-1" 35 aria-hidden="true" 36 > 37 <path 38 fillRule="evenodd" 39 d="M4.25 5.5a.75.75 0 00-.75.75v8.5c0 .414.336.75.75.75h8.5a.75.75 0 00.75-.75v-4a.75.75 0 011.5 0v4A2.25 2.25 0 0112.75 17h-8.5A2.25 2.25 0 012 14.75v-8.5A2.25 2.25 0 014.25 4h5a.75.75 0 010 1.5h-5z" 40 /> 41 <path 42 fillRule="evenodd" 43 d="M6.194 12.753a.75.75 0 001.06.053L16.5 4.44v2.81a.75.75 0 001.5 0v-4.5a.75.75 0 00-.75-.75h-4.5a.75.75 0 000 1.5h2.553l-9.056 8.194a.75.75 0 00-.053 1.06z" 44 /> 45 </svg> 46 ); 47 48 return ( 49 <a 50 href={href} 51 {...rest} 52 className={`inline-flex items-center hover:underline ${className}`} 53 {...(isExternal && { 54 target: "_blank", 55 rel: "noopener noreferrer", 56 "aria-label": `${ 57 typeof children === "string" ? children : "" 58 } (opens in new tab)`, 59 })} 60 > 61 {children} 62 {isExternal && externalLinkIcon} 63 </a> 64 ); 65}