Text and display
Contents
- Use typography primitives for styled text
- Text.Sans vs Text.Heading vs Text.Mono
- InlineCode vs CopyableCode vs CodeBlock
- Markdown and DescriptionList
- Avatar
- FilePreview vs file-list parts
- Kbd
- Icons
Use typography primitives for styled text
Use the Text namespace when standalone copy needs raft-ui typography. Keep native text elements when their semantics and inherited styles are intentional.
Incorrect:
<p className="text-sm text-gray-500">Last synced 2 minutes ago</p>Correct:
<Text.Sans size="small">Last synced 2 minutes ago</Text.Sans>Text.Sans vs Text.Heading vs Text.Mono
| Component | For |
|---|---|
Text.Sans | body copy, labels, and descriptions |
Text.Heading | section and page headings; level is 1 through 6 |
Text.Mono | code-like values, metadata, and tabular numbers |
Prefer the namespace used by the canonical compositions.
Text.Sans sizes — large body small caption.
Text.Mono sizes — code meta eyebrow tabular.
Use Text.Mono size="tabular" for numbers that update in place — counts, timers, file sizes, and percentages. Proportional digits can change width and make the surrounding layout jitter.
<Text.Mono size="tabular">{unreadCount}</Text.Mono>Use size="meta" for timestamps and IDs, size="eyebrow" for the small label above a section.
Text.Heading level selects both the heading element and its recipe size. Pick it from document structure. Use render only when the surrounding document requires a different element.
InlineCode vs CopyableCode vs CodeBlock
| Use | |
|---|---|
InlineCode | a token inside a sentence — a prop name, a flag, a key |
CopyableCode | a single-line command the user is meant to run or paste |
CodeBlock | multi-line code on display |
If the user's next move is to select the text, it should have been CopyableCode or CodeBlock.
<CopyableCodeRoot>
<CopyableCode truncate>{command}</CopyableCode>
<CopyableCodeAction aria-label="Copy install command" />
</CopyableCodeRoot>CopyableCodeRoot sizes are sm and md. Use truncate on CopyableCode for long single-line commands, and give CopyableCodeAction an aria-label that says what is being copied. When you omit it, the label swaps between Copy code and Copied code.
Compose a titled block with CodeBlockHeader, CodeBlockTitle, CodeBlockActions, and CodeBlockAction above CodeBlockBody. In a block without a header, place CodeBlockActions inside CodeBlockBody. Render the complete <pre><code>…</code></pre> as body content.
Markdown and DescriptionList
Rendered markdown is styled by the Markdown* part set. Map paragraphs, headings, lists, links, blockquotes, inline code (MarkdownInlineCode; fenced code is CodeBlock), tables, images, task checkboxes, rules, and marks to the matching exported parts. Wrap wide tables in MarkdownTableScroll, and compose MarkdownTable, MarkdownTableRow, MarkdownHeaderCell, and MarkdownCell.
DescriptionList renders term/value pairs. Wrap DescriptionTerm and DescriptionDetails in DescriptionItem, and set direction="horizontal" or direction="vertical".
Avatar
<Avatar type="human" size="sm">
<AvatarImage src={user.avatarUrl} />
<AvatarFallback>{initials}</AvatarFallback>
</Avatar>- Pass the required
typeandsizeprops.typeisagentorhuman; it picks the placeholder fill. - Sizes are
3xs2xsxssmmdlgxl. - Include
AvatarFallbackwhenever you includeAvatarImage. WhenAvatarhas no children, it renders its built-in fallback automatically. - Use
AvatarGroupandAvatarGroupCountfor stacks. Pass the required avatarsizetoAvatarGroupCount. AvatarBadgefor a presence dot attached to the avatar. For a standalone state dot elsewhere, useStatus.
FilePreview vs file-list parts
FilePreview renders one file as a tile. It has dedicated shapes rather than a type prop:
| Shape | For |
|---|---|
FilePreviewMedia | images and video |
FilePreviewDocument | PDFs and documents |
FilePreviewCode | source files |
FilePreviewFile | anything else |
Pick the shape by what the file is. FilePreviewBadge labels the format.
The file-list parts render a list surface: FilesPanel, FilesViewport, FilesList, and per-row FileRow, FileThumbnail, FileContent, FileName, FileMeta, FileMetaItem, FileActions, FileAction, FileRowOpen, FileImage. There is no Files root component.
Use FilePreview for attachments inside a composer or message; compose the file-list parts for a browsable list.
Kbd
<KbdGroup aria-label="Command K">
<Kbd>⌘</Kbd>
<Kbd>K</Kbd>
</KbdGroup>Render one key per Kbd. Use KbdGroup to apply spacing to a key combination. Add any visible separator as explicit content when the shortcut notation requires one.
Icons
Raft-ui's internal recipes and canonical compositions are tuned to Lucide SVGs, but raft-ui does not re-export Lucide; it exports only the conversation icons MessageIcon, ChatIcon, DirectMessageIcon, and ThreadIcon. When application code imports Lucide icons, declare lucide-react as a direct application dependency rather than relying on raft-ui's transitive dependency. A consumer may provide another SVG icon set when it preserves the component's expected sizing and stroke treatment.
Let raft-ui components own their icons' default treatment. Buttons, menu items, sidebar items, toasts, and tabs apply recipe-specific sizing and sometimes stroke widths. Override those values only when the component's API or a deliberate one-off treatment requires it.
Incorrect:
<Button size="icon-sm">
<SearchIcon className="size-4 stroke-2" />
</Button>Correct:
<Button size="icon-sm">
<SearchIcon />
</Button>In your own markup — outside any icon-owning component — size icons explicitly (className="size-4").