@tooee/renderers 0.1.11 → 0.1.12

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.
Files changed (43) hide show
  1. package/dist/CodeView.d.ts +3 -7
  2. package/dist/CodeView.d.ts.map +1 -1
  3. package/dist/CodeView.js +5 -31
  4. package/dist/CodeView.js.map +1 -1
  5. package/dist/CommandPalette.d.ts.map +1 -1
  6. package/dist/CommandPalette.js +1 -23
  7. package/dist/CommandPalette.js.map +1 -1
  8. package/dist/DecorationLayer.d.ts +14 -0
  9. package/dist/DecorationLayer.d.ts.map +1 -0
  10. package/dist/DecorationLayer.js +2 -0
  11. package/dist/DecorationLayer.js.map +1 -0
  12. package/dist/MarkdownView.d.ts +3 -9
  13. package/dist/MarkdownView.d.ts.map +1 -1
  14. package/dist/MarkdownView.js +11 -32
  15. package/dist/MarkdownView.js.map +1 -1
  16. package/dist/RowDocumentRenderable.d.ts +14 -26
  17. package/dist/RowDocumentRenderable.d.ts.map +1 -1
  18. package/dist/RowDocumentRenderable.js +74 -78
  19. package/dist/RowDocumentRenderable.js.map +1 -1
  20. package/dist/Table.d.ts +5 -9
  21. package/dist/Table.d.ts.map +1 -1
  22. package/dist/Table.js +17 -46
  23. package/dist/Table.js.map +1 -1
  24. package/dist/index.d.ts +5 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +3 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/parsers.d.ts.map +1 -1
  29. package/dist/parsers.js.map +1 -1
  30. package/dist/useGutterPalette.d.ts +3 -0
  31. package/dist/useGutterPalette.d.ts.map +1 -0
  32. package/dist/useGutterPalette.js +10 -0
  33. package/dist/useGutterPalette.js.map +1 -0
  34. package/package.json +18 -16
  35. package/src/CodeView.tsx +11 -54
  36. package/src/CommandPalette.tsx +1 -25
  37. package/src/DecorationLayer.ts +11 -0
  38. package/src/MarkdownView.tsx +19 -51
  39. package/src/RowDocumentRenderable.ts +91 -135
  40. package/src/Table.tsx +35 -71
  41. package/src/index.ts +4 -7
  42. package/src/parsers.ts +4 -1
  43. package/src/useGutterPalette.ts +15 -0
package/src/Table.tsx CHANGED
@@ -1,8 +1,13 @@
1
1
  import { useTerminalDimensions } from "@opentui/react"
2
2
  import { useTheme } from "@tooee/themes"
3
- import { useEffect, useRef, type RefObject } from "react"
3
+ import { type RefObject } from "react"
4
+ import type { MarkState } from "@tooee/marks"
4
5
  import type { ColumnDef, TableRow } from "./table-types.js"
5
- import type { RowDocumentRenderable, RowDocumentPalette, RowDocumentDecorations } from "./RowDocumentRenderable.js"
6
+ import {
7
+ computeRowDocumentGutterWidth,
8
+ type RowDocumentRenderable,
9
+ } from "./RowDocumentRenderable.js"
10
+ import { useGutterPalette } from "./useGutterPalette.js"
6
11
  import "./row-document.js"
7
12
 
