Skip to content

Commit 47a57d9

Browse files
committed
Create Link typography component
1 parent 92706da commit 47a57d9

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

src/components/link/index.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import * as React from 'react'
2+
import { Slot } from '@radix-ui/react-slot'
3+
import { cva, type VariantProps } from 'class-variance-authority'
4+
5+
import { cn } from '../../lib/utils'
6+
7+
const linkVariants = cva(
8+
'leading-tight inline-flex items-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
9+
{
10+
variants: {
11+
variant: {
12+
default: '',
13+
underline: 'underline underline-offset-4',
14+
hover: 'hover:underline hover:underline-offset-4',
15+
},
16+
textColor: {
17+
primary: 'text-primary hover:text-primary/80',
18+
inherit: 'text-inherit hover:opacity-80',
19+
},
20+
},
21+
defaultVariants: {
22+
variant: 'default',
23+
textColor: 'primary',
24+
},
25+
}
26+
)
27+
28+
export interface LinkProps
29+
extends React.AnchorHTMLAttributes<HTMLAnchorElement>,
30+
VariantProps<typeof linkVariants> {
31+
asChild?: boolean
32+
}
33+
34+
const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
35+
({ className, variant, textColor, asChild = false, ...props }, ref) => {
36+
const Comp = asChild ? Slot : 'a'
37+
return <Comp className={cn(linkVariants({ variant, textColor, className }))} ref={ref} {...props} />
38+
}
39+
)
40+
Link.displayName = 'Link'
41+
42+
export { Link, linkVariants }
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import type { Meta, StoryObj } from '@storybook/react'
2+
import { Link } from '../../components/link'
3+
4+
const meta = {
5+
title: 'Typography/Link',
6+
component: Link,
7+
parameters: {
8+
layout: 'centered',
9+
},
10+
tags: ['autodocs'],
11+
argTypes: {
12+
variant: {
13+
control: 'select',
14+
options: ['default', 'underline', 'hover'],
15+
description: 'The visual style variant of the link',
16+
},
17+
textColor: {
18+
control: 'select',
19+
options: ['primary', 'inherit'],
20+
description: 'The text color scheme of the link',
21+
defaultValue: 'primary',
22+
},
23+
asChild: {
24+
control: 'boolean',
25+
description: 'When true, renders the child component with Link styles and props merged.',
26+
},
27+
className: {
28+
control: 'text',
29+
description: 'Additional CSS classes for custom styling',
30+
},
31+
},
32+
} satisfies Meta<typeof Link>
33+
34+
export default meta
35+
type Story = StoryObj<typeof meta>
36+
37+
export const Default: Story = {
38+
args: {
39+
children: 'Oasis Explorer',
40+
href: '#',
41+
textColor: 'primary',
42+
},
43+
}

0 commit comments

Comments
 (0)