Skip to content

Commit 2968ee8

Browse files
committed
feat(ui): setup link component
1 parent 208bc8e commit 2968ee8

File tree

1 file changed

+53
-7
lines changed

1 file changed

+53
-7
lines changed

packages/ui/src/Link/Link.tsx

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
1-
export const Link = () => {
2-
return (
3-
<div>
4-
<p>link</p>
5-
</div>
6-
);
7-
};
1+
import type { LinkProps as NextLinkProps } from 'next/link';
2+
import { forwardRef } from 'react';
3+
import NextLink from 'next/link';
4+
5+
import { cn } from '@acme/ui';
6+
7+
type AnchorProps = React.ComponentPropsWithoutRef<'a'>;
8+
9+
export type Props = {
10+
/** Indicates if the link is external */
11+
isExternal?: boolean;
12+
href: string;
13+
children: React.ReactNode;
14+
className?: string;
15+
} & (NextLinkProps | AnchorProps);
16+
17+
/**
18+
* Displays a link that can be either a Next.js Link or a regular anchor tag.
19+
* @param {boolean} [external=false] - Indicates if the link is external.
20+
*/
21+
export const Link = forwardRef<HTMLAnchorElement, Props>(
22+
({ isExternal = false, children, className, href, ...props }, ref) => {
23+
const Comp = isExternal ? NextLink : 'a';
24+
25+
const linkProps = isExternal
26+
? { target: '_blank', rel: 'noopener noreferrer', href }
27+
: { href };
28+
29+
return (
30+
<span className='inline-flex overflow-hidden'>
31+
<Comp
32+
ref={ref}
33+
className={cn(
34+
'group relative outline-none focus-visible:ring-2 focus-visible:ring-grey-text-contrast focus-visible:ring-offset-1',
35+
className,
36+
)}
37+
{...linkProps}
38+
{...props}
39+
>
40+
<span className='invisible'>{children}</span>
41+
<span className='absolute left-0 top-0 transition-transform duration-500 ease-in-out group-hover:-translate-y-[120%] group-hover:duration-300'>
42+
{children}
43+
</span>
44+
<span className='absolute left-0 top-0 translate-y-[150%] decoration-grey-text-contrast decoration-dashed decoration-1 underline-offset-2 transition-transform duration-500 ease-in-out group-hover:-translate-y-0 group-hover:underline group-hover:duration-300'>
45+
{children}
46+
</span>
47+
</Comp>
48+
</span>
49+
);
50+
},
51+
);
52+
53+
Link.displayName = 'CustomLink';

0 commit comments

Comments
 (0)