8
13
  export interface TableProps {
@@ -18,12 +23,7 @@ export interface TableProps {
18
23
  sampleSize?: number
19
24
  /** Show line numbers in the gutter (default: true) */
20
25
  showLineNumbers?: boolean
21
- cursor?: number
22
- selectionStart?: number
23
- selectionEnd?: number
24
- matchingRows?: Set<number>
25
- currentMatchRow?: number
26
- toggledRows?: Set<number>
26
+ marks?: MarkState
27
27
  docRef?: RefObject<RowDocumentRenderable | null>
28
28
  /** Column width mode: "content" sizes to content (default), "fill" expands to fill available width */
29
29
  columnWidthMode?: "content" | "fill"
@@ -73,7 +73,10 @@ function computeColumnWidths(
73
73
  // Use Bun.stringWidth for correct display width with CJK/emoji
74
74
  const naturalWidths = headers.map((header, col) => {
75
75
  const headerLen = Bun.stringWidth(header)
76
- const maxRowLen = sampledRows.reduce((max, row) => Math.max(max, Bun.stringWidth(row[col] ?? "")), 0)
76
+ const maxRowLen = sampledRows.reduce(
77
+ (max, row) => Math.max(max, Bun.stringWidth(row[col] ?? "")),
78
+ 0,
79
+ )
77
80
  const contentWidth = Math.max(headerLen, maxRowLen)
78
81
  // Apply min/max constraints before adding padding
79
82
  const constrainedWidth = Math.min(maxColumnWidth, Math.max(minColumnWidth, contentWidth))
@@ -124,22 +127,6 @@ function computeColumnWidths(
124
127
  })
125
128
  }
126
129
 
127
- /**
128
- * Pre-compute gutter width to subtract from available column space.
129
- * Mirrors RowDocumentRenderable._computeGutterWidth logic.
130
- */
131
- function computeGutterWidth(rowCount: number, showLineNumbers: boolean): number {
132
- let width = 0
133
- if (showLineNumbers) {
134
- // lineNumberStart defaults to 1, so max line number = rowCount
135
- const maxLineNum = rowCount
136
- width += Math.max(String(maxLineNum).length, 1)
137
- }
138
- width += 1 // signColumnWidth
139
- width += 1 // gutterPaddingRight (default)
140
- return width
141
- }
142
-
143
130
  function formatCellValue(value: unknown): string {
144
131
  if (value == null) return ""
145
132
  if (typeof value === "string") return value
@@ -160,20 +147,20 @@ export function Table({
160
147
  maxColumnWidth = DEFAULT_MAX_COL_WIDTH,
161
148
  sampleSize = DEFAULT_SAMPLE_SIZE,
162
149
  showLineNumbers = true,
163
- cursor,
164
- selectionStart,
165
- selectionEnd,
166
- matchingRows,
167
- currentMatchRow,
168
- toggledRows,
150
+ marks,
169
151
  docRef,
170
152
  columnWidthMode = "content",
171
153
  }: TableProps) {
172
154
  const { theme } = useTheme()
155
+ const palette = useGutterPalette()
173
156
  const { width: terminalWidth } = useTerminalDimensions()
174
157
 
175
158
  // Compute available content width: start with total space, subtract margins and gutter
176
- const gutterWidth = computeGutterWidth(rows.length, showLineNumbers)
159
+ const gutterWidth = computeRowDocumentGutterWidth({
160
+ showLineNumbers,
161
+ rowCount: rows.length,
162
+ signColumnWidth: 1,
163
+ })
177
164
  const effectiveMaxWidth = Math.max(0, (maxWidth ?? terminalWidth) - MARGIN * 2 - gutterWidth)
178
165
 
179
166
  const headers = columns.map((column) => column.header ?? column.key)
@@ -197,37 +184,16 @@ export function Table({
197
184
  return numericCount > sampleValues.length / 2
198
185
  })
199
186
 
200
- const internalRef = useRef<RowDocumentRenderable>(null)
201
- const effectiveRef = docRef ?? internalRef
202
-
203
- const palette: RowDocumentPalette = {
204
- gutterFg: theme.textMuted,
205
- gutterBg: theme.backgroundElement,
206
- cursorSignFg: theme.primary,
207
- matchSignFg: theme.warning,
208
- currentMatchSignFg: theme.primary,
209
- cursorBg: theme.cursorLine,
210
- selectionBg: theme.selection,
211
- matchBg: theme.warning,
212
- currentMatchBg: theme.primary,
213
- toggledBg: theme.backgroundPanel,
214
- }
215
-
216
- useEffect(() => {
217
- const decorations: RowDocumentDecorations = {
218
- cursorRow: cursor,
219
- selection: selectionStart != null && selectionEnd != null
220
- ? { start: selectionStart, end: selectionEnd }
221
- : null,
222
- matchingRows: matchingRows,
223
- currentMatchRow: currentMatchRow,
224
- toggledRows: toggledRows,
225
- }
226
- effectiveRef.current?.setDecorations(decorations)
227
- }, [cursor, selectionStart, selectionEnd, matchingRows, currentMatchRow, toggledRows])
228
-
229
187
  return (
230
- <box style={{ flexDirection: "column", flexGrow: 1, marginLeft: MARGIN, marginRight: MARGIN, marginBottom: MARGIN }}>
188
+ <box
189
+ style={{
190
+ flexDirection: "column",
191
+ flexGrow: 1,
192
+ marginLeft: MARGIN,
193
+ marginRight: MARGIN,
194
+ marginBottom: MARGIN,
195
+ }}
196
+ >
231
197
  {/* Fixed header row — outside row-document so it stays visible */}
232
198
  <box style={{ flexDirection: "row", flexShrink: 0, paddingLeft: gutterWidth }}>
233
199
  {headers.map((h, i) => (
@@ -254,13 +220,14 @@ export function Table({
254
220
 
255
221
  {/* Scrollable data rows */}
256
222
  <row-document
257
- ref={effectiveRef}
223
+ ref={docRef}
258
224
  mode="multi"
259
225
  rowChildOffset={0}
260
226
  showGutter={true}
261
227
  showLineNumbers={showLineNumbers}
262
228
  signColumnWidth={1}
263
229
  palette={palette}
230
+ decorations={marks?.sets}
264
231
  style={{ flexGrow: 1 }}
265
232
  >
266
233
  {normalizedRows.map((row, i) => (
@@ -268,9 +235,10 @@ export function Table({
268
235
  {row.map((cell, j) => {
269
236
  const contentWidth = colWidths[j] - PADDING * 2
270
237
  const cellWidth = Bun.stringWidth(cell)
271
- const displayCell = alignments[j] && cellWidth <= contentWidth
272
- ? " ".repeat(contentWidth - cellWidth) + cell
273
- : cell
238
+ const displayCell =
239
+ alignments[j] && cellWidth <= contentWidth
240
+ ? " ".repeat(contentWidth - cellWidth) + cell
241
+ : cell
274
242
  return (
275
243
  <text
276
244
  key={j}
@@ -293,9 +261,5 @@ export function Table({
293
261
  }
294
262
 
295
263
  // Exported for testing and MarkdownView
296
- export {
297
- computeColumnWidths,
298
- isNumeric,
299
- sampleRows,
300
- }
264
+ export { computeColumnWidths, isNumeric, sampleRows }
301
265
  export type { ColumnWidthOptions }
package/src/index.ts CHANGED
@@ -1,12 +1,7 @@
1
1
  export { MarkdownView } from "./MarkdownView.js"
2
2
  export { CodeView } from "./CodeView.js"
3
3
  export { ImageView } from "./ImageView.js"
4
- export {
5
- Table,
6
- computeColumnWidths,
7
- isNumeric,
8
- sampleRows,
9
- } from "./Table.js"
4
+ export { Table, computeColumnWidths, isNumeric, sampleRows } from "./Table.js"
10
5
  export type { TableProps, ColumnWidthOptions } from "./Table.js"
11
6
  export type { ColumnDef, TableRow } from "./table-types.js"
12
7
  export { CommandPalette } from "./CommandPalette.js"
@@ -14,8 +9,10 @@ export type { CommandPaletteEntry } from "./CommandPalette.js"
14
9
  export { parseCSV, parseTSV, parseJSON, parseAuto, detectFormat } from "./parsers.js"
15
10
  export type { Format, ParsedTable } from "./parsers.js"
16
11
  export { RowDocumentRenderable } from "./RowDocumentRenderable.js"
12
+ export { computeRowDocumentGutterWidth } from "./RowDocumentRenderable.js"
17
13
  export type {
18
14
  RowDocumentOptions,
19
15
  RowDocumentPalette,
20
- RowDocumentDecorations,
21
16
  } from "./RowDocumentRenderable.js"
17
+ export type { DecorationLayer, RowDecoration } from "./DecorationLayer.js"
18
+ export { useGutterPalette } from "./useGutterPalette.js"
package/src/parsers.ts CHANGED
@@ -56,7 +56,10 @@ export function parseTSV(input: string): { columns: ColumnDef[]; rows: TableRow[
56
56
  const lines = splitLines(input)
57
57
  if (lines.length === 0) return { columns: [], rows: [] }
58
58
  const columns = createColumnDefs(lines[0].split("\t"))
59
- const rows = buildRows(columns, lines.slice(1).map((line) => line.split("\t")))
59
+ const rows = buildRows(
60
+ columns,
61
+ lines.slice(1).map((line) => line.split("\t")),
62
+ )
60
63
  return { columns, rows }
61
64
  }
62
65
 
@@ -0,0 +1,15 @@
1
+ import { useMemo } from "react"
2
+ import { useTheme } from "@tooee/themes"
3
+ import type { RowDocumentPalette } from "./RowDocumentRenderable.js"
4
+
5
+ export function useGutterPalette(): RowDocumentPalette {
6
+ const { theme } = useTheme()
7
+
8
+ return useMemo(
9
+ () => ({
10
+ gutterFg: theme.textMuted,
11
+ gutterBg: theme.backgroundElement,
12
+ }),
13
+ [theme.textMuted, theme.backgroundElement],
14
+ )
15
+ }