Skip to content

Commit 106025d

Browse files
committed
Add Typography component
1 parent 13bca08 commit 106025d

3 files changed

Lines changed: 132 additions & 29 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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: "scroll-m-20 text-4xl font-semibold tracking-[-0.04em] lg:text-5xl",
10+
h2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-[-0.04em] first:mt-0",
11+
h3: "scroll-m-20 text-2xl font-semibold tracking-[-0.04em]",
12+
h4: "scroll-m-20 text-xl font-semibold tracking-[-0.04em]",
13+
p: "leading-7 [&:not(:first-child)]:mt-6",
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-sm 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+
30+
asChild?: boolean
31+
}
32+
33+
34+
function defaultTagFor(
35+
variant: NonNullable<VariantProps<typeof typographyVariants>["variant"]>
36+
): keyof JSX.IntrinsicElements {
37+
switch (variant) {
38+
case "h1":
39+
case "h2":
40+
case "h3":
41+
case "h4":
42+
return variant
43+
case "blockquote":
44+
return "blockquote"
45+
default:
46+
return "p"
47+
}
48+
}
49+
50+
export const Typography = React.forwardRef<HTMLElement, TypographyProps>(
51+
({ asChild = false, variant, className, ...props }, ref) => {
52+
53+
const v = (variant ?? "p") as NonNullable<TypographyProps["variant"]>
54+
const Comp: any = asChild ? Slot : defaultTagFor(v)
55+
56+
return (
57+
<Comp
58+
ref={ref}
59+
className={cn(typographyVariants({ variant: v, className }))}
60+
{...props}
61+
/>
62+
)
63+
}
64+
)
65+
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)