Skip to content

Commit 9c7702d

Browse files
authored
Merge pull request #60 from oasisprotocol/kaja/typography-component
Typography component
2 parents 13bca08 + 478ded3 commit 9c7702d

File tree

3 files changed

+125
-26
lines changed

3 files changed

+125
-26
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import * as React from 'react'
2+
import { Slot } from '@radix-ui/react-slot'
3+
import { cva, type VariantProps } from 'class-variance-authority'
4+
import { cn } from '../../lib/utils'
5+
6+
export const typographyVariants = cva('', {
7+
variants: {
8+
variant: {
9+
h1: 'text-3xl font-semibold text-foreground',
10+
h2: 'text-2xl font-semibold text-foreground',
11+
h3: 'text-xl font-semibold text-foreground',
12+
h4: 'text-lg font-semibold text-foreground',
13+
p: 'leading-7',
14+
blockquote: 'mt-6 border-l-2 pl-6 italic',
15+
lead: 'text-xl text-muted-foreground',
16+
large: 'text-lg font-semibold',
17+
small: 'text-sm font-medium leading-none',
18+
},
19+
textColor: {
20+
muted: 'text-muted-foreground',
21+
},
22+
},
23+
defaultVariants: {
24+
variant: 'p',
25+
},
26+
})
27+
28+
export interface TypographyProps
29+
extends React.HTMLAttributes<HTMLElement>,
30+
VariantProps<typeof typographyVariants> {
31+
asChild?: boolean
32+
}
33+
34+
function defaultTagFor(variant?: TypographyProps['variant']): keyof JSX.IntrinsicElements {
35+
switch (variant) {
36+
case 'h1':
37+
case 'h2':
38+
case 'h3':
39+
case 'h4':
40+
return variant
41+
case 'blockquote':
42+
return 'blockquote'
43+
default:
44+
return 'p'
45+
}
46+
}
47+
48+
export const Typography = React.forwardRef<HTMLElement, TypographyProps>(
49+
({ textColor, asChild = false, variant, className, ...props }, ref) => {
50+
const Comp: React.ElementType = asChild ? Slot : defaultTagFor(variant)
51+
return <Comp ref={ref} className={cn(typographyVariants({ variant, textColor }), className)} {...props} />
52+
}
53+
)
54+
Typography.displayName = 'Typography'
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+
}
Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,45 @@
1-
import type { Meta, StoryObj } from '@storybook/react'
2-
import { Link } from '../../components/link'
1+
import type { Meta, StoryObj } from '@storybook/react-vite'
2+
import { Typography } from '../../components/typography'
33

4-
const meta = {
5-
title: 'Typography/Link',
6-
component: Link,
4+
const meta: Meta<typeof Typography> = {
5+
title: 'Typography/Typography',
6+
component: Typography,
77
parameters: {
8+
docs: {
9+
description: {
10+
component:
11+
'Project typography primitives (h1–h4, p, blockquote, small, lead, large). Use the `textColor` prop for muted text.',
12+
},
13+
},
814
layout: 'centered',
15+
design: {
16+
type: 'figma',
17+
url: 'https://www.figma.com/design/dSsI9L6NSpNCorbSdiYd1k/Oasis-Design-System---shadcn-ui---Default---December-2024?node-id=473-1978',
18+
},
919
},
1020
tags: ['autodocs'],
1121
argTypes: {
1222
variant: {
1323
control: 'select',
14-
options: ['default', 'underline', 'hover'],
15-
description: 'The visual style variant of the link',
24+
options: ['h1', 'h2', 'h3', 'h4', 'p', 'blockquote', 'lead', 'large', 'small'],
1625
},
1726
textColor: {
1827
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',
28+
options: [undefined, 'muted'],
29+
description: 'Optional text color override (e.g., muted).',
3030
},
31+
asChild: { control: 'boolean' },
32+
className: { control: 'text' },
33+
children: { control: 'text' },
34+
},
35+
args: {
36+
variant: 'p',
37+
textColor: undefined,
38+
children: 'The quick brown fox jumps over the lazy dog.',
3139
},
32-
} satisfies Meta<typeof Link>
40+
}
3341

3442
export default meta
3543
type Story = StoryObj<typeof meta>
3644

37-
export const Default: Story = {
38-
args: {
39-
children: 'Oasis Explorer',
40-
href: '#',
41-
textColor: 'primary',
42-
},
43-
}
45+
export const Default: Story = {}

0 commit comments

Comments
 (0)