Skip to content
Updated May 2026Edit this page ↗

Layout Widgets

Layout widgets in @termuijs/widgets handle structural concerns — grouping, scrolling, centering, and status display.

Card

A bordered container with an optional title embedded in the top border:

TYPESCRIPT
import { Card } from '@termuijs/widgets'
import { Text } from '@termuijs/widgets'
 
const card = new Card({ flexGrow: 1 }, { title: 'System Status' })
card.addChild(new Text('CPU: 42%', {}))
card.addChild(new Text('MEM: 58%', {}))
OptionTypeDescription
titlestringText shown centered in the top border line
borderColorColorColor of the border and title text

Card always has border: 'single' and padding: 1 by default. Pass overrides in the style argument.

ScrollView

A vertically scrollable container. Content that overflows the height can be scrolled with arrow keys:

TYPESCRIPT
import { ScrollView } from '@termuijs/widgets'
 
const scroll = new ScrollView({ height: 20, flexGrow: 1 }, { scrollbar: true })
for (const line of logLines) {
    scroll.addChild(new Text(line, {}))
}
OptionTypeDefaultDescription
scrollbarbooleantrueShow a scrollbar on the right edge

Keyboard: / scroll one line; PageUp/PageDown scroll by half the visible height; Home/End jump to top/bottom.

Center

Centers a single child widget within its available space:

TYPESCRIPT
import { Center } from '@termuijs/widgets'
import { Text } from '@termuijs/widgets'
 
const centered = new Center({ flexGrow: 1 }, {})
centered.addChild(new Text('Loading...', { bold: true }))
OptionTypeDefaultDescription
axis'x' \| 'y' \| 'both''both'Which axes to center on

Columns

Evenly-split column layout from an array of widgets:

TYPESCRIPT
import { Columns } from '@termuijs/widgets'
 
const cols = new Columns({ flexGrow: 1 }, { gap: 1 })
cols.addChildren([cpuGauge, memGauge, diskGauge, netGauge])
OptionTypeDefaultDescription
gapnumber0Column gap in characters

Each child gets an equal share of the available width. For unequal columns, use the row intrinsic with explicit flexGrow values.

A navigable sidebar with items, optional badges, and active item highlighting:

TYPESCRIPT
import { Sidebar } from '@termuijs/widgets'
 
const sidebar = new Sidebar({ width: 20 }, {
    items: [
        { id: 'dashboard', label: 'Dashboard', badge: '3' },
        { id: 'logs',      label: 'Logs' },
        { id: 'settings',  label: 'Settings' },
    ],
    activeId: 'dashboard',
    onSelect: (id) => navigate(id),
})
OptionTypeDescription
itemsSidebarItem[]List of navigation items
activeIdstringID of the currently active item (highlighted)
onSelect(id: string) => voidCalled when an item is selected with Enter
collapsedbooleanShow only icons/initials (narrow mode)

SidebarItem: { id: string, label: string, badge?: string, icon?: string }

Keyboard: / to navigate, Enter to select.

KeyValue

Aligned key–value pairs, left-padded so all values line up in a column:

TYPESCRIPT
import { KeyValue } from '@termuijs/widgets'
 
const info = new KeyValue({ flexGrow: 1 }, {
    data: {
        'Node version': process.version,
        'Platform':     process.platform,
        'Arch':         process.arch,
        'PID':          String(process.pid),
    },
    separator: ' : ',
})
OptionTypeDefaultDescription
dataRecord<string, string>RequiredKey–value pairs to display
separatorstring' : 'String between key and value
keyColorColorColor for the key column
valueColorColorColor for the value column

Definition

Term + definition stacked pairs, like a glossary or CLI man-page style reference:

TYPESCRIPT
import { Definition } from '@termuijs/widgets'
 
const glossary = new Definition({ flexGrow: 1 }, {
    items: [
        { term: 'TUI', definition: 'Terminal User Interface — an interactive app that runs inside a terminal emulator.' },
        { term: 'Fiber', definition: 'Internal reconciler node tracking component state and hook calls.' },
    ],
})

Each term is rendered bold; the definition follows on the next line, indented.

A full-width alert with a title and optional body text:

TYPESCRIPT
import { Banner } from '@termuijs/widgets'
 
const alert = new Banner({ flexGrow: 1 }, {
    title: 'Deployment Failed',
    message: 'Build step exited with code 1. Check the logs for details.',
    variant: 'error',
})
OptionTypeDescription
titlestringBold header line
messagestringBody text (optional)
variant'info' \| 'success' \| 'warning' \| 'error'Sets border color

StatusMessage

Compact single-line status with an icon and a message:

TYPESCRIPT
import { StatusMessage } from '@termuijs/widgets'
 
const msg = new StatusMessage({ height: 1 }, {
    message: 'Connected to database',
    variant: 'success',
})

Icons: / [+] for success, / [x] for error, / [!] for warning, / [i] for info. ASCII fallbacks activate when NO_UNICODE=1.

See also