Skip to content

Commit 912664e

Browse files
committed
Add Typography component
1 parent 13bca08 commit 912664e

3 files changed

Lines changed: 119 additions & 29 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
muted: 'text-muted-foreground',
19+
},
20+
},
21+
defaultVariants: {
22+
variant: 'p',
23+
},
24+
})
25+
26+
export interface TypographyProps
27+
extends React.HTMLAttributes<HTMLElement>,
28+
VariantProps<typeof typographyVariants> {
29+
asChild?: boolean
30+
}
31+
32+
function defaultTagFor(variant?: TypographyProps['variant']): keyof JSX.IntrinsicElements {
33+
switch (variant) {
34+
case 'h1':
35+
case 'h2':
36+
case 'h3':
37+
case 'h4':
38+
return variant
39+
case 'blockquote':
40+
return 'blockquote'
41+
default:
42+
return 'p'
43+
}
44+
}
45+
46+
export const Typography = React.forwardRef<HTMLElement, TypographyProps>(
47+
({ asChild = false, variant, className, ...props }, ref) => {
48+
const Comp: React.ElementType = asChild ? Slot : defaultTagFor(variant)
49+
return <Comp ref={ref} className={cn(typographyVariants({ variant }), className)} {...props} />
50+
}
51+
)
52+
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: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,38 @@
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: 'Project typography primitives (h1–h4, p, blockquote, small, muted).',
11+
},
12+
},
813
layout: 'centered',
14+
design: {
15+
type: 'figma',
16+
url: 'https://www.figma.com/design/dSsI9L6NSpNCorbSdiYd1k/Oasis-Design-System---shadcn-ui---Default---December-2024?node-id=473-1978',
17+
},
918
},
1019
tags: ['autodocs'],
1120
argTypes: {
1221
variant: {
1322
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',
23+
options: ['h1', 'h2', 'h3', 'h4', 'p', 'blockquote', 'lead', 'large', 'small', 'muted'],
3024
},
25+
asChild: { control: 'boolean' },
26+
className: { control: 'text' },
27+
children: { control: 'text' },
3128
},
32-
} satisfies Meta<typeof Link>
29+
args: {
30+
variant: 'p',
31+
children: 'The quick brown fox jumps over the lazy dog.',
32+
},
33+
}
3334

3435
export default meta
3536
type Story = StoryObj<typeof meta>
3637

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

0 commit comments

Comments
 (0)