(node: React.ReactNode, columns?: number)
| 72 | * Renders a React node to a string with ANSI escape codes (for terminal output). |
| 73 | */ |
| 74 | export function renderToAnsiString(node: React.ReactNode, columns?: number): Promise<string> { |
| 75 | return new Promise(async resolve => { |
| 76 | let output = ''; |
| 77 | |
| 78 | // Capture all writes. Set .columns so Ink (ink.tsx:~165) picks up a |
| 79 | // chosen width instead of PassThrough's undefined → 80 fallback — |
| 80 | // useful for rendering at terminal width for file dumps that should |
| 81 | // match what the user sees on screen. |
| 82 | const stream = new PassThrough(); |
| 83 | if (columns !== undefined) { |
| 84 | ; |
| 85 | (stream as unknown as { |
| 86 | columns: number; |
| 87 | }).columns = columns; |
| 88 | } |
| 89 | stream.on('data', chunk => { |
| 90 | output += chunk.toString(); |
| 91 | }); |
| 92 | |
| 93 | // Render the component wrapped in RenderOnceAndExit |
| 94 | // Non-TTY stdout (PassThrough) gives full-frame output instead of diffs |
| 95 | const instance = await render(<RenderOnceAndExit>{node}</RenderOnceAndExit>, { |
| 96 | stdout: stream as unknown as NodeJS.WriteStream, |
| 97 | patchConsole: false |
| 98 | }); |
| 99 | |
| 100 | // Wait for the component to exit naturally |
| 101 | await instance.waitUntilExit(); |
| 102 | |
| 103 | // Extract only the first frame's content to avoid duplication |
| 104 | // (Ink outputs multiple frames in non-TTY mode) |
| 105 | await resolve(extractFirstFrame(output)); |
| 106 | }); |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Renders a React node to a plain text string (ANSI codes stripped). |
no test coverage detected