Text components that use the font of the host app: Heading (H1 to H4) with the visual size separate from the semantic level, Text, Lead, Prose for raw HTML, InlineCode, Blockquote and List.
Heading 1
Heading 2
Heading 3
Heading 4
A level 2 heading drawn small
import { H1, H2, H3, H4, Heading } from "@rdloom/react";
export default function TypographyHeadingsExample() {
return (
<div className="flex w-full justify-center">
<div className="flex w-full max-w-lg flex-col gap-3">
<H1>Heading 1</H1>
<H2>Heading 2</H2>
<H3>Heading 3</H3>
<H4>Heading 4</H4>
<Heading level={2} size="sm">
A level 2 heading drawn small
</Heading>
</div>
</div>
);
}Installation
npx rdloom add typographyCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/typography.jsonWorks, but without upgrade tracking.
Usage
import { H1, H2, H3, H4, Heading } from "@rdloom/react";
<div className="flex w-full justify-center">
<div className="flex w-full max-w-lg flex-col gap-3">
<H1>Heading 1</H1>
<H2>Heading 2</H2>
<H3>Heading 3</H3>
<H4>Heading 4</H4>
<Heading level={2} size="sm">
A level 2 heading drawn small
</Heading>
</div>
</div>Prose
Shipping a release
A release starts from main. Read the release notes before you tag it.
Checklist
- Run the full test suite
- Update the changelog
Small releases are easier to roll back.
| Step | Owner |
|---|---|
| Tag | Release manager |
| Announce | Support |
import { Prose } from "@rdloom/react";
export default function TypographyProseExample() {
return (
<div className="flex w-full justify-center">
<Prose>
<h2>Shipping a release</h2>
<p>
A release starts from <code>main</code>. Read the <a href="#notes">release notes</a> before you tag it.
</p>
<h3>Checklist</h3>
<ul>
<li>Run the full test suite</li>
<li>Update the changelog</li>
</ul>
<blockquote>Small releases are easier to roll back.</blockquote>
<hr />
<table>
<thead>
<tr>
<th>Step</th>
<th>Owner</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tag</td>
<td>Release manager</td>
</tr>
<tr>
<td>Announce</td>
<td>Support</td>
</tr>
</tbody>
</table>
</Prose>
</div>
);
}Text tones
A short introduction to the page.
Large default text
Medium default text
Small muted helper text
The password must have at least 8 characters.
Inline muted span inside a paragraph.
import { Lead, Text } from "@rdloom/react";
export default function TypographyTextTonesExample() {
return (
<div className="flex w-full justify-center">
<div className="flex w-full max-w-md flex-col gap-2">
<Lead>A short introduction to the page.</Lead>
<Text size="lg">Large default text</Text>
<Text>Medium default text</Text>
<Text size="sm" tone="muted">
Small muted helper text
</Text>
<Text size="sm" tone="danger">
The password must have at least 8 characters.
</Text>
<Text>
Inline{" "}
<Text as="span" tone="muted">
muted span
</Text>{" "}
inside a paragraph.
</Text>
</div>
</div>
);
}Lists and quote
- Install the package
- Import
Headingwhere you need it
- Write the spec
- Build the component
Say what the page is for before you style it.
import { Blockquote, InlineCode, List, ListItem } from "@rdloom/react";
export default function TypographyListsAndQuoteExample() {
return (
<div className="flex w-full justify-center">
<div className="flex w-full max-w-md flex-col gap-4">
<List>
<ListItem>Install the package</ListItem>
<ListItem>
Import <InlineCode>Heading</InlineCode> where you need it
</ListItem>
</List>
<List ordered>
<ListItem>Write the spec</ListItem>
<ListItem>Build the component</ListItem>
</List>
<Blockquote source="A teammate">Say what the page is for before you style it.</Blockquote>
</div>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
levelHeading only: the semantic level, 1 to 4. Pick the level that fits the page outline, not the look. | number | 2 |
sizeVisual size, independent of the level. Heading takes sm to 2xl; Text takes sm, md or lg (default md). | "sm" | "md" | "lg" | "xl" | "2xl" | "xl" |
toneText colour. danger is for error text and must say what is wrong in words. | "default" | "muted" | "danger" | "default" |
asText only: the element, a paragraph or an inline span. | "p" | "span" | "p" |
childrenrequiredThe text, or for Prose the raw HTML elements to style. | node | none |
Accessibility
Role heading, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
Not interactive.
Screen readers announce
- Headings are reachable by heading navigation with the right level
- Lists are announced with their item count
- Inline code is read as ordinary text
What your code must do
- Heading renders h1 to h4 from level, so the outline is set by level and never by size
- Do not skip levels (h2 then h4)
- Muted text keeps 4.5:1 against the surface; danger text is never the only sign of an error
- Blockquote is a real blockquote element; a source goes in a footer or cite
- List renders ul or ol with real list items
- Links inside Prose keep an underline and a visible focus ring
Guidelines
Use it when
- Page and section headings
- Article or CMS content that arrives as HTML (wrap it in Prose)
- Body, helper and error text that must follow the design tokens
Avoid it when
- Labels for form fields: use the field's own label
- Choosing a heading level for its size: change size instead
Don't
- Using H1 several times on a page
- Picking h4 because it looks smaller
- Using danger tone without a message
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-text-default--rd-color-text-muted--rd-color-feedback-danger--rd-color-border-default--rd-color-border-strong--rd-color-surface-subtle--rd-color-action-primary--rd-color-focus-ring--rd-radius-control