Orbit
Text
Source
Variant-driven typography for anything text-related.
Overview
Use Text for any text node, never a div with tailwind text classes. You choose what the text is; the component decides how it looks.
Each prop sits on one axis. variant is the role (size, weight and font family), color is the tone, and as is the element. Orthogonal modifiers layer on without touching the role: monospace, tabularNums, truncate, lineThrough and a formatter for numbers. Colors resolve light and dark automatically, and loading renders a skeleton with no extra markup.
Text has no className. Size, weight, color and leading are owned by the props above, so compose layout and spacing with Box around Text rather than reaching for utility classes.
Variants
Each variant maps to a typographic role. The token name is shown in monospace above each sample.
heading-2xl
The quick brown fox
heading-xl
The quick brown fox
heading-l
The quick brown fox
heading-m
The quick brown fox
heading-s
The quick brown fox
heading-xs
The quick brown fox
heading-xxs
The quick brown fox
body
The quick brown fox
default
The quick brown fox
label
The quick brown fox
caption
The quick brown fox
<Text variant="heading-l">Page title</Text>
<Text variant="body">Comfortable reading copy.</Text>
<Text variant="label">Field label</Text>
Monospace
monospace is a boolean prop, not a variant. It swaps in the mono font family while keeping the size and weight from variant, so any text (a heading, body copy or a label) can be monospaced.
variant="heading-s" monospace
npm install @polar-sh/orbit
variant="body" monospace
npm install @polar-sh/orbit
variant="default" monospace
npm install @polar-sh/orbit
variant="label" monospace
npm install @polar-sh/orbit
<Text variant="heading-s" monospace>404</Text>
<Text variant="body" monospace>npm install @polar-sh/orbit</Text>
<Text variant="label" monospace>POLAR_TOKEN</Text>
Formatting
Pass a raw value as children and a formatter to render it: 'number' for grouping separators, 'compact' for short magnitudes, or a function for anything else. Formatting lives in the component, so call sites never hand-roll toLocaleString. Add tabularNums to align figures in columns.
3290033
3,290,033
3.3M
48200
48,200
48K
1500
1,500
1.5K
42
42
42
<Text variant="heading-s" formatter="number">{3290033}</Text>
<Text variant="body" formatter="compact">{3290033}</Text>
<Text formatter={(v) => `$${v}`}>{42}</Text>Truncation
truncate owns the overflow CSS: true clamps to one line, a number clamps to that many lines.
truncate
Orbit is the Polar design system: tokens, primitives and components for building product interfaces quickly and consistently.
truncate={2}
<Text variant="body" truncate>One line, then an ellipsis…</Text>
<Text variant="body" truncate={2}>Clamped to two lines…</Text>Colors
Color tokens auto-resolve for light and dark mode. inverse is shown on an inverse surface.
default
Sample text in this color
muted
Sample text in this color
disabled
Sample text in this color
accent
Sample text in this color
success
Sample text in this color
warning
Sample text in this color
danger
Sample text in this color
inverse
Sample text in this color
<Text color="default">De-emphasised copy</Text>
<Text color="accent">Accent</Text>
<Text color="success">Saved</Text>
<Text color="danger">Something went wrong</Text>
States
loading renders a skeleton, single or multi-line. lineThrough strikes the content.
loading
loading, placeholderNumberOfLines=3
lineThrough
Previous price
<Text loading placeholderText="Loading a single line of text" />
<Text loading placeholderNumberOfLines={3} />
<Text lineThrough color="default">Previous price</Text>Best practices
Keep typographic decisions inside Text. Choose the role and tone; let the component own the rest.
Do
✓
Pick a variant for the role (body, label, heading-l), never a raw font size.
✓
Set as on headings so the document outline is correct; the visual size and the heading level are independent.
✓
Use color="inherit" to adopt a parent Box color, for example to animate hover and active states.
✓
Pass raw numbers as children with a formatter, and add tabularNums when figures sit in a column.
✓
Compose layout and spacing with Box around Text.
✓
For truncation that reveals the full text in a tooltip on hover, use the Truncated component; use truncate for plain clamping.
Avoid
✗
Do not reach for a class to set size, weight, color or leading. Text owns typography and has no className prop.
✗
Do not encode hierarchy with size alone. An h2 can use any heading variant.
✗
Do not pre-format numbers with toLocaleString. Let formatter do it so output stays consistent and SSR safe.
✗
Do not nest layout containers inside Text. Keep children to text and inline content.
✗
Do not use a heading variant for non-heading emphasis. Reach for the right variant, monospace or a color token.
Props
default | body | label | caption | heading-2xl | heading-xl | heading-l | heading-m | heading-s | heading-xs | heading-xxs.
Renders the text in the monospace font family while keeping the size and weight from variant. Pair with any variant.
formatter
TextFormatterFormats the children value for display. 'number' adds grouping separators (3,290,033), 'compact' shortens (3.3M), or pass a function for full control. Pass the raw value as children.
Uses tabular (monospaced) figures so numbers line up in columns. Ideal for tables and stat readouts.
true clamps to a single line with an ellipsis; a number clamps to that many lines.
default | muted | disabled | accent | danger | error | warning | success | inverse | white | black | inherit.
Underlying element. Defaults to a sensible element per variant (heading variants render h1 to h6, everything else p). Override for the correct document outline. DOM props are forwarded.
align
TextAlignText alignment.
wrap
TextWrapWrapping behavior.
Render a pulsing skeleton placeholder instead of children.
placeholderText
stringSizes the single-line skeleton. Falls back to children, then Loading...
When greater than 1, renders a multi-line skeleton.
Applies a line-through text decoration.