docs/components/text-table.mdx
docs/components/text-table.mdxBrowse 89 files
10,445 bytes
Token encoding: o200k_base
Snapshot ac753b4
title: TextTable description: Render styled, wrapping, and selectable tabular text skill: intents: [text-table, table, tabular-data, styled-cells, table-selection]
TextTable
TextTableRenderable lays out a two-dimensional array of styled text cells. Use Markdown when the table starts as Markdown source.
It supports intrinsic or full-width columns, constrained wrapping, independent borders, cell padding, and text selection.
Availability
| Field | Availability |
|---|---|
| Package | @opentui/core |
| Core renderable | TextTableRenderable |
| React | Unavailable |
| Solid | Unavailable |
| Status | Built-in Core renderable |
Basic usage
import { TextTableRenderable, bold, fg, type TextChunk, type TextTableContent } from "@opentui/core"
const cell = (text: string): TextChunk[] => [{ __isChunk: true, text }]
const content: TextTableContent = [
[[bold("Service")], [bold("Status")], [bold("Notes")]],
[cell("api"), [fg("#00d4aa")("OK")], cell("latency 28ms")],
[cell("worker"), [fg("#b8a0ff")("DEGRADED")], cell("queue depth: 124")],
]
const table = new TextTableRenderable(renderer, {
width: "100%",
wrapMode: "word",
columnWidthMode: "content",
borderStyle: "rounded",
content,
})
renderer.root.add(table)
Monochrome preview of the same table:
╭───────┬────────┬────────────────╮
│Service│Status │Notes │
├───────┼────────┼────────────────┤
│api │OK │latency 28ms │
├───────┼────────┼────────────────┤
│worker │DEGRADED│queue depth: 124│
╰───────┴────────┴────────────────╯
Content
The public content types are:
type TextTableCellContent = TextChunk[] | null | undefined
type TextTableContent = TextTableCellContent[][]
Use styled-text helpers such as bold(), fg(), and bg() to build each cell's TextChunk[]. null, undefined, and missing cells render as empty text. Rows can have different lengths. The table uses the longest row's column count and fills missing cells with empty content.
The first row has no special behavior. Styling it as a header is a convention. TextTable has no header option or separate header model.
Replace the table data through the content setter:
table.content = [
[[bold("Name")], [bold("State")]],
[cell("worker-1"), [fg("#22c55e")("ready")]],
]
Column sizing and wrapping
columnWidthMode controls what happens when the available width exceeds the content's intrinsic width:
"full"expands columns evenly to fill the width constraint. This is the default."content"keeps the table at its intrinsic width when additional space is available.
When content is wider than a finite width constraint, wrapMode: "word" or "char" allows the table to shrink columns and grow rows. wrapMode: "none" preserves intrinsic column widths instead of shrinking over-wide content.
columnFitter chooses how constrained width is distributed:
"proportional"preserves more width for intrinsically wider columns. This is the default."balanced"keeps constrained columns closer to an even visual width while respecting their intrinsic sizes.
const table = new TextTableRenderable(renderer, {
width: 50,
wrapMode: "word",
columnWidthMode: "full",
columnFitter: "balanced",
content,
})
Borders and spacing
border controls separators between cells. outerBorder controls the boundary around the table. When omitted, outerBorder follows the initial border value and later assignments. Assigning a different outerBorder value makes it independent. Assigning its current value is a no-op and keeps that relationship unchanged.
// Outer border without inner cell separators
const table = new TextTableRenderable(renderer, {
border: false,
outerBorder: true,
content,
})
showBorders: false suppresses border glyph painting without removing the space reserved by enabled inner or outer borders. columnGap adds space between columns only when inner vertical borders are disabled.
cellPadding sets both axes. cellPaddingX and cellPaddingY override that value per axis. OpenTUI floors padding and gap values and clamps them to zero. Non-finite values use the default 0.
Selection
Selection starts only within cell content, not on border glyphs. Selection within one cell can be partial. A vertical drag in the anchor column selects that column. Moving into another column changes to grid selection.
getSelectedText() joins nonempty selected cells in a row with tabs. It joins selected rows with newlines and excludes
table borders. A selected blank cell does not add an empty tab field.
renderer.on("selection", () => {
console.log(table.getSelectedText())
})
Selection-related methods are:
| Method | Result |
|---|---|
shouldStartSelection(x, y) | Whether the global position is selectable cell content |
onSelectionChanged(selection) | Applies a renderer selection and reports whether text is selected |
hasSelection() | Whether any cell has a selection |
getSelection() | The first selected cell's { start, end } range, or null |
getSelectedText() | Tab/newline-delimited nonempty selected cell text |
Options
TextTable also accepts the standard renderable layout options.
| Option | Type | Default | Description |
|---|---|---|---|
content | TextTableContent | [] | Rows of styled cell chunks |
wrapMode | "none" | "char" | "word" | "word" | Cell text wrapping behavior |
columnWidthMode | "content" | "full" | "full" | Preserve intrinsic width or fill the width constraint |
columnFitter | "proportional" | "balanced" | "proportional" | Width allocation when columns must shrink |
cellPadding | number | 0 | Horizontal and vertical padding on each side of a cell |
cellPaddingX | number | cellPadding | Horizontal padding on each side |
cellPaddingY | number | cellPadding | Vertical padding on each side |
columnGap | number | 0 | Gap between columns when inner vertical borders are off |
showBorders | boolean | true | Paint enabled border glyphs |
border | boolean | true | Enable inner row and column separators |
outerBorder | boolean | border | Enable the table boundary |
borderStyle | "single" | "double" | "rounded" | "heavy" | "single" | Border glyph set |
borderColor | ColorInput | "#FFFFFF" | Border foreground color |
borderBackgroundColor | ColorInput | "transparent" | Border background color |
backgroundColor | ColorInput | "transparent" | Buffered table surface background |
fg | ColorInput | "#FFFFFF" | Default cell text foreground |
bg | ColorInput | "transparent" | Default cell text background |
attributes | number | 0 | Default text attribute bitmask |
selectable | boolean | true | Allow cell text selection |
selectionBg | ColorInput | - | Selection background override |
selectionFg | ColorInput | - | Selection foreground override |
flexShrink | number | 0 | Inherited layout shrink factor |
The renderable always uses a buffered surface. The mutable table-specific properties are content, wrapMode, columnWidthMode, columnFitter, cellPadding, cellPaddingX, cellPaddingY, columnGap, showBorders, border, outerBorder, borderStyle, and borderColor.
Related components
Use Markdown for document tables. Use Code for syntax-highlighted source and Diff for patches. Line number gutter applies to line-aware content instead of table rows.