From 9da0d31853dd01165b5942bc9442a0edc4ba522c Mon Sep 17 00:00:00 2001 From: bq Date: Fri, 10 Jul 2026 13:11:46 +0200 Subject: [PATCH 1/2] fix: wrap results from spinner with `wrapTextWithPrefix` and add prefix --- packages/prompts/src/spinner.ts | 15 +- .../__snapshots__/progress-bar.test.ts.snap | 84 +++++----- .../test/__snapshots__/spinner.test.ts.snap | 146 +++++++++++------- packages/prompts/test/spinner.test.ts | 36 +++-- 4 files changed, 159 insertions(+), 122 deletions(-) diff --git a/packages/prompts/src/spinner.ts b/packages/prompts/src/spinner.ts index 618ae427..df6e84d6 100644 --- a/packages/prompts/src/spinner.ts +++ b/packages/prompts/src/spinner.ts @@ -1,5 +1,5 @@ import { styleText } from 'node:util'; -import { block, getColumns, settings } from '@clack/core'; +import { block, getColumns, settings, wrapTextWithPrefix } from '@clack/core'; import { wrapAnsi } from 'fast-wrap-ansi'; import { cursor, erase } from 'sisteransi'; import { @@ -127,15 +127,16 @@ export const spinner = ({ return min > 0 ? `[${min}m ${secs}s]` : `[${secs}s]`; }; + const prefix = `${styleText('gray', S_BAR)} `; const hasGuide = opts.withGuide ?? settings.withGuide; const start = (msg = ''): void => { isSpinnerActive = true; unblock = block({ output }); - _message = removeTrailingDots(msg); + _message = wrapTextWithPrefix(output, removeTrailingDots(msg), hasGuide ? prefix : '', ''); _origin = performance.now(); if (hasGuide) { - output.write(`${styleText('gray', S_BAR)}\n`); + output.write(`${prefix}\n`); } let frameIndex = 0; let indicatorTimer = 0; @@ -159,11 +160,7 @@ export const spinner = ({ outputMessage = `${frame} ${_message}${loadingDots}`; } - const wrapped = wrapAnsi(outputMessage, columns, { - hard: true, - trim: false, - }); - output.write(wrapped); + output.write(outputMessage); frameIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0; // indicator increase by 1 every 8 frames @@ -182,7 +179,7 @@ export const spinner = ({ : code === 1 ? styleText('red', S_STEP_CANCEL) : styleText('red', S_STEP_ERROR); - _message = msg ?? _message; + _message = wrapTextWithPrefix(output, msg ?? _message, hasGuide ? prefix : '', ''); if (!silent) { if (indicator === 'timer') { output.write(`${step} ${_message} ${formatTimer(_origin)}\n`); diff --git a/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap b/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap index 8296f517..b4548b3f 100644 --- a/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap +++ b/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap @@ -3,7 +3,7 @@ exports[`prompts - progress (isCI = false) > message > sets message for next frame 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -15,7 +15,7 @@ exports[`prompts - progress (isCI = false) > message > sets message for next fra exports[`prompts - progress (isCI = false) > process exit handling > prioritizes cancel option over global setting 1`] = ` [ "", - "│ + "│ ", "■ Progress cancel message ", @@ -26,7 +26,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > prioritizes exports[`prompts - progress (isCI = false) > process exit handling > prioritizes error option over global setting 1`] = ` [ "", - "│ + "│ ", "▲ Progress error message ", @@ -37,7 +37,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > prioritizes exports[`prompts - progress (isCI = false) > process exit handling > uses custom cancel message when provided directly 1`] = ` [ "", - "│ + "│ ", "■ Custom cancel message ", @@ -48,7 +48,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > uses custom exports[`prompts - progress (isCI = false) > process exit handling > uses custom error message when provided directly 1`] = ` [ "", - "│ + "│ ", "▲ Custom error message ", @@ -59,7 +59,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > uses custom exports[`prompts - progress (isCI = false) > process exit handling > uses default cancel message 1`] = ` [ "", - "│ + "│ ", "■ Canceled ", @@ -70,7 +70,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > uses defaul exports[`prompts - progress (isCI = false) > process exit handling > uses global custom cancel message from settings 1`] = ` [ "", - "│ + "│ ", "■ Global cancel message ", @@ -81,7 +81,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > uses global exports[`prompts - progress (isCI = false) > process exit handling > uses global custom error message from settings 1`] = ` [ "", - "│ + "│ ", "▲ Global error message ", @@ -92,7 +92,7 @@ exports[`prompts - progress (isCI = false) > process exit handling > uses global exports[`prompts - progress (isCI = false) > start > renders frames at interval 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -110,7 +110,7 @@ exports[`prompts - progress (isCI = false) > start > renders frames at interval exports[`prompts - progress (isCI = false) > start > renders message 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ foo", ] @@ -119,7 +119,7 @@ exports[`prompts - progress (isCI = false) > start > renders message 1`] = ` exports[`prompts - progress (isCI = false) > start > renders timer when indicator is "timer" 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ [0s]", ] @@ -128,7 +128,7 @@ exports[`prompts - progress (isCI = false) > start > renders timer when indicato exports[`prompts - progress (isCI = false) > stop > renders cancel symbol when calling cancel() 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -142,7 +142,7 @@ exports[`prompts - progress (isCI = false) > stop > renders cancel symbol when c exports[`prompts - progress (isCI = false) > stop > renders error symbol when calling error() 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -156,7 +156,7 @@ exports[`prompts - progress (isCI = false) > stop > renders error symbol when ca exports[`prompts - progress (isCI = false) > stop > renders message 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -170,7 +170,7 @@ exports[`prompts - progress (isCI = false) > stop > renders message 1`] = ` exports[`prompts - progress (isCI = false) > stop > renders message when cancelling 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -184,7 +184,7 @@ exports[`prompts - progress (isCI = false) > stop > renders message when cancell exports[`prompts - progress (isCI = false) > stop > renders message when erroring 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -198,7 +198,7 @@ exports[`prompts - progress (isCI = false) > stop > renders message when errorin exports[`prompts - progress (isCI = false) > stop > renders message without removing dots 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -212,7 +212,7 @@ exports[`prompts - progress (isCI = false) > stop > renders message without remo exports[`prompts - progress (isCI = false) > stop > renders submit symbol and stops progress 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", "", @@ -226,7 +226,7 @@ exports[`prompts - progress (isCI = false) > stop > renders submit symbol and st exports[`prompts - progress (isCI = false) > style > renders block progressbar 1`] = ` [ "", - "│ + "│ ", "◒ ██████████ ", "", @@ -249,7 +249,7 @@ exports[`prompts - progress (isCI = false) > style > renders block progressbar 1 exports[`prompts - progress (isCI = false) > style > renders heavy progressbar 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━ ", "", @@ -272,7 +272,7 @@ exports[`prompts - progress (isCI = false) > style > renders heavy progressbar 1 exports[`prompts - progress (isCI = false) > style > renders light progressbar 1`] = ` [ "", - "│ + "│ ", "◒ ────────── ", "", @@ -295,7 +295,7 @@ exports[`prompts - progress (isCI = false) > style > renders light progressbar 1 exports[`prompts - progress (isCI = true) > message > sets message for next frame 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -309,7 +309,7 @@ exports[`prompts - progress (isCI = true) > message > sets message for next fram exports[`prompts - progress (isCI = true) > process exit handling > prioritizes cancel option over global setting 1`] = ` [ "", - "│ + "│ ", "■ Progress cancel message ", @@ -320,7 +320,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > prioritizes exports[`prompts - progress (isCI = true) > process exit handling > prioritizes error option over global setting 1`] = ` [ "", - "│ + "│ ", "▲ Progress error message ", @@ -331,7 +331,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > prioritizes exports[`prompts - progress (isCI = true) > process exit handling > uses custom cancel message when provided directly 1`] = ` [ "", - "│ + "│ ", "■ Custom cancel message ", @@ -342,7 +342,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > uses custom exports[`prompts - progress (isCI = true) > process exit handling > uses custom error message when provided directly 1`] = ` [ "", - "│ + "│ ", "▲ Custom error message ", @@ -353,7 +353,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > uses custom exports[`prompts - progress (isCI = true) > process exit handling > uses default cancel message 1`] = ` [ "", - "│ + "│ ", "■ Canceled ", @@ -364,7 +364,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > uses default exports[`prompts - progress (isCI = true) > process exit handling > uses global custom cancel message from settings 1`] = ` [ "", - "│ + "│ ", "■ Global cancel message ", @@ -375,7 +375,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > uses global exports[`prompts - progress (isCI = true) > process exit handling > uses global custom error message from settings 1`] = ` [ "", - "│ + "│ ", "▲ Global error message ", @@ -386,7 +386,7 @@ exports[`prompts - progress (isCI = true) > process exit handling > uses global exports[`prompts - progress (isCI = true) > start > renders frames at interval 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", ] @@ -395,7 +395,7 @@ exports[`prompts - progress (isCI = true) > start > renders frames at interval 1 exports[`prompts - progress (isCI = true) > start > renders message 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ foo...", ] @@ -404,7 +404,7 @@ exports[`prompts - progress (isCI = true) > start > renders message 1`] = ` exports[`prompts - progress (isCI = true) > start > renders timer when indicator is "timer" 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", ] @@ -413,7 +413,7 @@ exports[`prompts - progress (isCI = true) > start > renders timer when indicator exports[`prompts - progress (isCI = true) > stop > renders cancel symbol when calling cancel() 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -429,7 +429,7 @@ exports[`prompts - progress (isCI = true) > stop > renders cancel symbol when ca exports[`prompts - progress (isCI = true) > stop > renders error symbol when calling error() 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -445,7 +445,7 @@ exports[`prompts - progress (isCI = true) > stop > renders error symbol when cal exports[`prompts - progress (isCI = true) > stop > renders message 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -461,7 +461,7 @@ exports[`prompts - progress (isCI = true) > stop > renders message 1`] = ` exports[`prompts - progress (isCI = true) > stop > renders message when cancelling 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -477,7 +477,7 @@ exports[`prompts - progress (isCI = true) > stop > renders message when cancelli exports[`prompts - progress (isCI = true) > stop > renders message when erroring 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -493,7 +493,7 @@ exports[`prompts - progress (isCI = true) > stop > renders message when erroring exports[`prompts - progress (isCI = true) > stop > renders message without removing dots 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -509,7 +509,7 @@ exports[`prompts - progress (isCI = true) > stop > renders message without remov exports[`prompts - progress (isCI = true) > stop > renders submit symbol and stops progress 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " @@ -525,7 +525,7 @@ exports[`prompts - progress (isCI = true) > stop > renders submit symbol and sto exports[`prompts - progress (isCI = true) > style > renders block progressbar 1`] = ` [ "", - "│ + "│ ", "◒ ██████████ ...", " @@ -546,7 +546,7 @@ exports[`prompts - progress (isCI = true) > style > renders block progressbar 1` exports[`prompts - progress (isCI = true) > style > renders heavy progressbar 1`] = ` [ "", - "│ + "│ ", "◒ ━━━━━━━━━━ ...", " @@ -567,7 +567,7 @@ exports[`prompts - progress (isCI = true) > style > renders heavy progressbar 1` exports[`prompts - progress (isCI = true) > style > renders light progressbar 1`] = ` [ "", - "│ + "│ ", "◒ ────────── ...", " diff --git a/packages/prompts/test/__snapshots__/spinner.test.ts.snap b/packages/prompts/test/__snapshots__/spinner.test.ts.snap index 31412ea1..bb6d54fa 100644 --- a/packages/prompts/test/__snapshots__/spinner.test.ts.snap +++ b/packages/prompts/test/__snapshots__/spinner.test.ts.snap @@ -3,7 +3,7 @@ exports[`spinner (isCI = false) > can be aborted by a signal 1`] = ` [ "", - "│ + "│ ", "■ Canceled ", @@ -14,7 +14,7 @@ exports[`spinner (isCI = false) > can be aborted by a signal 1`] = ` exports[`spinner (isCI = false) > clear > stops and clears the spinner from the output 1`] = ` [ "", - "│ + "│ ", "◒ Loading", "", @@ -38,7 +38,7 @@ exports[`spinner (isCI = false) > global withGuide: false removes guide 1`] = ` exports[`spinner (isCI = false) > indicator customization > custom delay 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -61,7 +61,7 @@ exports[`spinner (isCI = false) > indicator customization > custom delay 1`] = ` exports[`spinner (isCI = false) > indicator customization > custom frame style 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -84,7 +84,7 @@ exports[`spinner (isCI = false) > indicator customization > custom frame style 1 exports[`spinner (isCI = false) > indicator customization > custom frames 1`] = ` [ "", - "│ + "│ ", "🐴 ", "", @@ -107,7 +107,7 @@ exports[`spinner (isCI = false) > indicator customization > custom frames 1`] = exports[`spinner (isCI = false) > indicator customization > custom frames with lots of frame have consistent ellipsis display 1`] = ` [ "", - "│ + "│ ", "0 ", "", @@ -307,10 +307,23 @@ exports[`spinner (isCI = false) > indicator customization > custom frames with l ] `; +exports[`spinner (isCI = false) > lines are indented as expected 1`] = ` +[ + "", + "│ +", + "◇ Foo +│ Bar +│ Biz +", + "", +] +`; + exports[`spinner (isCI = false) > message > sets message for next frame 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -327,7 +340,7 @@ exports[`spinner (isCI = false) > message > sets message for next frame 1`] = ` exports[`spinner (isCI = false) > process exit handling > prioritizes cancel option over global setting 1`] = ` [ "", - "│ + "│ ", "■ Spinner cancel message ", @@ -338,7 +351,7 @@ exports[`spinner (isCI = false) > process exit handling > prioritizes cancel opt exports[`spinner (isCI = false) > process exit handling > prioritizes error option over global setting 1`] = ` [ "", - "│ + "│ ", "▲ Spinner error message ", @@ -349,7 +362,7 @@ exports[`spinner (isCI = false) > process exit handling > prioritizes error opti exports[`spinner (isCI = false) > process exit handling > uses custom cancel message when provided directly 1`] = ` [ "", - "│ + "│ ", "■ Custom cancel message ", @@ -360,7 +373,7 @@ exports[`spinner (isCI = false) > process exit handling > uses custom cancel mes exports[`spinner (isCI = false) > process exit handling > uses custom error message when provided directly 1`] = ` [ "", - "│ + "│ ", "▲ Custom error message ", @@ -371,7 +384,7 @@ exports[`spinner (isCI = false) > process exit handling > uses custom error mess exports[`spinner (isCI = false) > process exit handling > uses default cancel message 1`] = ` [ "", - "│ + "│ ", "■ Canceled ", @@ -382,7 +395,7 @@ exports[`spinner (isCI = false) > process exit handling > uses default cancel me exports[`spinner (isCI = false) > process exit handling > uses global custom cancel message from settings 1`] = ` [ "", - "│ + "│ ", "■ Global cancel message ", @@ -393,7 +406,7 @@ exports[`spinner (isCI = false) > process exit handling > uses global custom can exports[`spinner (isCI = false) > process exit handling > uses global custom error message from settings 1`] = ` [ "", - "│ + "│ ", "▲ Global error message ", @@ -404,11 +417,11 @@ exports[`spinner (isCI = false) > process exit handling > uses global custom err exports[`spinner (isCI = false) > start > handles multi-line messages 1`] = ` [ "", - "│ + "│ ", "◒ foo -bar -baz", +│ bar +│ baz", "", "", "", @@ -421,10 +434,10 @@ baz", exports[`spinner (isCI = false) > start > handles wrapping 1`] = ` [ "", - "│ + "│ ", - "◒ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxx", + "◒ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +│ xxxxxxxxxxxxxxxxxxxxxxx", "", "", "", @@ -437,7 +450,7 @@ xxxxxxxxxxxxx", exports[`spinner (isCI = false) > start > renders frames at interval 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -460,7 +473,7 @@ exports[`spinner (isCI = false) > start > renders frames at interval 1`] = ` exports[`spinner (isCI = false) > start > renders message 1`] = ` [ "", - "│ + "│ ", "◒ foo", "", @@ -474,7 +487,7 @@ exports[`spinner (isCI = false) > start > renders message 1`] = ` exports[`spinner (isCI = false) > start > renders timer when indicator is "timer" 1`] = ` [ "", - "│ + "│ ", "◒ [0s]", "", @@ -488,7 +501,7 @@ exports[`spinner (isCI = false) > start > renders timer when indicator is "timer exports[`spinner (isCI = false) > stop > renders cancel symbol when calling cancel() 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -502,7 +515,7 @@ exports[`spinner (isCI = false) > stop > renders cancel symbol when calling canc exports[`spinner (isCI = false) > stop > renders error symbol when calling error() 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -516,7 +529,7 @@ exports[`spinner (isCI = false) > stop > renders error symbol when calling error exports[`spinner (isCI = false) > stop > renders message 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -530,7 +543,7 @@ exports[`spinner (isCI = false) > stop > renders message 1`] = ` exports[`spinner (isCI = false) > stop > renders message when cancelling 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -544,7 +557,7 @@ exports[`spinner (isCI = false) > stop > renders message when cancelling 1`] = ` exports[`spinner (isCI = false) > stop > renders message when erroring 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -558,7 +571,7 @@ exports[`spinner (isCI = false) > stop > renders message when erroring 1`] = ` exports[`spinner (isCI = false) > stop > renders message without removing dots 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -572,7 +585,7 @@ exports[`spinner (isCI = false) > stop > renders message without removing dots 1 exports[`spinner (isCI = false) > stop > renders submit symbol and stops spinner 1`] = ` [ "", - "│ + "│ ", "◒ ", "", @@ -598,7 +611,7 @@ exports[`spinner (isCI = false) > withGuide: false removes guide 1`] = ` exports[`spinner (isCI = true) > can be aborted by a signal 1`] = ` [ "", - "│ + "│ ", "■ Canceled ", @@ -609,7 +622,7 @@ exports[`spinner (isCI = true) > can be aborted by a signal 1`] = ` exports[`spinner (isCI = true) > clear > stops and clears the spinner from the output 1`] = ` [ "", - "│ + "│ ", "◒ Loading...", " @@ -637,7 +650,7 @@ exports[`spinner (isCI = true) > global withGuide: false removes guide 1`] = ` exports[`spinner (isCI = true) > indicator customization > custom delay 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -653,7 +666,7 @@ exports[`spinner (isCI = true) > indicator customization > custom delay 1`] = ` exports[`spinner (isCI = true) > indicator customization > custom frame style 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -669,7 +682,7 @@ exports[`spinner (isCI = true) > indicator customization > custom frame style 1` exports[`spinner (isCI = true) > indicator customization > custom frames 1`] = ` [ "", - "│ + "│ ", "🐴 ...", " @@ -685,7 +698,7 @@ exports[`spinner (isCI = true) > indicator customization > custom frames 1`] = ` exports[`spinner (isCI = true) > indicator customization > custom frames with lots of frame have consistent ellipsis display 1`] = ` [ "", - "│ + "│ ", "0 ...", " @@ -698,10 +711,23 @@ exports[`spinner (isCI = true) > indicator customization > custom frames with lo ] `; +exports[`spinner (isCI = true) > lines are indented as expected 1`] = ` +[ + "", + "│ +", + "◇ Foo +│ Bar +│ Biz +", + "", +] +`; + exports[`spinner (isCI = true) > message > sets message for next frame 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -722,7 +748,7 @@ exports[`spinner (isCI = true) > message > sets message for next frame 1`] = ` exports[`spinner (isCI = true) > process exit handling > prioritizes cancel option over global setting 1`] = ` [ "", - "│ + "│ ", "■ Spinner cancel message ", @@ -733,7 +759,7 @@ exports[`spinner (isCI = true) > process exit handling > prioritizes cancel opti exports[`spinner (isCI = true) > process exit handling > prioritizes error option over global setting 1`] = ` [ "", - "│ + "│ ", "▲ Spinner error message ", @@ -744,7 +770,7 @@ exports[`spinner (isCI = true) > process exit handling > prioritizes error optio exports[`spinner (isCI = true) > process exit handling > uses custom cancel message when provided directly 1`] = ` [ "", - "│ + "│ ", "■ Custom cancel message ", @@ -755,7 +781,7 @@ exports[`spinner (isCI = true) > process exit handling > uses custom cancel mess exports[`spinner (isCI = true) > process exit handling > uses custom error message when provided directly 1`] = ` [ "", - "│ + "│ ", "▲ Custom error message ", @@ -766,7 +792,7 @@ exports[`spinner (isCI = true) > process exit handling > uses custom error messa exports[`spinner (isCI = true) > process exit handling > uses default cancel message 1`] = ` [ "", - "│ + "│ ", "■ Canceled ", @@ -777,7 +803,7 @@ exports[`spinner (isCI = true) > process exit handling > uses default cancel mes exports[`spinner (isCI = true) > process exit handling > uses global custom cancel message from settings 1`] = ` [ "", - "│ + "│ ", "■ Global cancel message ", @@ -788,7 +814,7 @@ exports[`spinner (isCI = true) > process exit handling > uses global custom canc exports[`spinner (isCI = true) > process exit handling > uses global custom error message from settings 1`] = ` [ "", - "│ + "│ ", "▲ Global error message ", @@ -799,11 +825,11 @@ exports[`spinner (isCI = true) > process exit handling > uses global custom erro exports[`spinner (isCI = true) > start > handles multi-line messages 1`] = ` [ "", - "│ + "│ ", "◒ foo -bar -baz...", +│ bar +│ baz...", " ", "", @@ -818,10 +844,10 @@ baz...", exports[`spinner (isCI = true) > start > handles wrapping 1`] = ` [ "", - "│ + "│ ", - "◒ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxx...", + "◒ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +│ xxxxxxxxxxxxxxxxxxxxxxx...", " ", "", @@ -836,7 +862,7 @@ xxxxxxxxxxxxx...", exports[`spinner (isCI = true) > start > renders frames at interval 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -852,7 +878,7 @@ exports[`spinner (isCI = true) > start > renders frames at interval 1`] = ` exports[`spinner (isCI = true) > start > renders message 1`] = ` [ "", - "│ + "│ ", "◒ foo...", " @@ -868,7 +894,7 @@ exports[`spinner (isCI = true) > start > renders message 1`] = ` exports[`spinner (isCI = true) > start > renders timer when indicator is "timer" 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -884,7 +910,7 @@ exports[`spinner (isCI = true) > start > renders timer when indicator is "timer" exports[`spinner (isCI = true) > stop > renders cancel symbol when calling cancel() 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -900,7 +926,7 @@ exports[`spinner (isCI = true) > stop > renders cancel symbol when calling cance exports[`spinner (isCI = true) > stop > renders error symbol when calling error() 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -916,7 +942,7 @@ exports[`spinner (isCI = true) > stop > renders error symbol when calling error( exports[`spinner (isCI = true) > stop > renders message 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -932,7 +958,7 @@ exports[`spinner (isCI = true) > stop > renders message 1`] = ` exports[`spinner (isCI = true) > stop > renders message when cancelling 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -948,7 +974,7 @@ exports[`spinner (isCI = true) > stop > renders message when cancelling 1`] = ` exports[`spinner (isCI = true) > stop > renders message when erroring 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -964,7 +990,7 @@ exports[`spinner (isCI = true) > stop > renders message when erroring 1`] = ` exports[`spinner (isCI = true) > stop > renders message without removing dots 1`] = ` [ "", - "│ + "│ ", "◒ ...", " @@ -980,7 +1006,7 @@ exports[`spinner (isCI = true) > stop > renders message without removing dots 1` exports[`spinner (isCI = true) > stop > renders submit symbol and stops spinner 1`] = ` [ "", - "│ + "│ ", "◒ ...", " diff --git a/packages/prompts/test/spinner.test.ts b/packages/prompts/test/spinner.test.ts index 18896121..d0df12fa 100644 --- a/packages/prompts/test/spinner.test.ts +++ b/packages/prompts/test/spinner.test.ts @@ -53,22 +53,23 @@ describe.each(['true', 'false'])('spinner (isCI = %s)', (isCI) => { expect(output.buffer).toMatchSnapshot(); }); - test('renders message', () => { + test('handles wrapping', () => { + const columns = getColumns(output); const result = prompts.spinner({ output }); - result.start('foo'); + result.start('x'.repeat(columns + 10)); vi.advanceTimersByTime(80); - result.stop(); + result.stop('stopped'); expect(output.buffer).toMatchSnapshot(); }); - test('renders timer when indicator is "timer"', () => { - const result = prompts.spinner({ output, indicator: 'timer' }); + test('renders message', () => { + const result = prompts.spinner({ output }); - result.start(); + result.start('foo'); vi.advanceTimersByTime(80); @@ -77,15 +78,14 @@ describe.each(['true', 'false'])('spinner (isCI = %s)', (isCI) => { expect(output.buffer).toMatchSnapshot(); }); - test('handles wrapping', () => { - const columns = getColumns(output); - const result = prompts.spinner({ output }); + test('renders timer when indicator is "timer"', () => { + const result = prompts.spinner({ output, indicator: 'timer' }); - result.start('x'.repeat(columns + 10)); + result.start(); vi.advanceTimersByTime(80); - result.stop('stopped'); + result.stop(); expect(output.buffer).toMatchSnapshot(); }); @@ -427,6 +427,20 @@ describe.each(['true', 'false'])('spinner (isCI = %s)', (isCI) => { expect(output.buffer).toMatchSnapshot(); }); + test('lines are indented as expected', async () => { + const controller = new AbortController(); + const result = prompts.spinner({ + output, + signal: controller.signal, + }); + + result.start('Testing\n1, 2, 3'); + + result.stop('Foo\nBar\nBiz'); + + expect(output.buffer).toMatchSnapshot(); + }); + test('withGuide: false removes guide', () => { const result = prompts.spinner({ output, withGuide: false }); From a259beaa04b849d2e239e40773dbbec82008870e Mon Sep 17 00:00:00 2001 From: bq Date: Fri, 10 Jul 2026 13:21:58 +0200 Subject: [PATCH 2/2] changeset --- .changeset/shy-wolves-start.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/shy-wolves-start.md diff --git a/.changeset/shy-wolves-start.md b/.changeset/shy-wolves-start.md new file mode 100644 index 00000000..5aab8e20 --- /dev/null +++ b/.changeset/shy-wolves-start.md @@ -0,0 +1,5 @@ +--- +"@clack/prompts": patch +--- + +Fix `spinner`, `progress` and `task` not wrapping or prefixing newlines in their messages.