Overview
TextTableRenderable renders tabular data with customizable borders, wrapping modes, and column sizing strategies. It supports text selection across cells, multiple border styles, and handles complex content including styled text and Unicode characters.
Basic Usage
import { TextTableRenderable, createCliRenderer } from '@opentui/core'
const renderer = await createCliRenderer()
const table = new TextTableRenderable(renderer, {
content: [
[[{ __isChunk: true, text: 'Name' }], [{ __isChunk: true, text: 'Status' }]],
[[{ __isChunk: true, text: 'API' }], [{ __isChunk: true, text: 'OK' }]],
[[{ __isChunk: true, text: 'Worker' }], [{ __isChunk: true, text: 'ERROR' }]],
],
wrapMode: 'word',
borderStyle: 'single',
})
renderer.root.add(table)
With Styled Content
import { TextTableRenderable, bold, fg } from '@opentui/core'
const table = new TextTableRenderable(renderer, {
content: [
[[bold('Service')], [bold('Status')], [bold('Latency')]],
[
[{ __isChunk: true, text: 'api' }],
[fg('#00d4aa')('OK')],
[{ __isChunk: true, text: '28ms' }],
],
[
[{ __isChunk: true, text: 'worker' }],
[fg('#b8a0ff')('DEGRADED')],
[{ __isChunk: true, text: '124ms' }],
],
[
[{ __isChunk: true, text: 'billing' }],
[fg('#ffffff')('ERROR')],
[{ __isChunk: true, text: 'timeout' }],
],
],
borderStyle: 'rounded',
borderColor: '#2a2a2a',
fg: '#f0f0f0',
cellPadding: 1,
})
Full Width Table
const table = new TextTableRenderable(renderer, {
content: [
[[{ __isChunk: true, text: 'Region' }], [{ __isChunk: true, text: 'Requests' }]],
[[{ __isChunk: true, text: 'us-east-1' }], [{ __isChunk: true, text: '1.2M' }]],
[[{ __isChunk: true, text: 'eu-west-1' }], [{ __isChunk: true, text: '890K' }]],
],
width: '100%',
columnWidthMode: 'full', // Expand columns to fill available width
wrapMode: 'word',
})
Text Wrapping
// Long content that wraps within cells
const table = new TextTableRenderable(renderer, {
content: [
[
[{ __isChunk: true, text: 'Task' }],
[{ __isChunk: true, text: 'Description' }],
],
[
[{ __isChunk: true, text: 'Migration' }],
[{ __isChunk: true, text: 'Migrate all production databases to the new infrastructure with zero downtime and full data validation' }],
],
],
wrapMode: 'word', // 'none' | 'word' | 'char'
columnFitter: 'balanced', // Better distribution for wrapped content
})
Border Styles
// Different border configurations
const doubleBorder = new TextTableRenderable(renderer, {
content: data,
borderStyle: 'double',
border: true,
outerBorder: true,
})
const innerOnly = new TextTableRenderable(renderer, {
content: data,
border: true,
outerBorder: false, // Only show borders between cells
})
const noBorders = new TextTableRenderable(renderer, {
content: data,
showBorders: false, // Hide all borders while preserving layout
})
Unicode and CJK Support
const unicodeTable = new TextTableRenderable(renderer, {
content: [
[[{ __isChunk: true, text: 'Locale' }], [{ __isChunk: true, text: 'Sample' }]],
[[{ __isChunk: true, text: 'ja-JP' }], [{ __isChunk: true, text: '東京の夜景と絵文字 🌃✨' }]],
[[{ __isChunk: true, text: 'zh-CN' }], [{ __isChunk: true, text: '你好世界,布局检查中 🚀' }]],
[[{ __isChunk: true, text: 'ko-KR' }], [{ __isChunk: true, text: '한글과 이모지 조합 테스트 😄' }]],
],
wrapMode: 'char', // Better for CJK text
})
Props
content
TextTableContent
default:"[]"
Table data as a 2D array of cell content. Each cell contains TextChunk[] or null/undefined.type TextTableContent = TextTableCellContent[][]
type TextTableCellContent = TextChunk[] | null | undefined
wrapMode
'none' | 'char' | 'word'
default:"'word'"
Text wrapping behavior within cells:
'none': No wrapping, content may overflow
'word': Wrap at word boundaries
'char': Wrap at any character (better for CJK)
columnWidthMode
'content' | 'full'
default:"'full'"
Column sizing strategy:
'content': Columns sized to fit content
'full': Columns expand to fill available width
columnFitter
'proportional' | 'balanced'
default:"'proportional'"
Algorithm for shrinking columns when content exceeds available width:
'proportional': Shrink proportionally to intrinsic width
'balanced': More even distribution using sqrt-based weighting
Padding around cell content (applied to all sides). Minimum value is 0.
Whether to draw borders. When false, borders are hidden but layout remains the same.
Whether to show inner borders between cells.
Whether to show the outer border around the entire table.
borderStyle
BorderStyle
default:"'single'"
Border drawing style: 'single' | 'rounded' | 'double' | 'heavy'
borderColor
ColorInput
default:"'#FFFFFF'"
Color of the border lines. Accepts hex colors, RGB objects, or color names.
borderBackgroundColor
ColorInput
default:"'transparent'"
Background color behind borders.
backgroundColor
ColorInput
default:"'transparent'"
Background color for the entire table.
fg
ColorInput
default:"'#FFFFFF'"
Default text color for cell content.
bg
ColorInput
default:"'transparent'"
Default background color for cell content.
Default text attributes (bold, italic, etc.) as a bitmask.
Whether table content can be selected with mouse drag.
Background color for selected text.
Foreground color for selected text.
Methods
content
Get or set the table content.
table.content = newData
const currentData = table.content
wrapMode
Get or set the text wrapping mode.
columnWidthMode
Get or set the column width mode.
table.columnWidthMode = 'content'
columnFitter
Get or set the column fitting algorithm.
table.columnFitter = 'balanced'
cellPadding
Get or set the cell padding.
showBorders
Get or set border visibility.
table.showBorders = false
border
Get or set inner border display.
outerBorder
Get or set outer border display.
borderStyle
Get or set the border style.
table.borderStyle = 'double'
borderColor
Get or set the border color.
table.borderColor = '#2a2a2a'
getSelectedText()
Get the currently selected text from the table. Returns tab-separated columns and newline-separated rows.
const selected = table.getSelectedText()
// Example output: "api\tOK\t28ms\nworker\tDEGRADED\t124ms"
Selection Support
TextTableRenderable supports three selection modes:
- single-cell: Selection within one cell
- column-locked: Selection across rows in the same column
- grid: Free selection across any cells
renderer.on('selection', (selection) => {
const selectedText = table.getSelectedText()
console.log('Selected:', selectedText)
})
// Clear selection
renderer.clearSelection()
Common Patterns
Dynamic Data Updates
function updateTableData(newData: TextTableContent) {
table.content = newData
// Table automatically recalculates layout and re-renders
}
setInterval(() => {
updateTableData(fetchLatestData())
}, 1000)
Responsive Width
const table = new TextTableRenderable(renderer, {
content: data,
width: '100%', // Fill parent width
columnWidthMode: 'full',
wrapMode: 'word',
flexGrow: 1, // Grow with parent
})
Status Dashboard
const statusTable = new TextTableRenderable(renderer, {
content: [
[[bold('Service')], [bold('Status')], [bold('Uptime')]],
...services.map(s => [
[{ __isChunk: true, text: s.name }],
[fg(s.healthy ? '#00ff00' : '#ff0000')(s.status)],
[{ __isChunk: true, text: s.uptime }],
]),
],
borderStyle: 'rounded',
cellPadding: 1,
width: '100%',
})
- Tables efficiently handle cell content changes by only rebuilding modified cells
- Layout computation is cached and only recalculated when dimensions or content change
- Large tables with wrapping enabled may require more computation for layout
- Use
columnWidthMode: 'content' for better performance with fixed-width content
- Box - Container for tables
- ScrollBox - Scrollable container for large tables
- Text - For styled text content in cells