ink-ui

๐Ÿ“Š Table

Structured data grid that measures its own columns, wraps or truncates cells, and aligns them per column.

<Table> renders a structured data grid with bold, muted column headers. Columns size themselves to their content, shrink to fit the terminal when the table is too wide, and either wrap or truncate whatever still does not fit.

import { Table } from "@kud/ink-ui"
import type { Column } from "@kud/ink-ui"

๐Ÿ”ง Props

PropTypeDefaultDescription
dataT[]โ€”Array of row objects
columnsColumn<T>[]โ€”Column definitions (see below)
gapnumber2Characters between columns
maxWidthnumberterminal widthWidth the table shrinks to fit
headerColorstringcolors.mutedColour of the header row

The table is generic over the row type T, so column keys are checked against your data shape.

Column<T> shape

FieldTypeDefaultDescription
keykeyof T & stringโ€”Object key to read for this column
headerstringโ€”Column heading text
widthnumbermeasuredFixed character width โ€” never shrunk
minWidthnumber3Floor a measured column shrinks to
align"left" | "center" | "right""left"Horizontal alignment of header and cells
overflow"wrap" | "truncate""truncate"What happens to content wider than the column

Missing or nullish cell values render as an empty string.

๐Ÿ“ How columns are sized

A column without a width is measured: it takes the widest of its header and its cells, counting display columns, so wide glyphs and CJK text are not undercounted. A cell holding newlines is measured by its widest line.

If the measured columns plus their gaps come to more than maxWidth, the widest column gives up characters first, one at a time, until the table fits or every measured column has reached its minWidth. Columns you gave an explicit width are never touched โ€” an over-wide table you asked for stays over-wide rather than quietly disagreeing with you.

๐ŸŽจ Overflow and alignment

overflow: "wrap" wraps a cell inside its column and grows the row to suit; the neighbouring cells stay top-aligned beside it. The default, overflow: "truncate", keeps every row one line tall and ends a clipped cell with โ€ฆ.

align positions a cell within its column. A cell that wraps to the full column width has nowhere left to move, so alignment shows on cells that are narrower than their column.

๐Ÿ’ก Examples

A measured table โ€” no widths at all:

<Table
  columns={[
    { key: "name", header: "Name" },
    { key: "status", header: "Status" },
  ]}
  data={[
    { name: "api", status: "ok" },
    { name: "db", status: "degraded" },
  ]}
/>

A wide, wrapping column beside fixed ones:

<Table
  columns={[
    { key: "file", header: "File", width: 32 },
    { key: "program", header: "Program", overflow: "wrap" },
    { key: "source", header: "Source", align: "right" },
  ]}
  data={items}
/>

On this page