@tooee/renderers 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ import type { ColumnDef, TableRow } from "./table-types.js";
2
+ export interface TableProps {
3
+ columns: ColumnDef[];
4
+ rows: TableRow[];
5
+ /** Maximum width for the table. If not provided, uses terminal width. */
6
+ maxWidth?: number;
7
+ /** Minimum width for any column (default: 4) */
8
+ minColumnWidth?: number;
9
+ /** Maximum width for any column (default: 50) */
10
+ maxColumnWidth?: number;
11
+ /** Number of rows to sample for width calculation (default: 100) */
12
+ sampleSize?: number;
13
+ cursor?: number;
14
+ selectionStart?: number;
15
+ selectionEnd?: number;
16
+ matchingRows?: Set<number>;
17
+ currentMatchRow?: number;
18
+ toggledRows?: Set<number>;
19
+ }
20
+ declare function isNumeric(value: string): boolean;
21
+ interface ColumnWidthOptions {
22
+ minColumnWidth: number;
23
+ maxColumnWidth: number;
24
+ sampleSize: number;
25
+ }
26
+ declare function sampleRows(rows: string[][], sampleSize: number): string[][];
27
+ declare function computeColumnWidths(headers: string[], rows: string[][], maxWidth: number, options: ColumnWidthOptions): number[];
28
+ declare function truncate(text: string, width: number): string;
29
+ declare function padCell(text: string, width: number, rightAlign: boolean): string;
30
+ declare function buildBorderLine(widths: number[], left: string, mid: string, right: string, fill: string): string;
31
+ declare function buildDataLine(cells: string[], widths: number[], alignments: boolean[]): string;
32
+ export declare function Table({ columns, rows, maxWidth, minColumnWidth, maxColumnWidth, sampleSize, cursor, selectionStart, selectionEnd, matchingRows, currentMatchRow, toggledRows, }: TableProps): import("react").ReactNode;
33
+ export { computeColumnWidths, truncate, padCell, isNumeric, buildBorderLine, buildDataLine, sampleRows, };
34
+ export type { ColumnWidthOptions };
35
+ //# sourceMappingURL=Table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../src/Table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,EAAE,CAAA;IACpB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC1B;AASD,iBAAS,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzC;AAED,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CASpE;AAED,iBAAS,mBAAmB,CAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,MAAM,EAAE,EAAE,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,GAC1B,MAAM,EAAE,CAsDV;AAED,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,iBAAS,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAWzE;AAED,iBAAS,eAAe,CACtB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,CAGvF;AAcD,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,cAAsC,EACtC,cAAsC,EACtC,UAAgC,EAChC,MAAM,EACN,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,WAAW,GACZ,EAAE,UAAU,6BA6EZ;AAGD,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,UAAU,GACX,CAAA;AACD,YAAY,EAAE,kBAAkB,EAAE,CAAA"}
package/dist/Table.js ADDED
@@ -0,0 +1,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
2
+ import { useTerminalDimensions } from "@opentui/react";
3
+ import { useTheme } from "@tooee/themes";
4
+ const PADDING = 1;
5
+ const THRESHOLD = 20;
6
+ const ELLIPSIS = "…";
7
+ const DEFAULT_MIN_COL_WIDTH = 4;
8
+ const DEFAULT_MAX_COL_WIDTH = 50;
9
+ const DEFAULT_SAMPLE_SIZE = 100;
10
+ function isNumeric(value) {
11
+ return /^\s*-?[\d,]+\.?\d*\s*$/.test(value);
12
+ }
13
+ function sampleRows(rows, sampleSize) {
14
+ if (rows.length <= sampleSize)
15
+ return rows;
16
+ // Sample evenly distributed rows for representative widths
17
+ const step = rows.length / sampleSize;
18
+ const sampled = [];
19
+ for (let i = 0; i < sampleSize; i++) {
20
+ sampled.push(rows[Math.floor(i * step)]);
21
+ }
22
+ return sampled;
23
+ }
24
+ function computeColumnWidths(headers, rows, maxWidth, options) {
25
+ const { minColumnWidth, maxColumnWidth, sampleSize } = options;
26
+ const colCount = headers.length;
27
+ // Sample rows for performance on large tables
28
+ const sampledRows = sampleRows(rows, sampleSize);
29
+ // Calculate natural width for each column (header + content + padding)
30
+ const naturalWidths = headers.map((header, col) => {
31
+ const headerLen = header.length;
32
+ const maxRowLen = sampledRows.reduce((max, row) => Math.max(max, (row[col] ?? "").length), 0);
33
+ const contentWidth = Math.max(headerLen, maxRowLen);
34
+ // Apply min/max constraints before adding padding
35
+ const constrainedWidth = Math.min(maxColumnWidth, Math.max(minColumnWidth, contentWidth));
36
+ return constrainedWidth + PADDING * 2;
37
+ });
38
+ // 1 for each column border + 1 for trailing border
39
+ const borderOverhead = colCount + 1;
40
+ const totalNatural = naturalWidths.reduce((a, b) => a + b, 0) + borderOverhead;
41
+ // If everything fits, use natural widths
42
+ if (totalNatural <= maxWidth) {
43
+ return naturalWidths;
44
+ }
45
+ const available = maxWidth - borderOverhead;
46
+ const minColWidthWithPadding = minColumnWidth + PADDING * 2;
47
+ // Extreme case: not even minimum widths fit
48
+ if (available <= colCount * minColWidthWithPadding) {
49
+ return naturalWidths.map(() => Math.max(minColWidthWithPadding, Math.floor(available / colCount)));
50
+ }
51
+ // Give compact columns their natural width, distribute rest proportionally
52
+ const compact = naturalWidths.map((w) => w <= THRESHOLD);
53
+ const compactTotal = naturalWidths.reduce((sum, w, i) => sum + (compact[i] ? w : 0), 0);
54
+ const remaining = available - compactTotal;
55
+ const longTotal = naturalWidths.reduce((sum, w, i) => sum + (compact[i] ? 0 : w), 0);
56
+ if (longTotal === 0 || remaining <= 0) {
57
+ // All compact or no space left — distribute evenly
58
+ const total = naturalWidths.reduce((a, b) => a + b, 0);
59
+ return naturalWidths.map((w) => Math.max(minColWidthWithPadding, Math.floor((w / total) * available)));
60
+ }
61
+ return naturalWidths.map((w, i) => {
62
+ if (compact[i])
63
+ return w;
64
+ return Math.max(minColWidthWithPadding, Math.floor((w / longTotal) * remaining));
65
+ });
66
+ }
67
+ function truncate(text, width) {
68
+ const contentWidth = width - PADDING * 2;
69
+ if (contentWidth <= 0)
70
+ return "";
71
+ if (text.length <= contentWidth)
72
+ return text;
73
+ if (contentWidth <= 1)
74
+ return ELLIPSIS.slice(0, contentWidth);
75
+ return text.slice(0, contentWidth - 1) + ELLIPSIS;
76
+ }
77
+ function padCell(text, width, rightAlign) {
78
+ const contentWidth = width - PADDING * 2;
79
+ const truncated = truncate(text, width);
80
+ const padLeft = " ".repeat(PADDING);
81
+ const padRight = " ".repeat(PADDING);
82
+ if (rightAlign) {
83
+ const space = contentWidth - truncated.length;
84
+ return padLeft + " ".repeat(Math.max(0, space)) + truncated + padRight;
85
+ }
86
+ const space = contentWidth - truncated.length;
87
+ return padLeft + truncated + " ".repeat(Math.max(0, space)) + padRight;
88
+ }
89
+ function buildBorderLine(widths, left, mid, right, fill) {
90
+ return left + widths.map((w) => fill.repeat(w)).join(mid) + right;
91
+ }
92
+ function buildDataLine(cells, widths, alignments) {
93
+ const parts = cells.map((cell, i) => padCell(cell, widths[i], alignments[i]));
94
+ return "│" + parts.join("│") + "│";
95
+ }
96
+ function formatCellValue(value) {
97
+ if (value == null)
98
+ return "";
99
+ if (typeof value === "string")
100
+ return value;
101
+ if (typeof value === "number" || typeof value === "boolean")
102
+ return String(value);
103
+ if (value instanceof Date)
104
+ return value.toISOString();
105
+ try {
106
+ return JSON.stringify(value);
107
+ }
108
+ catch {
109
+ return String(value);
110
+ }
111
+ }
112
+ export function Table({ columns, rows, maxWidth, minColumnWidth = DEFAULT_MIN_COL_WIDTH, maxColumnWidth = DEFAULT_MAX_COL_WIDTH, sampleSize = DEFAULT_SAMPLE_SIZE, cursor, selectionStart, selectionEnd, matchingRows, currentMatchRow, toggledRows, }) {
113
+ const { theme } = useTheme();
114
+ const { width: terminalWidth } = useTerminalDimensions();
115
+ // Use terminal width minus margins (1 on each side) if maxWidth not provided
116
+ const effectiveMaxWidth = maxWidth ?? terminalWidth - 2;
117
+ const headers = columns.map((column) => column.header ?? column.key);
118
+ const normalizedRows = rows.map((row) => columns.map((column) => formatCellValue(row[column.key])));
119
+ const colWidths = computeColumnWidths(headers, normalizedRows, effectiveMaxWidth, {
120
+ minColumnWidth,
121
+ maxColumnWidth,
122
+ sampleSize,
123
+ });
124
+ const alignments = columns.map((column, colIdx) => {
125
+ if (column.align === "right")
126
+ return true;
127
+ if (column.align === "left")
128
+ return false;
129
+ const sampleValues = normalizedRows.slice(0, 10).map((row) => row[colIdx] ?? "");
130
+ const numericCount = sampleValues.filter(isNumeric).length;
131
+ return numericCount > sampleValues.length / 2;
132
+ });
133
+ const topBorder = buildBorderLine(colWidths, "┌", "┬", "┐", "─");
134
+ const headerSep = buildBorderLine(colWidths, "├", "┼", "┤", "─");
135
+ const bottomBorder = buildBorderLine(colWidths, "└", "┴", "┘", "─");
136
+ const headerLine = buildDataLine(headers, colWidths, alignments);
137
+ const dataLines = normalizedRows.map((row) => buildDataLine(row, colWidths, alignments));
138
+ const getRowStyle = (rowIndex) => {
139
+ const isCursor = cursor === rowIndex;
140
+ const isSelected = selectionStart != null &&
141
+ selectionEnd != null &&
142
+ rowIndex >= selectionStart &&
143
+ rowIndex <= selectionEnd;
144
+ const isMatch = matchingRows?.has(rowIndex);
145
+ const isCurrentMatch = currentMatchRow === rowIndex;
146
+ const isToggled = toggledRows?.has(rowIndex);
147
+ let bg;
148
+ let fg = theme.text;
149
+ // Determine background: selection < cursor (cursor overwrites)
150
+ if (isSelected) {
151
+ bg = theme.selection;
152
+ }
153
+ if (isToggled && !isCursor && !isSelected) {
154
+ bg = theme.backgroundPanel;
155
+ }
156
+ if (isCursor) {
157
+ bg = theme.cursorLine;
158
+ }
159
+ // Highlight match indicator on matching rows
160
+ if (isMatch && !isCursor) {
161
+ fg = isCurrentMatch ? theme.primary : theme.warning;
162
+ }
163
+ return { fg, bg };
164
+ };
165
+ return (_jsxs("box", { style: { flexDirection: "column", marginLeft: 1, marginRight: 1, marginBottom: 1 }, children: [_jsx("text", { content: topBorder, fg: theme.border }), _jsx("text", { content: headerLine, fg: theme.primary }), _jsx("text", { content: headerSep, fg: theme.border }), dataLines.map((line, i) => {
166
+ const style = getRowStyle(i);
167
+ return _jsx("text", { content: line, fg: style.fg, bg: style.bg }, i);
168
+ }), _jsx("text", { content: bottomBorder, fg: theme.border })] }));
169
+ }
170
+ // Exported for testing
171
+ export { computeColumnWidths, truncate, padCell, isNumeric, buildBorderLine, buildDataLine, sampleRows, };
172
+ //# sourceMappingURL=Table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.js","sourceRoot":"","sources":["../src/Table.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export { MarkdownView } from "./MarkdownView.jsx";
2
+ export { CodeView } from "./CodeView.jsx";
3
+ export { ImageView } from "./ImageView.jsx";
4
+ export { Table, computeColumnWidths, truncate, padCell, isNumeric, buildBorderLine, buildDataLine, sampleRows, } from "./Table.jsx";
5
+ export type { TableProps, ColumnWidthOptions } from "./Table.jsx";
6
+ export type { ColumnDef, TableRow } from "./table-types.js";
7
+ export { CommandPalette } from "./CommandPalette.jsx";
8
+ export type { CommandPaletteEntry } from "./CommandPalette.jsx";
9
+ export { parseCSV, parseTSV, parseJSON, parseAuto, detectFormat } from "./parsers.js";
10
+ export type { Format, ParsedTable } from "./parsers.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EACL,KAAK,EACL,mBAAmB,EACnB,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACrF,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { MarkdownView } from "./MarkdownView.jsx";
2
+ export { CodeView } from "./CodeView.jsx";
3
+ export { ImageView } from "./ImageView.jsx";
4
+ export { Table, computeColumnWidths, truncate, padCell, isNumeric, buildBorderLine, buildDataLine, sampleRows, } from "./Table.jsx";
5
+ export { CommandPalette } from "./CommandPalette.jsx";
6
+ export { parseCSV, parseTSV, parseJSON, parseAuto, detectFormat } from "./parsers.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EACL,KAAK,EACL,mBAAmB,EACnB,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,22 @@
1
+ import type { ColumnDef, TableRow } from "./table-types.js";
2
+ export interface ParsedTable {
3
+ columns: ColumnDef[];
4
+ rows: TableRow[];
5
+ format: Format;
6
+ }
7
+ export declare function parseCSV(input: string): {
8
+ columns: ColumnDef[];
9
+ rows: TableRow[];
10
+ };
11
+ export declare function parseTSV(input: string): {
12
+ columns: ColumnDef[];
13
+ rows: TableRow[];
14
+ };
15
+ export declare function parseJSON(input: string): {
16
+ columns: ColumnDef[];
17
+ rows: TableRow[];
18
+ };
19
+ export type Format = "csv" | "tsv" | "json" | "unknown";
20
+ export declare function detectFormat(input: string): Format;
21
+ export declare function parseAuto(input: string): ParsedTable;
22
+ //# sourceMappingURL=parsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../src/parsers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAA;IACpB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAMlF;AAwCD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAMlF;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAenF;AAED,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;AAEvD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYlD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAoBpD"}
@@ -0,0 +1,143 @@
1
+ export function parseCSV(input) {
2
+ const lines = splitLines(input);
3
+ if (lines.length === 0)
4
+ return { columns: [], rows: [] };
5
+ const columns = createColumnDefs(parseCSVLine(lines[0]));
6
+ const rows = buildRows(columns, lines.slice(1).map(parseCSVLine));
7
+ return { columns, rows };
8
+ }
9
+ function parseCSVLine(line) {
10
+ const fields = [];
11
+ let i = 0;
12
+ while (i < line.length) {
13
+ if (line[i] === '"') {
14
+ // Quoted field
15
+ i++;
16
+ let field = "";
17
+ while (i < line.length) {
18
+ if (line[i] === '"') {
19
+ if (i + 1 < line.length && line[i + 1] === '"') {
20
+ field += '"';
21
+ i += 2;
22
+ }
23
+ else {
24
+ i++; // closing quote
25
+ break;
26
+ }
27
+ }
28
+ else {
29
+ field += line[i];
30
+ i++;
31
+ }
32
+ }
33
+ fields.push(field);
34
+ if (i < line.length && line[i] === ",")
35
+ i++; // skip comma
36
+ }
37
+ else {
38
+ const nextComma = line.indexOf(",", i);
39
+ if (nextComma === -1) {
40
+ fields.push(line.slice(i));
41
+ break;
42
+ }
43
+ else {
44
+ fields.push(line.slice(i, nextComma));
45
+ i = nextComma + 1;
46
+ }
47
+ }
48
+ }
49
+ return fields;
50
+ }
51
+ export function parseTSV(input) {
52
+ const lines = splitLines(input);
53
+ if (lines.length === 0)
54
+ return { columns: [], rows: [] };
55
+ const columns = createColumnDefs(lines[0].split("\t"));
56
+ const rows = buildRows(columns, lines.slice(1).map((line) => line.split("\t")));
57
+ return { columns, rows };
58
+ }
59
+ export function parseJSON(input) {
60
+ const data = JSON.parse(input);
61
+ if (!Array.isArray(data) || data.length === 0)
62
+ return { columns: [], rows: [] };
63
+ const keys = Array.from(new Set(data.flatMap((item) => Object.keys(item))));
64
+ const columns = keys.map((key) => ({ key, header: key }));
65
+ const rows = data.map((item) => {
66
+ const row = {};
67
+ for (const column of columns) {
68
+ row[column.key] = item[column.key] ?? "";
69
+ }
70
+ return row;
71
+ });
72
+ return { columns, rows };
73
+ }
74
+ export function detectFormat(input) {
75
+ const trimmed = input.trimStart();
76
+ if (trimmed.startsWith("[")) {
77
+ try {
78
+ const parsed = JSON.parse(trimmed);
79
+ if (Array.isArray(parsed))
80
+ return "json";
81
+ }
82
+ catch { }
83
+ }
84
+ const firstLine = input.split("\n")[0] ?? "";
85
+ if (firstLine.includes("\t"))
86
+ return "tsv";
87
+ if (firstLine.includes(","))
88
+ return "csv";
89
+ return "unknown";
90
+ }
91
+ export function parseAuto(input) {
92
+ const format = detectFormat(input);
93
+ let columns;
94
+ let rows;
95
+ switch (format) {
96
+ case "csv":
97
+ ;
98
+ ({ columns, rows } = parseCSV(input));
99
+ break;
100
+ case "tsv":
101
+ ;
102
+ ({ columns, rows } = parseTSV(input));
103
+ break;
104
+ case "json":
105
+ ;
106
+ ({ columns, rows } = parseJSON(input));
107
+ break;
108
+ default:
109
+ // Fall back to CSV
110
+ ;
111
+ ({ columns, rows } = parseCSV(input));
112
+ break;
113
+ }
114
+ return { columns, rows, format };
115
+ }
116
+ function splitLines(input) {
117
+ return input.split("\n").filter((line) => line.trim().length > 0);
118
+ }
119
+ function createColumnDefs(rawHeaders) {
120
+ const seen = new Map();
121
+ return rawHeaders.map((header, index) => {
122
+ const trimmed = header.trim();
123
+ const fallback = `column_${index + 1}`;
124
+ const base = trimmed === "" ? fallback : trimmed;
125
+ const count = seen.get(base) ?? 0;
126
+ seen.set(base, count + 1);
127
+ const key = count === 0 ? base : `${base}_${count + 1}`;
128
+ return {
129
+ key,
130
+ header: trimmed || undefined,
131
+ };
132
+ });
133
+ }
134
+ function buildRows(columns, rawRows) {
135
+ return rawRows.map((row) => {
136
+ const record = {};
137
+ columns.forEach((column, index) => {
138
+ record[column.key] = row[index] ?? "";
139
+ });
140
+ return record;
141
+ });
142
+ }
143
+ //# sourceMappingURL=parsers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.js","sourceRoot":"","sources":["../src/parsers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ColumnDef {
2
+ key: string;
3
+ header?: string;
4
+ align?: "left" | "right";
5
+ }
6
+ export type TableRow = Record<string, unknown>;
7
+ //# sourceMappingURL=table-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-types.d.ts","sourceRoot":"","sources":["../src/table-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACzB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=table-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-types.js","sourceRoot":"","sources":["../src/table-types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@tooee/renderers",
3
+ "version": "0.1.0",
4
+ "description": "Content renderers (markdown, code, image, table) for Tooee",
5
+ "license": "MIT",
6
+ "author": "Gareth Andrew",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/gingerhendrix/tooee.git",
10
+ "directory": "packages/renderers"
11
+ },
12
+ "homepage": "https://github.com/gingerhendrix/tooee",
13
+ "bugs": "https://github.com/gingerhendrix/tooee/issues",
14
+ "keywords": ["tui", "terminal", "cli", "opentui", "markdown", "syntax-highlighting", "image"],
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "import": {
19
+ "@tooee/source": "./src/index.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ }
23
+ },
24
+ "files": ["dist", "src"],
25
+ "scripts": {
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "dependencies": {
29
+ "@tooee/themes": "0.0.0",
30
+ "marked": "^16.3.0"
31
+ },
32
+ "devDependencies": {
33
+ "@opentui/core": "^0.1.67",
34
+ "@opentui/react": "^0.1.67",
35
+ "@types/bun": "^1.3.5",
36
+ "@types/react": "^19.1.10",
37
+ "jimp": "^1.6.0",
38
+ "typescript": "^5.8.3"
39
+ },
40
+ "peerDependencies": {
41
+ "@opentui/core": "^0.1.67",
42
+ "@opentui/react": "^0.1.67",
43
+ "react": "^18.0.0 || ^19.0.0"
44
+ }
45
+ }
@@ -0,0 +1,117 @@
1
+ import { useEffect, useRef } from "react"
2
+ import type { LineNumberRenderable } from "@opentui/core"
3
+ import { useTheme } from "@tooee/themes"
4
+
5
+ interface CodeViewProps {
6
+ content: string
7
+ language?: string
8
+ showLineNumbers?: boolean
9
+ cursor?: number
10
+ selectionStart?: number
11
+ selectionEnd?: number
12
+ matchingLines?: Set<number>
13
+ currentMatchLine?: number
14
+ toggledLines?: Set<number>
15
+ }
16
+
17
+ export function CodeView({
18
+ content,
19
+ language,
20
+ showLineNumbers = true,
21
+ cursor,
22
+ selectionStart,
23
+ selectionEnd,
24
+ matchingLines,
25
+ currentMatchLine,
26
+ toggledLines,
27
+ }: CodeViewProps) {
28
+ const { syntax, theme } = useTheme()
29
+ const lineNumRef = useRef<LineNumberRenderable>(null)
30
+
31
+ useEffect(() => {
32
+ const ref = lineNumRef.current
33
+ if (!ref) return
34
+
35
+ ref.clearAllLineColors()
36
+ ref.clearAllLineSigns()
37
+
38
+ // Search matches
39
+ if (matchingLines) {
40
+ for (const line of matchingLines) {
41
+ ref.setLineSign(line, {
42
+ after: "●",
43
+ afterColor: line === currentMatchLine ? theme.primary : theme.warning,
44
+ })
45
+ }
46
+ }
47
+
48
+ // Selection range
49
+ if (selectionStart != null && selectionEnd != null) {
50
+ for (let i = selectionStart; i <= selectionEnd; i++) {
51
+ ref.setLineColor(i, { content: theme.selection, gutter: theme.selection })
52
+ }
53
+ }
54
+
55
+ if (toggledLines) {
56
+ for (const line of toggledLines) {
57
+ const isSelected =
58
+ selectionStart != null && selectionEnd != null && line >= selectionStart && line <= selectionEnd
59
+ if (line === cursor || isSelected) continue
60
+ ref.setLineColor(line, {
61
+ content: theme.backgroundPanel,
62
+ gutter: theme.backgroundPanel,
63
+ })
64
+ }
65
+ }
66
+
67
+ // Cursor line (overwrites selection color on cursor line)
68
+ if (cursor != null) {
69
+ ref.setLineColor(cursor, { content: theme.cursorLine, gutter: theme.cursorLine })
70
+ ref.setLineSign(cursor, {
71
+ before: "▸",
72
+ beforeColor: theme.primary,
73
+ // Preserve search match sign if present
74
+ ...(matchingLines?.has(cursor)
75
+ ? {
76
+ after: "●",
77
+ afterColor: cursor === currentMatchLine ? theme.primary : theme.warning,
78
+ }
79
+ : {}),
80
+ })
81
+ }
82
+ }, [
83
+ content,
84
+ cursor,
85
+ selectionStart,
86
+ selectionEnd,
87
+ matchingLines,
88
+ currentMatchLine,
89
+ toggledLines,
90
+ theme,
91
+ ])
92
+
93
+ const codeElement = <code content={content} filetype={language} syntaxStyle={syntax} />
94
+
95
+ return (
96
+ <box
97
+ style={{
98
+ flexDirection: "column",
99
+ }}
100
+ >
101
+ {showLineNumbers ? (
102
+ <line-number
103
+ ref={lineNumRef}
104
+ key={theme.textMuted + theme.backgroundElement}
105
+ fg={theme.textMuted}
106
+ bg={theme.backgroundElement}
107
+ paddingRight={1}
108
+ showLineNumbers
109
+ >
110
+ {codeElement}
111
+ </line-number>
112
+ ) : (
113
+ codeElement
114
+ )}
115
+ </box>
116
+ )
117
+ }