Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hungry-drinks-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clack/prompts": patch
---

Fix spinner clearing by tracking the previously rendered output instead of message.
1 change: 1 addition & 0 deletions examples/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"path": "jiti ./path.ts",
"spinner-ci": "npx cross-env CI=\"true\" jiti ./spinner-ci.ts",
"spinner-timer": "jiti ./spinner-timer.ts",
"spinner-wrap": "jiti ./spinner-wrap.ts",
"task-log": "jiti ./task-log.ts"
},
"devDependencies": {
Expand Down
48 changes: 48 additions & 0 deletions examples/basic/spinner-wrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as p from '@clack/prompts';

p.intro('spinner start...');

const barWidth = 3;
const columns = (process.stdout.columns || 80) - barWidth;

async function testCase(subtract = 0) {
p.log.info(`Testing spinner with message width = terminal columns - ${subtract}...`);

const spin = p.spinner();

spin.start();

// Create a message that fills the width the terminal
const length = columns - subtract;
const step = Math.floor(length / 5);

// Start with full line
const chars = Array.from({ length }, () => '□');

// Replace some characters with spaces for better wrapping
for (let i = step; i < length; i += step) {
chars[i] = ' ';
}

const message = chars.join('');

spin.message(message);

await wait(3000);

spin.stop('Done');
}

async function test() {
await testCase(0); // Do not subtract anything, output width = terminal columns
await testCase(2); // Subtract 2
await testCase(3); // Subtract 3, which is the length of spinner symbols
}

test();

//

function wait(ms: number) {
return new Promise((r) => setTimeout(r, ms));
}
11 changes: 5 additions & 6 deletions packages/prompts/src/spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const spinner = ({
let isCancelled = false;
let _message = '';
let _prevMessage: string | undefined;
let _prevOutput: string | undefined;
let _origin: number = performance.now();
const columns = getColumns(output);
const styleFn = opts?.styleFrame ?? defaultStyleFn;
Expand Down Expand Up @@ -102,13 +103,9 @@ export const spinner = ({
};

const clearPrevMessage = () => {
if (_prevMessage === undefined) return;
if (_prevOutput === undefined) return;
if (isCI) output.write('\n');
const wrapped = wrapAnsi(_prevMessage, columns, {
hard: true,
trim: false,
});
const prevLines = wrapped.split('\n');
const prevLines = _prevOutput.split('\n');
if (prevLines.length > 1) {
output.write(cursor.up(prevLines.length - 1));
}
Expand Down Expand Up @@ -164,6 +161,8 @@ export const spinner = ({
});
output.write(wrapped);

_prevOutput = wrapped;

frameIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0;
// indicator increase by 1 every 8 frames
indicatorTimer = indicatorTimer < 4 ? indicatorTimer + 0.125 : 0;
Expand Down