Skip to content

Text ​

The primitive for rendering text content. Supports styling (colors, bold, italic, etc.), text wrapping/truncation modes, and nested Text elements for inline style changes.

Import ​

tsx
import { Text } from "silvery"

Props ​

TextProps extends StyleProps, TestProps, and MouseEventProps.

PropTypeDefaultDescription
childrenReactNode--Text content (string, number, or nested Text elements)
colorstring--Foreground color (name, hex, or $token)
backgroundColorstring--Background color
boldboolean--Bold text
dimboolean--Dim text
dimColorboolean--Dim text (alias, Ink compatibility)
italicboolean--Italic text
underlineboolean--Enable underline
underlineStyle"single" | "double" | "curly" | "dotted" | "dashed" | false--Underline style variant
underlineColorstring--Underline color
strikethroughboolean--Strikethrough text
inverseboolean--Inverse (swap fg/bg)
wrap"wrap" | "wrap-truncate" | "truncate" | "truncate-start" | "truncate-middle" | "truncate-end" | "clip" | boolean"wrap"Text wrapping/truncation mode

Ref: TextHandle ​

ts
interface TextHandle {
  getNode(): AgNode | null
}

Usage ​

tsx
// Basic text
<Text>Hello, world!</Text>

// Colored text
<Text color="green">Success!</Text>
<Text color="#ff6600">Orange text</Text>

// Styled text
<Text bold>Important</Text>
<Text italic underline>Emphasized</Text>

// Combined styles
<Text color="red" bold inverse>Alert!</Text>

// Nested text with different styles
<Text>
  Normal <Text bold>bold</Text> normal
</Text>

// Truncation modes
<Text wrap="truncate">This long text will be truncated...</Text>
<Text wrap="truncate-middle">Long...text</Text>

// Semantic theme colors (Sterling)
<Text color="$fg-accent">Brand emphasis</Text>
<Text color="$fg-muted">Secondary info</Text>

Wrap modes — what each one does ​

wrap is the only knob today. Each mode bundles three CSS-equivalent axes (white-space, overflow-wrap, text-overflow) into one named composite. The CSS column is the canonical reference for what each mode actually does — useful when porting from web/Polaris and when reasoning about the upcoming canvas/DOM targets (silvery is a multi-target framework; the modes are designed to map cleanly).

wrap=BehaviorCSS-equivalent axes
"wrap" (default)Multi-line word wrap. Breaks at word boundaries (space, hyphen). Falls back to soft-break separators (/, \, ., _, :, ,) for long path-style tokens. Last-resort character wrap when no separator fits.white-space: normal + overflow-wrap: break-word
"wrap-truncate"Multi-line word wrap with ellipsis fallback. Same as "wrap" but when an unbreakable atomic token (no soft-break separators) would otherwise character-wrap, the offending line ends with … and the rest of that token is dropped. Subsequent text continues wrapping from the next word boundary. Use for body text where information loss is preferable to mid-token character wrapping (e.g. card bodies that contain occasional long identifiers).white-space: normal + overflow-wrap: break-word + text-overflow: ellipsis
"truncate"Single-line. Trims at end with … ellipsis when content exceeds available width.white-space: nowrap + overflow: hidden + text-overflow: ellipsis
"truncate-end"Alias of "truncate" — explicit "trim at end".white-space: nowrap + overflow: hidden + text-overflow: ellipsis
"truncate-start"Single-line. Trims at start with … prefix.(no direct CSS analogue; named composite — equivalent to direction: rtl + text-overflow: ellipsis)
"truncate-middle"Single-line. Trims in the middle (e.g. path/to/.../file.md). Useful for long paths where both ends matter.(no direct CSS analogue; named composite)
"clip"Single-line. Hard clips at right edge without ellipsis. Use only when the truncation marker would itself be misleading (e.g. tabular cells).white-space: nowrap + overflow: hidden + text-overflow: clip
falseNo wrapping, no clipping. Text overflows its container. Avoid in bordered cells; use "wrap" or "truncate" instead.white-space: nowrap + overflow: visible

Picking a mode ​

  • Body text (paragraphs, descriptions, list items) → "wrap" (default).
  • Bordered card bodies that may contain occasional long identifiers (UUIDs, hashes, paste-bin output) → "wrap-truncate". Wraps prose normally, ellipsis-truncates atomic tokens that would otherwise character-wrap and look like garbled text.
  • Titles and labels in fixed-width chrome (status bars, table headers, card titles) → "truncate".
  • File paths that need both ends visible → "truncate-middle".
  • Numeric or tabular cells where … would be confused with content → "clip".
  • Never wrap={false} inside a bordered Box — it produces the "text painted past border" failure shape that selected backgrounds amplify.

Soft-break separators in "wrap" mode ​

Long path-style or identifier tokens like .claude/skills/{claim,do}/SKILL.md are unbreakable from a pure word-boundary perspective. "wrap" breaks them at the SECONDARY break points /, \, ., _, :, , (after the separator) — path/ ends one line, to starts the next. Brackets and parens ({ } [ ] ( )) are not soft breaks — paired delimiters shouldn't be orphaned, matching CSS behavior.

For atomic tokens with no separators (e.g. aaaaaaaaaaaaaaaaaaaa), "wrap" falls back to character wrap (the token spans multiple lines). If you'd prefer … truncation in that case, use "wrap-truncate": the wrap algorithm is the same, but when an unbreakable token would otherwise character-wrap, the offending line ends with … and the rest of that token is dropped. Subsequent text after the next word boundary continues wrapping normally — only the offending atomic run is truncated, not the entire text.

See Also ​

  • Box -- layout container
  • Typography -- semantic text presets (H1, H2, P, etc.)