- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Date Picker
- Desktop Window
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Frame
- Heading
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Live Waveform
- Marker
- Menubar
- Message
- Message Scroller
- Meter
- Meter Ring
- Native Select
- Navigation Menu
- NumberCount
- Pagination
- Paragraph
- Popover
- Progress
- Progress Ring
- Questionnaire
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Spinner
- Stepper
- Switch
- Table
- Tabs
- Textarea
- Timeline
- Toast
- Toggle
- Toggle Group
- Tooltip
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"
Paragraph is for application UI, the same as
Heading. Rendered markdown and MDX already get
their paragraph styles from the typeset layer, so you do not need this
component inside prose.
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.
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.
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.
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.
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.
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.
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".
The default paragraph variant.
The primary paragraph variant.
The secondary paragraph variant.
The muted paragraph variant.
The info paragraph variant.
The success paragraph variant.
The warning paragraph variant.
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.
A paragraph wrapped with pretty fills every line normally and only tidies the last one, so no single word is left stranded.
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.
import { Paragraph } from "@/components/ui/paragraph"
export default function ParagraphRender() {API reference#
Paragraph#
Renders a p element styled from the body scale.
| Prop | Type | Default |
|---|---|---|
size | 1 | 2 | 3 | 4 | 5 | 6 | 4 |
variant | "default" | "primary" | "secondary" | "muted" | "info" | "success" | "warning" | "danger" | default |
wrap | "normal" | "nowrap" | "balance" | "pretty" | pretty |
render | ReactElement | (props, state) => ReactElement | - |
className | string | - |
Scale#
| Size | Classes | Pairs with heading |
|---|---|---|
1 | text-[1.25rem]/[1.6] tracking-[-0.006em] | 2.25rem |
2 | text-[1.125rem]/[1.6] tracking-[-0.004em] | 1.75rem |
3 | text-[1.0625rem]/[1.65] tracking-[-0.002em] | 1.5rem |
4 | text-[1rem]/[1.65] | 1.375rem |
5 | text-[0.9375rem]/[1.6] tracking-[0.002em] | 1.25rem |
6 | text-[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.