diff --git a/src/table.tsx b/src/table.tsx
index d974f71..d408296 100644
--- a/src/table.tsx
+++ b/src/table.tsx
@@ -2,6 +2,7 @@
import cliTruncate from 'cli-truncate'
import {Box, Text, render} from 'ink'
+import {WriteStream} from 'node:tty'
import {sha1} from 'object-hash'
import React from 'react'
import stripAnsi from 'strip-ansi'
@@ -384,14 +385,33 @@ export function Skeleton(props: React.PropsWithChildren & {readonly height?: num
return {texts}
}
+/**
+ * A custom WriteStream that captures the frames written to stdout.
+ * This allows us to avoid an issue where Ink rerenders the component twice
+ * because it uses ansiEscapes.clearTerminal, which doesn't seem to have
+ * the desired effect in powershell.
+ */
+class Stdout extends WriteStream {
+ private frames: string[] = []
+ public lastFrame(): string | undefined {
+ return this.frames.filter((f) => stripAnsi(f) !== '').at(-1)
+ }
+
+ write(data: string): boolean {
+ this.frames.push(data)
+ return true
+ }
+}
+
/**
* Renders a table with the given data.
* @param options see {@link TableOptions}
*/
export function printTable>(options: TableOptions): void {
- const instance = render()
+ const stdout = new Stdout(1)
+ const instance = render(, {stdout})
instance.unmount()
- process.stdout.write('\n')
+ process.stdout.write(`${stdout.lastFrame()}\n`)
}
function Container(props: ContainerProps) {
@@ -406,6 +426,7 @@ export function printTables[]>(
tables: {[P in keyof T]: TableOptions},
options?: Omit,
): void {
+ const stdout = new Stdout(1)
const leftMargin = options?.marginLeft ?? options?.margin ?? 0
const rightMargin = options?.marginRight ?? options?.margin ?? 0
const columns = process.stdout.columns - (leftMargin + rightMargin)
@@ -422,7 +443,8 @@ export function printTables[]>(
))}
,
+ {stdout},
)
instance.unmount()
- process.stdout.write('\n')
+ process.stdout.write(`${stdout.lastFrame()}\n`)
}