1

Paragraph

A paragraph whose size pairs with the matching heading size.

Build faster with ondo

Components you own, styled with your own theme tokens. Copy them in, keep the code, change whatever you need.

import { Heading } from "@/components/ui/heading"
import { Paragraph } from "@/components/ui/paragraph"

Installation

bunx --bun shadcn@latest add @ondo-ui/paragraph

Usage

import { Paragraph } from "@/components/ui/paragraph"
<Paragraph
  size="1 | 2 | 3 | 4 | 5 | 6"
  variant="default | primary | secondary | muted | info | success | warning | danger"
  wrap="normal | nowrap | balance | pretty"
>
  Paragraph
</Paragraph>

size picks a step on the body scale. Each step matches the Heading step with the same number, so a heading and the paragraph under it can share one number.

Examples

Sizes

1 is the largest and 6 the smallest. 4 is the default and the one to reach for in body copy.

Size 1 — a lede paragraph under a hero heading.

Size 2 — an intro paragraph for a section.

Size 3 — a slightly larger body paragraph.

Size 4 — the default body paragraph.

Size 5 — supporting copy inside dense UI.

Size 6 — captions, hints, and metadata.

import { Paragraph } from "@/components/ui/paragraph"

export default function ParagraphSizes() {

Pairing with a heading

The two scales are numbered together. Passing the same size to Heading and Paragraph keeps the title and its copy in proportion at every step.

size=1

Ship a design system

Every heading size has a paragraph size with the same number, so a heading and the copy beneath it stay in proportion.

size=2

Ship a design system

Every heading size has a paragraph size with the same number, so a heading and the copy beneath it stay in proportion.

size=3

Ship a design system

Every heading size has a paragraph size with the same number, so a heading and the copy beneath it stay in proportion.

size=4

Ship a design system

Every heading size has a paragraph size with the same number, so a heading and the copy beneath it stay in proportion.

size=5

Ship a design system

Every heading size has a paragraph size with the same number, so a heading and the copy beneath it stay in proportion.

size=6

Ship a design system

Every heading size has a paragraph size with the same number, so a heading and the copy beneath it stay in proportion.

import { Heading } from "@/components/ui/heading"
import { Paragraph } from "@/components/ui/paragraph"

Variants

variant changes the text colour. The danger variant uses the theme's destructive colour token. Use Tailwind font utilities through className when you need to adjust the weight, such as className="font-medium".

variant="default"

The default paragraph variant.

variant="primary"

The primary paragraph variant.

variant="secondary"

The secondary paragraph variant.

variant="muted"

The muted paragraph variant.

variant="info"

The info paragraph variant.

variant="success"

The success paragraph variant.

variant="warning"

The warning paragraph variant.

variant="danger"

The danger paragraph variant.

import { Paragraph } from "@/components/ui/paragraph"

const variants = [

Wrap

wrap controls how the text breaks across lines and defaults to pretty, which fills lines normally and only tidies the last one so a final word is not left alone. balance evens out every line instead, which suits short blocks rather than running copy.

wrap="pretty" (default)

A paragraph wrapped with pretty fills every line normally and only tidies the last one, so no single word is left stranded.

wrap="balance"

A paragraph wrapped with balance evens out every line, which suits short blocks such as a single callout sentence.

import { Paragraph } from "@/components/ui/paragraph"

export default function ParagraphWrap() {

Custom element

Use the render prop when the markup needs a different element — a span inside another paragraph, or a figcaption under an image — but you still want the body scale.

Rendered as a span, for copy that sits inside another paragraph.
Rendered as a figcaption, for an image credit.
import { Paragraph } from "@/components/ui/paragraph"

export default function ParagraphRender() {

API reference

Paragraph

Renders a p element styled from the body scale.

PropTypeDefault
size1 | 2 | 3 | 4 | 5 | 64
variant"default" | "primary" | "secondary" | "muted" | "info" | "success" | "warning" | "danger"default
wrap"normal" | "nowrap" | "balance" | "pretty"pretty
renderReactElement | (props, state) => ReactElement-
classNamestring-

Scale

SizeClassesPairs with heading
1text-[1.25rem]/[1.6] tracking-[-0.006em]2.25rem
2text-[1.125rem]/[1.6] tracking-[-0.004em]1.75rem
3text-[1.0625rem]/[1.65] tracking-[-0.002em]1.5rem
4text-[1rem]/[1.65]1.375rem
5text-[0.9375rem]/[1.6] tracking-[0.002em]1.25rem
6text-[0.875rem]/[1.6] tracking-[0.004em]1.125rem

Every size gets a colour from variant and a wrap utility from wrap (text-pretty by default). Use className with Tailwind font utilities for weight.