UNPKG

@nadle/ink-table

Version:
105 lines 3.92 kB
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; import { Box, Text } from "ink"; import { sha1 } from "object-hash"; /* Components */ export function Table({ data, columns, padding = 1, cell = Cell, header = Header, skeleton = Skeleton }) { const allColumns = columns || Array.from(new Set(data.flatMap((row) => Object.keys(row)))); const columnMeta = allColumns.map((key) => { const maxContentWidth = Math.max(String(key).length, ...data.map((row) => String(row[key] ?? "").length)); return { column: key, key: String(key), width: maxContentWidth + padding * 2 }; }); const headings = Object.fromEntries(allColumns.map((col) => [col, col])); const RowHeader = row({ padding, cell: skeleton, skeleton: { line: "─", left: "┌", right: "┐", cross: "┬", component: skeleton } }); const RowHeading = row({ padding, cell: header, skeleton: { line: " ", left: "│", right: "│", cross: "│", component: skeleton } }); const RowSeparator = row({ padding, cell: skeleton, skeleton: { line: "─", left: "├", right: "┤", cross: "┼", component: skeleton } }); const RowData = row({ cell, padding, skeleton: { line: " ", left: "│", right: "│", cross: "│", component: skeleton } }); const RowFooter = row({ padding, cell: skeleton, skeleton: { line: "─", left: "└", right: "┘", cross: "┴", component: skeleton } }); return (_jsxs(Box, { flexDirection: "column", children: [RowHeader({ data: {}, key: "header", columns: columnMeta }), RowHeading({ data: headings, key: "heading", columns: columnMeta }), data.map((row, index) => { const key = `row-${sha1(row)}-${index}`; return (_jsxs(Box, { flexDirection: "column", children: [RowSeparator({ data: {}, key: `sep-${key}`, columns: columnMeta }), RowData({ data: row, key: `data-${key}`, columns: columnMeta })] }, key)); }), RowFooter({ data: {}, key: "footer", columns: columnMeta })] })); } /* Helper components */ export function Header(props) { return (_jsx(Text, { bold: true, color: "blue", children: props.children })); } export function Cell(props) { return _jsx(Text, { children: props.children }); } export function Skeleton(props) { return _jsx(Text, { bold: true, children: props.children }); } function row(config) { const skeleton = config.skeleton; return ({ key, data, columns }) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(skeleton.component, { children: skeleton.left }), ...intersperse((i) => _jsx(skeleton.component, { children: skeleton.cross }, `${key}-sep-${i}`), columns.map((column, i) => { const value = data[column.column]; const content = value == null ? "" : String(value); const leftPad = config.padding; const rightPad = column.width - content.length - leftPad; return (_jsx(config.cell, { column: i, children: `${skeleton.line.repeat(leftPad)}${content}${skeleton.line.repeat(rightPad)}` }, `${key}-col-${column.key}`)); })), _jsx(skeleton.component, { children: skeleton.right })] }, key)); } /* Util */ function intersperse(intersperser, elements) { return elements.reduce((acc, el, idx) => { if (idx === 0) { return [el]; } return [...acc, intersperser(idx), el]; }, []); } //# sourceMappingURL=index.js.map