Tiesen Logo
Components

Typography

A form component built from scratch that works with Standard Schema

GitHubComponent Source
import { Typography } from '@/components/ui/typography'

export default function TypographyDemo() {
  const text = 'The quick brown fox jumps over the lazy dog.'

  return (
    <article className='not-prose'>
      <Typography variant='h1'>H1. Heading 1</Typography>
      <Typography variant='h2'>H2. Heading 2</Typography>
      <Typography variant='h3'>H3. Heading 3</Typography>
      <Typography variant='h4'>H4. Heading 4</Typography>
      <Typography variant='h5'>H5. Heading 5</Typography>
      <Typography variant='h6'>H6. Heading 6</Typography>
      <Typography>{text}</Typography>
      <Typography variant='blockquote'>“{text}”</Typography>
      <Typography variant='code'>{text}</Typography>
      <Typography variant='ul'>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
      </Typography>
      <Typography variant='ol'>
        <li>Ordered item 1</li>
        <li>Ordered item 2</li>
        <li>Ordered item 3</li>
      </Typography>
    </article>
  )
}

Installation

CLI

npx shadcn add https://ui.tiesen.id.vn/r/typography.json
npx shadcn add https://ui.tiesen.id.vn/r/typography.json
pnpm dlx shadcn add https://ui.tiesen.id.vn/r/typography.json
bunx --bun shadcn add https://ui.tiesen.id.vn/r/typography.json

Manual

Copy and paste the following code into your project.

import type { VariantProps } from 'class-variance-authority'
import * as React from 'react'
import { cva } from 'class-variance-authority'

import { cn } from '@/lib/utils'

const typographyVariants = cva('mb-1 text-base leading-7 font-normal', {
  variants: {
    variant: {
      h1: 'mb-8 scroll-m-20 text-7xl font-extrabold tracking-tight text-balance lg:text-8xl',
      h2: 'mb-5 scroll-m-20 text-5xl font-bold tracking-tight text-balance first:mt-0 lg:text-6xl',
      h3: 'mb-4 scroll-m-20 text-4xl font-semibold tracking-tight text-balance lg:text-5xl',
      h4: 'mb-3 scroll-m-20 text-3xl font-semibold tracking-tight text-balance lg:text-4xl',
      h5: 'mb-2.5 scroll-m-20 text-xl font-semibold tracking-tight text-balance lg:text-2xl',
      h6: 'mb-2 scroll-m-20 text-lg font-semibold tracking-tight text-balance lg:text-xl',
      p: 'text-base text-pretty lg:text-lg',
      ul: 'my-4 ml-6 list-disc text-base lg:text-lg [&>li]:mt-2 [&>li]:first:mt-0',
      ol: '"my-4 ml-6 list-decimal text-base lg:text-lg [&>li]:mt-2 [&>li]:first:mt-0',
      blockquote: 'my-2 border-l-2 pl-6 italic',
      code: 'relative w-fit rounded-md bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-medium',
      caption: 'block text-sm tracking-wide',
    },
  },
  defaultVariants: {
    variant: 'p',
  },
})

interface TypographyProps
  extends React.ComponentProps<'p'>,
    VariantProps<typeof typographyVariants> {
  component?: React.ElementType
}

function Typography({
  className,
  variant = 'p',
  component,
  ...props
}: TypographyProps) {
  const Comp = component ?? (variant as React.ElementType)

  return (
    <Comp
      data-slot='typography'
      className={cn(typographyVariants({ variant }), className)}
      {...props}
    />
  )
}

export { Typography, typographyVariants }