Typography
Semantic text elements with consistent styling. Provides unified typography system for headings, body text, blockquotes, lists, and inline code.
AccessibleDark ModeSemantic11 VariantsFlexible
Install
$
npx react-principles add typography01
Live Demo
Explore all variants and interactive states in Storybook.
Open Storybookopen_in_newHeading 1 - Page Title
Heading 2 - Section Title
Heading 3 - Subsection Title
Heading 4 - Component Title
This is body text. It uses a comfortable reading size with proper line height for long-form content. The text color provides good contrast in both light and dark modes.
This is a lead paragraph. It's larger than body text and perfect for introductory content or opening statements.
This is muted text. It's styled with a lighter color for secondary information.
This is small text. Use it for fine print, legal disclaimers, or copyright notices."Good typography is invisible—it lets the content shine without drawing attention to itself."
- Semantic HTML elements by default
- Consistent sizing and spacing
- Dark mode support out of the box
You can use inline code like Typography within body text to highlight technical terms.
02
Code Snippet
src/ui/Typography.tsx
import { Typography } from "@/ui/Typography"; // Headings <Typography variant="h1">Page Title</Typography> <Typography variant="h2">Section Title</Typography> <Typography variant="h3">Subsection Title</Typography> // Body text <Typography variant="p">Body text paragraph.</Typography> <Typography variant="lead">Large introductory paragraph.</Typography> <Typography variant="muted">Secondary subdued text.</Typography> // Block elements <Typography variant="blockquote">"Quote text here"</Typography> <Typography variant="list"> <li>First item</li> <li>Second item</li> </Typography> // Inline code <Typography variant="code">const foo = "bar";</Typography>
03
Copy-Paste (Single File)
Typography.tsx
import { forwardRef, type HTMLAttributes } from "react"; import { cn } from "@/lib/utils"; // ─── Types ──────────────────────────────────────────────────────────────────── export type TypographyVariant = | "h1" | "h2" | "h3" | "h4" | "p" | "lead" | "muted" | "small" | "blockquote" | "code" | "list"; export interface TypographyProps extends Omit<HTMLAttributes<HTMLElement>, "as"> { variant?: TypographyVariant; as?: React.ElementType; } // ─── Constants ──────────────────────────────────────────────────────────────── const VARIANT_STYLES: Record<TypographyVariant, string> = { h1: "text-4xl font-black tracking-tight text-slate-900 dark:text-white md:text-5xl", h2: "text-2xl font-bold text-slate-900 dark:text-white", h3: "text-xl font-bold text-slate-900 dark:text-white", h4: "text-lg font-semibold text-slate-900 dark:text-white", p: "text-sm leading-relaxed text-slate-600 dark:text-slate-400", lead: "text-lg leading-relaxed text-slate-700 dark:text-slate-300", muted: "text-sm text-slate-500 dark:text-slate-400", small: "text-xs text-slate-500 dark:text-slate-400", blockquote: "border-l-4 border-primary pl-4 italic text-slate-700 dark:text-slate-300", code: "font-mono text-xs bg-slate-100 dark:bg-[#1f2937] px-1.5 py-0.5 rounded text-slate-900 dark:text-white", list: "list-disc pl-4 space-y-1 text-sm text-slate-600 dark:text-slate-400", }; const DEFAULT_ELEMENTS: Record<TypographyVariant, string> = { h1: "h1", h2: "h2", h3: "h3", h4: "h4", p: "p", lead: "p", muted: "p", small: "small", blockquote: "blockquote", code: "code", list: "ul", }; // ─── Component ──────────────────────────────────────────────────────────────── export const Typography = forwardRef<HTMLElement, TypographyProps>( function TypographyRoot({ variant = "p", as, className, children, ...rest }, ref) { const Component = as || DEFAULT_ELEMENTS[variant]; const variantStyle = VARIANT_STYLES[variant]; return ( <Component ref={ref} className={cn(variantStyle, className)} {...rest}> {children} </Component> ); } );
04
Props
Extends all native HTML element attributes. The rendered element can be customized with the `as` prop.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | TypographyVariant | "p" | Typography style to apply (h1, h2, h3, h4, p, lead, muted, small, blockquote, code, list). |
as | React.ElementType | — | Override the default HTML element. Example: variant='h2' as='h1' renders h1 with h2 styling. |
className | string | — | Additional CSS classes to apply (merged with variant styles). |