Typography

This is a shadcn based typography component. Used to keep the visual hierarchy of the page consistent, and keep the semantics flexible.

Installation

npx shadcn@latest add https://shadcn-typography.vercel.app/r/typography.json

Construction

This component is built to provide semantic HTML structure while maintaining visual consistency.

import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { JSX } from "react";
 
const typographyVariants = cva("text-foreground", {
  variants: {
    variant: {
      h1: "font-heading text-6xl font-bold tracking-tighter md:text-7xl lg:text-8xl",
      h2: "font-heading text-3xl lg:text-4xl font-semibold tracking-tight first:mt-0",
      h3: "font-heading text-2xl font-semibold tracking-tight",
      h4: "font-heading text-xl font-semibold tracking-tight",
      p: "leading-7 [&:not(:first-child)]:mt-6",
      blockquote: "mt-6 border-l-2 pl-6 italic",
      ul: "my-6 ml-6 list-disc [&>li]:mt-2",
      ol: "my-6 ml-6 list-decimal [&>li]:mt-2",
      lead: "text-xl text-muted-foreground",
      large: "text-lg font-semibold",
      small: "text-sm font-medium leading-none",
      muted: "text-sm text-muted-foreground",
      inlineCode:
        "relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold",
    },
  },
  defaultVariants: {
    variant: "p",
  },
});
 
type VariantPropType = VariantProps<typeof typographyVariants>["variant"];
 
const variantElementMap: Record<
  NonNullable<VariantPropType>,
  React.ElementType
> = {
  h1: "h1",
  h2: "h2",
  h3: "h3",
  h4: "h4",
  p: "p",
  blockquote: "blockquote",
  ul: "ul",
  ol: "ol",
  lead: "p",
  large: "div",
  small: "small",
  muted: "p",
  inlineCode: "code",
};
 
export interface TypographyProps
  extends
    React.HTMLAttributes<HTMLElement>,
    VariantProps<typeof typographyVariants> {
  asChild?: boolean;
  as?: keyof JSX.IntrinsicElements;
}
 
const Typography = React.forwardRef<HTMLElement, TypographyProps>(
  ({ className, variant, as, asChild = false, ...props }, ref) => {
    const Comp = asChild
      ? Slot
      : (as ?? ((variant ? variantElementMap[variant] : "p") || "p"));
 
    return (
      <Comp
        className={cn(typographyVariants({ variant, className }))}
        ref={ref}
        {...props}
      />
    );
  },
);
Typography.displayName = "Typography";
 
export { Typography, typographyVariants };
 

Props

PropTypeDefaultDescription
variantstring"p"The visual style and semantic element to render.
asChildbooleanfalseChange the default rendered element for the one passed as a child.
asstring-Change the default rendered element to the one passed as a string.
classNamestring-Additional CSS classes to apply to the element.

Default variants

The default variants are a starting point for building your own typography. They are designed to be flexible and customizable, while still maintaining a consistent visual hierarchy.

  • Headings

    Standard heading hierarchies.

    h1

    Taxonomy of Design

    h2

    The Science of Typography

    h3

    Principles of Hierarchy

    h4

    Visual Balance

  • Content & Body

    Variants for body text and content emphasis.

    lead

    A modal dialog that interrupts the user with important content and expects a response.

    p

    The king, seeing how much happier his subjects were, realized the error of his ways and repealed the joke tax.

    large
    This is large text used for emphasis or introductions.
    small
    This contains email address or other small metadata.
    muted

    This is muted text, useful for secondary information or captions.

  • Special Elements

    Specific variants for quotes, code, and labels.

    blockquote
    "After all," he said, "everyone enjoys a good joke, so it's only fair that they should pay for the privilege."
    inlineCode

    Press ⌘K to open the command palette.

  • Lists

    Standard ordered and unordered lists.

    ul
    • 1st level of puns: 5 gold coins
    • 2nd level of jokes: 10 gold coins
    • 3rd level of one-liners : 20 gold coins
    ol
    1. System boot
    2. Check hardware
    3. Load specific modules