termino

TextTable

Lays out a two-dimensional array of styled text cells. Supports intrinsic or full-width columns, constrained wrapping, independent inner and outer borders, cell padding, and text selection.

~/components/text-table
live
$ termino table-demo
────────────────────────────────────────────
pkg version stars runtime
────────────────────────────────────────────
opentui/core 0.4.5 3.2k zig
opentui/react 0.4.5 1.8k react
opentui/solid 0.4.5 1.1k solid
opentui/three 0.4.5 412 webgpu
────────────────────────────────────────────
TextTable auto-sizes columns to content

TextTable currently has an imperative renderable API. It is not registered as a built-in React or Solid component.

##Basic usage

tsrenderable
1import { TextTableRenderable, bold, fg, type TextChunk, type TextTableContent } from "@opentui/core"
2
3const cell = (text: string): TextChunk[] => [{ __isChunk: true, text }]
4
5const content: TextTableContent = [
6[[bold("Service")], [bold("Status")], [bold("Notes")]],
7[cell("api"), [fg("#00d4aa")("OK")], cell("latency 28ms")],
8[cell("worker"), [fg("#b8a0ff")("DEGRADED")], cell("queue depth: 124")],
9]
10
11const table = new TextTableRenderable(renderer, {
12width: "100%",
13wrapMode: "word",
14columnWidthMode: "content",
15borderStyle: "rounded",
16content,
17})
18
19renderer.root.add(table)

##Content

Cell content is styled-text chunks. null, undefined, and missing cells render as empty text. Rows may have different lengths — the table uses the longest row's column count and fills missing cells with empty content.

ts
1type TextTableCellContent = TextChunk[] | null | undefined
2type TextTableContent = TextTableCellContent[][]

The first row has no special behavior. Styling it as a header is a convention — TextTable has no header option.

Replace data at runtime:

ts
1table.content = [
2[[bold("Name")], [bold("State")]],
3[cell("worker-1"), [fg("#22c55e")("ready")]],
4]

##Column sizing

  • columnWidthMode: "full" — expand columns evenly to fill the width constraint (default)
  • columnWidthMode: "content" — keep the table at intrinsic width
  • columnFitter: "proportional" — preserve width for intrinsically wider columns (default)
  • columnFitter: "balanced" — keep constrained columns closer to even width
  • wrapMode: "word" | "char" — shrink columns and grow rows when content is wider than the constraint

##Borders and spacing

ts
1// Outer border without inner cell separators
2const table = new TextTableRenderable(renderer, {
3border: false,
4outerBorder: true,
5content,
6})
7
8// Gap between columns when inner vertical borders are off
9{
10border: false,
11columnGap: 2,
12}
13
14// Padding per cell
15{
16cellPadding: 1,
17cellPaddingX: 2, // override per axis
18cellPaddingY: 1,
19}

showBorders: false suppresses border glyph painting without removing the space reserved by enabled borders.

##Selection

Selection starts only within cell content. A vertical drag that stays in the anchor column selects that column; moving into another column switches to grid selection.

ts
1renderer.on("selection", () => {
2console.log(table.getSelectedText())
3})
4
5table.shouldStartSelection(x, y) // is the position selectable?
6table.hasSelection()
7table.getSelection() // first cell's { start, end } or null

##Options

properties
proptypedefaultdescription
contentTextTableContent[]-Rows of styled cell chunks
wrapMode"none" | "char" | "word""word"Cell text wrapping behavior
columnWidthMode"content" | "full""full"Preserve intrinsic width or fill constraint
columnFitter"proportional" | "balanced""proportional"Width allocation when columns must shrink
cellPaddingnumber0Padding on each side of a cell
cellPaddingX / cellPaddingYnumbercellPaddingPer-axis padding
columnGapnumber0Gap between columns when inner vertical borders are off
showBordersbooleantruePaint enabled border glyphs
borderbooleantrueEnable inner row and column separators
outerBorderbooleanborderEnable the table boundary
borderStyle"single" | "double" | "rounded" | "heavy""single"Border glyph set
borderColorColorInput"#FFFFFF"Border foreground color
backgroundColorColorInputtransparentBuffered table surface background
fg / bgColorInput"#FFFFFF" / transparentDefault cell text colors
selectablebooleantrueAllow cell text selection