Skip to content

Commit 2aee2da

Browse files
jeetisssindresorhus
authored andcommitted
Support changing the spinner while ora is running (#95)
1 parent 24ebe3b commit 2aee2da

File tree

4 files changed

+67
-8
lines changed

4 files changed

+67
-8
lines changed

example.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ setTimeout(() => {
2020
}, 2000);
2121

2222
setTimeout(() => {
23-
spinner.succeed();
23+
spinner.indent = 0;
24+
spinner.spinner = 'moon';
25+
spinner.text = 'Loading with different spinners';
2426
}, 3000);
2527

28+
setTimeout(() => {
29+
spinner.succeed();
30+
}, 4000);
31+
2632
// $ node example.js nameOfSpinner

index.js

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,13 @@ class Ora {
2222
stream: process.stderr
2323
}, options);
2424

25-
const sp = this.options.spinner;
26-
this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary
27-
28-
if (this.spinner.frames === undefined) {
29-
throw new Error('Spinner must define `frames`');
30-
}
25+
this.spinner = this.options.spinner;
3126

3227
this.color = this.options.color;
3328
this.hideCursor = this.options.hideCursor !== false;
3429
this.interval = this.options.interval || this.spinner.interval || 100;
3530
this.stream = this.options.stream;
3631
this.id = null;
37-
this.frameIndex = 0;
3832
this.isEnabled = typeof this.options.isEnabled === 'boolean' ? this.options.isEnabled : ((this.stream && this.stream.isTTY) && !process.env.CI);
3933

4034
// Set *after* `this.stream`
@@ -55,6 +49,31 @@ class Ora {
5549
this._indent = indent;
5650
}
5751

52+
get spinner() {
53+
return this._spinner;
54+
}
55+
56+
set spinner(spinner) {
57+
this.frameIndex = 0;
58+
59+
if (typeof spinner === 'object') {
60+
if (spinner.frames === undefined) {
61+
throw new Error('The given spinner must have a `frames` property');
62+
}
63+
64+
this._spinner = spinner;
65+
} else if (process.platform === 'win32') {
66+
this._spinner = cliSpinners.line;
67+
} else if (spinner === undefined) {
68+
// Set default spinner
69+
this._spinner = cliSpinners.dots;
70+
} else if (cliSpinners[spinner]) {
71+
this._spinner = cliSpinners[spinner];
72+
} else {
73+
throw new Error(`There is no built-in spinner named '${spinner}'. See https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json for a full list.`);
74+
}
75+
}
76+
5877
get text() {
5978
return this[TEXT];
6079
}

readme.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ Change the text.
188188

189189
Change the spinner color.
190190

191+
#### .spinner
192+
193+
Change the spinner.
194+
191195
#### .indent
192196

193197
Change the spinner indent.

test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,36 @@ test('erases wrapped lines', t => {
236236
spinner.stop();
237237
});
238238

239+
test('reset frameIndex when setting new spinner', async t => {
240+
const stream = getPassThroughStream();
241+
const output = getStream(stream);
242+
243+
const spinner = new Ora({
244+
stream,
245+
isEnabled: true,
246+
spinner: {frames: ['foo', 'fooo']}
247+
});
248+
249+
spinner.render();
250+
t.is(spinner.frameIndex, 1);
251+
252+
spinner.spinner = {frames: ['baz']};
253+
spinner.render();
254+
255+
stream.end();
256+
257+
t.is(spinner.frameIndex, 0);
258+
t.regex(stripAnsi(await output), /foo baz/);
259+
});
260+
261+
test('throw when incorrect spinner', t => {
262+
const ora = new Ora();
263+
264+
t.throws(() => {
265+
ora.spinner = 'random-string-12345';
266+
}, /no built-in spinner/);
267+
});
268+
239269
test('indent option', t => {
240270
const stream = getPassThroughStream();
241271
stream.isTTY = true;

0 commit comments

Comments
 (0)