Skip to content

Commit 318edb9

Browse files
authored
Merge pull request #52 from oasisprotocol/mz/link
Create Link typography component
2 parents d027194 + 3acb375 commit 318edb9

3 files changed

Lines changed: 86 additions & 1 deletion

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+
}

src/styles/global.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
--card-foreground: hsl(240 10% 4%);
1313
--popover: hsl(0 0% 100%);
1414
--popover-foreground: hsl(240 10% 4%);
15-
--primary: hsl(241 100% 44%);
15+
--primary: hsl(241.33 100% 44.31%);
1616
--primary-foreground: hsl(0 0% 98%);
1717
--secondary: hsl(240 5% 96%);
1818
--secondary-foreground: hsl(240 6% 10%);

0 commit comments

Comments
 (0)