Skip to content

Commit 5535e82

Browse files
committed
Create Link typography component
1 parent 92706da commit 5535e82

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

src/components/link/index.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
'text-primary text-inherit leading-tight inline-flex items-center transition-colors hover:text-primary/80 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+
},
17+
defaultVariants: {
18+
variant: 'default',
19+
},
20+
}
21+
)
22+
23+
export interface LinkProps
24+
extends React.AnchorHTMLAttributes<HTMLAnchorElement>,
25+
VariantProps<typeof linkVariants> {
26+
asChild?: boolean
27+
}
28+
29+
const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
30+
({ className, variant, asChild = false, ...props }, ref) => {
31+
const Comp = asChild ? Slot : 'a'
32+
return <Comp className={cn(linkVariants({ variant, className }))} ref={ref} {...props} />
33+
}
34+
)
35+
Link.displayName = 'Link'
36+
37+
export { Link, linkVariants }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
asChild: {
18+
control: 'boolean',
19+
description: 'Pass true to render a custom component instead of an anchor tag',
20+
},
21+
},
22+
} satisfies Meta<typeof Link>
23+
24+
export default meta
25+
type Story = StoryObj<typeof meta>
26+
27+
export const Default: Story = {
28+
args: {
29+
children: 'Oasis Explorer',
30+
href: '#',
31+
},
32+
}

0 commit comments

Comments
 (0)