[READ-ONLY] Mirror of https://github.com/bombshell-dev/clack. Effortlessly build beautiful command-line apps bomb.sh/docs/clack/basics/getting-started/
cli command-line command-line-app node prompt prompts
5

Configure Feed

Select the types of activity you want to include in your feed.

fix(prompts): Fix dots loader in spinner (#309)

authored by

MacFJA and committed by
GitHub
(Apr 29, 2025, 8:34 PM +0100) 2048eb1c 19558b9d

+240 -1
+5
.changeset/tall-cows-fold.md
··· 1 + --- 2 + "@clack/prompts": patch 3 + --- 4 + 5 + Fix spinner's dots behavior with custom frames
+2 -1
packages/prompts/src/spinner.ts
··· 128 128 } 129 129 130 130 frameIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0; 131 - indicatorTimer = indicatorTimer < frames.length ? indicatorTimer + 0.125 : 0; 131 + // indicator increase by 1 every 8 frames 132 + indicatorTimer = indicatorTimer < 4 ? indicatorTimer + 0.125 : 0; 132 133 }, delay); 133 134 }; 134 135
+219
packages/prompts/test/__snapshots__/spinner.test.ts.snap
··· 46 46 ] 47 47 `; 48 48 49 + exports[`spinner (isCI = false) > indicator customization > custom frames with lots of frame have consistent ellipsis display 1`] = ` 50 + [ 51 + "<cursor.hide>", 52 + "│ 53 + ", 54 + "0 ", 55 + "<cursor.backward count=999>", 56 + "<erase.down>", 57 + "1 ", 58 + "<cursor.backward count=999>", 59 + "<erase.down>", 60 + "2 ", 61 + "<cursor.backward count=999>", 62 + "<erase.down>", 63 + "3 ", 64 + "<cursor.backward count=999>", 65 + "<erase.down>", 66 + "4 ", 67 + "<cursor.backward count=999>", 68 + "<erase.down>", 69 + "5 ", 70 + "<cursor.backward count=999>", 71 + "<erase.down>", 72 + "6 ", 73 + "<cursor.backward count=999>", 74 + "<erase.down>", 75 + "7 ", 76 + "<cursor.backward count=999>", 77 + "<erase.down>", 78 + "8 .", 79 + "<cursor.backward count=999>", 80 + "<erase.down>", 81 + "9 .", 82 + "<cursor.backward count=999>", 83 + "<erase.down>", 84 + "0 .", 85 + "<cursor.backward count=999>", 86 + "<erase.down>", 87 + "1 .", 88 + "<cursor.backward count=999>", 89 + "<erase.down>", 90 + "2 .", 91 + "<cursor.backward count=999>", 92 + "<erase.down>", 93 + "3 .", 94 + "<cursor.backward count=999>", 95 + "<erase.down>", 96 + "4 .", 97 + "<cursor.backward count=999>", 98 + "<erase.down>", 99 + "5 .", 100 + "<cursor.backward count=999>", 101 + "<erase.down>", 102 + "6 ..", 103 + "<cursor.backward count=999>", 104 + "<erase.down>", 105 + "7 ..", 106 + "<cursor.backward count=999>", 107 + "<erase.down>", 108 + "8 ..", 109 + "<cursor.backward count=999>", 110 + "<erase.down>", 111 + "9 ..", 112 + "<cursor.backward count=999>", 113 + "<erase.down>", 114 + "0 ..", 115 + "<cursor.backward count=999>", 116 + "<erase.down>", 117 + "1 ..", 118 + "<cursor.backward count=999>", 119 + "<erase.down>", 120 + "2 ..", 121 + "<cursor.backward count=999>", 122 + "<erase.down>", 123 + "3 ..", 124 + "<cursor.backward count=999>", 125 + "<erase.down>", 126 + "4 ...", 127 + "<cursor.backward count=999>", 128 + "<erase.down>", 129 + "5 ...", 130 + "<cursor.backward count=999>", 131 + "<erase.down>", 132 + "6 ...", 133 + "<cursor.backward count=999>", 134 + "<erase.down>", 135 + "7 ...", 136 + "<cursor.backward count=999>", 137 + "<erase.down>", 138 + "8 ...", 139 + "<cursor.backward count=999>", 140 + "<erase.down>", 141 + "9 ...", 142 + "<cursor.backward count=999>", 143 + "<erase.down>", 144 + "0 ...", 145 + "<cursor.backward count=999>", 146 + "<erase.down>", 147 + "1 ...", 148 + "<cursor.backward count=999>", 149 + "<erase.down>", 150 + "2 ...", 151 + "<cursor.backward count=999>", 152 + "<erase.down>", 153 + "3 ", 154 + "<cursor.backward count=999>", 155 + "<erase.down>", 156 + "4 ", 157 + "<cursor.backward count=999>", 158 + "<erase.down>", 159 + "5 ", 160 + "<cursor.backward count=999>", 161 + "<erase.down>", 162 + "6 ", 163 + "<cursor.backward count=999>", 164 + "<erase.down>", 165 + "7 ", 166 + "<cursor.backward count=999>", 167 + "<erase.down>", 168 + "8 ", 169 + "<cursor.backward count=999>", 170 + "<erase.down>", 171 + "9 ", 172 + "<cursor.backward count=999>", 173 + "<erase.down>", 174 + "0 ", 175 + "<cursor.backward count=999>", 176 + "<erase.down>", 177 + "1 .", 178 + "<cursor.backward count=999>", 179 + "<erase.down>", 180 + "2 .", 181 + "<cursor.backward count=999>", 182 + "<erase.down>", 183 + "3 .", 184 + "<cursor.backward count=999>", 185 + "<erase.down>", 186 + "4 .", 187 + "<cursor.backward count=999>", 188 + "<erase.down>", 189 + "5 .", 190 + "<cursor.backward count=999>", 191 + "<erase.down>", 192 + "6 .", 193 + "<cursor.backward count=999>", 194 + "<erase.down>", 195 + "7 .", 196 + "<cursor.backward count=999>", 197 + "<erase.down>", 198 + "8 .", 199 + "<cursor.backward count=999>", 200 + "<erase.down>", 201 + "9 ..", 202 + "<cursor.backward count=999>", 203 + "<erase.down>", 204 + "0 ..", 205 + "<cursor.backward count=999>", 206 + "<erase.down>", 207 + "1 ..", 208 + "<cursor.backward count=999>", 209 + "<erase.down>", 210 + "2 ..", 211 + "<cursor.backward count=999>", 212 + "<erase.down>", 213 + "3 ..", 214 + "<cursor.backward count=999>", 215 + "<erase.down>", 216 + "4 ..", 217 + "<cursor.backward count=999>", 218 + "<erase.down>", 219 + "5 ..", 220 + "<cursor.backward count=999>", 221 + "<erase.down>", 222 + "6 ..", 223 + "<cursor.backward count=999>", 224 + "<erase.down>", 225 + "7 ...", 226 + "<cursor.backward count=999>", 227 + "<erase.down>", 228 + "8 ...", 229 + "<cursor.backward count=999>", 230 + "<erase.down>", 231 + "9 ...", 232 + "<cursor.backward count=999>", 233 + "<erase.down>", 234 + "0 ...", 235 + "<cursor.backward count=999>", 236 + "<erase.down>", 237 + "1 ...", 238 + "<cursor.backward count=999>", 239 + "<erase.down>", 240 + "2 ...", 241 + "<cursor.backward count=999>", 242 + "<erase.down>", 243 + "3 ...", 244 + "<cursor.backward count=999>", 245 + "<erase.down>", 246 + "◇ 247 + ", 248 + "<cursor.show>", 249 + ] 250 + `; 251 + 49 252 exports[`spinner (isCI = false) > message > sets message for next frame 1`] = ` 50 253 [ 51 254 "<cursor.hide>", ··· 283 486 "│ 284 487 ", 285 488 "🐴 ...", 489 + " 490 + ", 491 + "<cursor.backward count=999>", 492 + "<erase.down>", 493 + "◇ 494 + ", 495 + "<cursor.show>", 496 + ] 497 + `; 498 + 499 + exports[`spinner (isCI = true) > indicator customization > custom frames with lots of frame have consistent ellipsis display 1`] = ` 500 + [ 501 + "<cursor.hide>", 502 + "│ 503 + ", 504 + "0 ...", 286 505 " 287 506 ", 288 507 "<cursor.backward count=999>",
+14
packages/prompts/test/spinner.test.ts
··· 173 173 expect(output.buffer).toMatchSnapshot(); 174 174 }); 175 175 176 + test('custom frames with lots of frame have consistent ellipsis display', () => { 177 + const result = prompts.spinner({ output, frames: Object.keys(Array(10).fill(0)) }); 178 + 179 + result.start(); 180 + 181 + for (let i = 0; i < 64; i++) { 182 + vi.advanceTimersByTime(80); 183 + } 184 + 185 + result.stop(); 186 + 187 + expect(output.buffer).toMatchSnapshot(); 188 + }); 189 + 176 190 test('custom delay', () => { 177 191 const result = prompts.spinner({ output, delay: 200 }); 178 192