Skip to content

Commit b30ce17

Browse files
author
Vadim Demedes
authored
Migrate to Ink 2 (#2)
1 parent 7f419e4 commit b30ce17

File tree

6 files changed

+77
-141
lines changed

6 files changed

+77
-141
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
node_modules
22
yarn.lock
3-
dist
3+
build

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
language: node_js
22
node_js:
3+
- '10'
34
- '8'
4-
- '6'

package.json

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@
99
"email": "[email protected]",
1010
"url": "github.com/vadimdemedes"
1111
},
12-
"main": "dist/index.js",
12+
"main": "build/index.js",
1313
"engines": {
14-
"node": ">=6"
14+
"node": ">=8"
1515
},
1616
"scripts": {
1717
"pretest": "npm run build",
1818
"test": "xo && ava",
19-
"build": "babel src --out-dir=dist",
20-
"prepublish": "npm run build"
19+
"build": "babel src --out-dir=build",
20+
"prepare": "npm run build"
2121
},
2222
"files": [
23-
"dist"
23+
"build"
2424
],
2525
"keywords": [
2626
"ink",
@@ -32,62 +32,38 @@
3232
"jsx",
3333
"react"
3434
],
35-
"peerDependencies": {
36-
"ink": "^0.5.0"
37-
},
3835
"dependencies": {
3936
"cli-spinners": "^1.0.0",
40-
"object.omit": "^2.0.1",
4137
"prop-types": "^15.5.10"
4238
},
4339
"devDependencies": {
44-
"ava": "^0.20.0",
45-
"babel-cli": "^6.24.1",
46-
"babel-plugin-transform-react-jsx": "^6.24.1",
40+
"@babel/cli": "^7.2.3",
41+
"@babel/core": "^7.3.3",
42+
"@babel/plugin-proposal-class-properties": "^7.3.3",
43+
"@babel/preset-react": "^7.0.0",
44+
"ava": "*",
45+
"babel-eslint": "^10.0.1",
46+
"delay": "^4.1.0",
4747
"eslint-config-xo-react": "^0.13.0",
4848
"eslint-plugin-react": "^7.1.0",
49-
"ink": "^0.5.0",
49+
"ink": "^2.0.0",
50+
"react": "^16.8.2",
5051
"sinon": "^2.3.6",
51-
"xo": "^0.18.2"
52+
"xo": "*"
5253
},
5354
"babel": {
5455
"plugins": [
55-
[
56-
"transform-react-jsx",
57-
{
58-
"pragma": "h",
59-
"useBuiltIns": true
60-
}
61-
]
56+
"@babel/plugin-proposal-class-properties"
57+
],
58+
"presets": [
59+
"@ava/stage-4",
60+
"@babel/preset-react"
6261
]
6362
},
64-
"ava": {
65-
"babel": {
66-
"presets": [
67-
"@ava/stage-4"
68-
],
69-
"plugins": [
70-
[
71-
"transform-react-jsx",
72-
{
73-
"pragma": "h",
74-
"useBuiltIns": true
75-
}
76-
]
77-
]
78-
}
79-
},
8063
"xo": {
64+
"parser": "babel-eslint",
8165
"extends": [
8266
"xo-react"
83-
],
84-
"rules": {
85-
"react/no-unused-prop-types": 1
86-
},
87-
"settings": {
88-
"react": {
89-
"pragma": "h"
90-
}
91-
}
67+
]
9268
}
9369
}

readme.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ $ npm install ink-spinner
1313
## Usage
1414

1515
```js
16-
const {h, render} = require('ink');
17-
const Spinner = require('ink-spinner');
16+
import React from 'react';
17+
import {render, Color} from 'ink';
18+
import Spinner from 'ink-spinner';
1819

1920
render((
20-
<div>
21-
<Spinner green/> Loading
22-
</div>
21+
<Color green>
22+
<Spinner green/>{' '}Loading
23+
</Color>
2324
));
2425
```
2526

@@ -28,8 +29,6 @@ render((
2829

2930
## Props
3031

31-
All props except the own ones listed below are passed as-is to `<Color>`, which means you can easily apply any color, without wrapping `<Spinner>` in `<Color>` manually.
32-
3332
### type
3433

3534
Type: `string`<br>

src/index.js

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,46 @@
1-
'use strict';
2-
3-
const {h, Color, Component} = require('ink');
4-
const PropTypes = require('prop-types');
5-
const spinners = require('cli-spinners');
6-
const omit = require('object.omit');
7-
8-
class Spinner extends Component {
9-
constructor(props) {
10-
super(props);
11-
12-
this.state = {
13-
frame: 0
14-
};
1+
import React, {Component} from 'react';
2+
import PropTypes from 'prop-types';
3+
import {Box} from 'ink';
4+
import spinners from 'cli-spinners';
5+
6+
export default class Spinner extends Component {
7+
static propTypes = {
8+
type: PropTypes.string
9+
}
1510

16-
this.switchFrame = this.switchFrame.bind(this);
11+
static defaultProps = {
12+
type: 'dots'
1713
}
1814

19-
getSpinner() {
20-
return spinners[this.props.type] || spinners.dots;
15+
state = {
16+
frame: 0
2117
}
2218

23-
render(props, {frame}) {
24-
const colorProps = omit(props, 'type');
19+
render() {
2520
const spinner = this.getSpinner();
2621

2722
return (
28-
<Color {...colorProps}>
29-
{spinner.frames[frame]}
30-
</Color>
23+
<Box>
24+
{spinner.frames[this.state.frame]}
25+
</Box>
3126
);
3227
}
3328

3429
componentDidMount() {
3530
const spinner = this.getSpinner();
36-
3731
this.timer = setInterval(this.switchFrame, spinner.interval);
3832
}
3933

4034
componentWillUnmount() {
4135
clearInterval(this.timer);
4236
}
4337

44-
switchFrame() {
45-
const {frame} = this.state;
38+
getSpinner() {
39+
return spinners[this.props.type] || spinners.dots;
40+
}
4641

42+
switchFrame = () => {
43+
const {frame} = this.state;
4744
const spinner = this.getSpinner();
4845
const isLastFrame = frame === spinner.frames.length - 1;
4946
const nextFrame = isLastFrame ? 0 : frame + 1;
@@ -53,13 +50,3 @@ class Spinner extends Component {
5350
});
5451
}
5552
}
56-
57-
Spinner.propTypes = {
58-
type: PropTypes.string
59-
};
60-
61-
Spinner.defaultProps = {
62-
type: 'dots'
63-
};
64-
65-
module.exports = Spinner;

test.js

Lines changed: 25 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,36 @@
1-
import {h, build, Color} from 'ink';
2-
import renderToString from 'ink/lib/render-to-string';
3-
import {stub} from 'sinon';
1+
import EventEmitter from 'events';
2+
import React from 'react';
3+
import {render} from 'ink';
4+
import {spy} from 'sinon';
45
import spinners from 'cli-spinners';
56
import test from 'ava';
7+
import delay from 'delay';
68
import Spinner from '.';
79

8-
test('render', t => {
9-
let component;
10+
test('render spinner', async t => {
11+
const stdout = {
12+
columns: 100,
13+
write: spy()
14+
};
1015

11-
function setRef(ref) {
12-
component = ref;
13-
}
16+
const stdin = new EventEmitter();
17+
stdin.setRawMode = () => {};
18+
stdin.setEncoding = () => {};
19+
stdin.pause = () => {};
1420

1521
const spinner = spinners.dots;
16-
let tree;
22+
const app = render(<Spinner/>, {
23+
stdout,
24+
stdin,
25+
debug: true
26+
});
1727

18-
for (let frame = 0; frame < spinner.frames.length; frame++) {
19-
tree = build(<Spinner ref={setRef}/>, tree);
20-
t.is(renderToString(tree), spinner.frames[frame]);
28+
await delay(spinner.frames.length * spinner.interval);
29+
app.unmount();
2130

22-
component.setState({
23-
frame: frame + 1
24-
});
25-
}
26-
});
27-
28-
test('pass props to <Color>', t => {
29-
const spinner = spinners.dots;
30-
31-
const actual = build(<Spinner green/>);
32-
const expected = build(<Color green>{spinner.frames[0]}</Color>);
33-
34-
t.is(renderToString(actual), renderToString(expected));
35-
});
36-
37-
test('spin', t => {
38-
stub(Spinner.prototype, 'setState');
39-
40-
let component;
41-
42-
function setRef(ref) {
43-
component = ref;
44-
}
45-
46-
build(<Spinner ref={setRef}/>);
47-
48-
const spinner = spinners.dots;
49-
50-
let frame = 1;
51-
let i = 0;
52-
53-
while (i < spinner.frames.length * 2) {
54-
component.switchFrame();
55-
56-
t.deepEqual(component.setState.getCall(i).args[0], {frame});
57-
component.state = {frame};
31+
const allFrames = stdout.write.args.map(args => args[0]);
32+
const frames = [...new Set(allFrames)];
5833

59-
frame = frame === spinner.frames.length - 1 ? 0 : frame + 1;
60-
i++;
61-
}
34+
t.deepEqual(frames, spinner.frames);
35+
t.pass();
6236
});

0 commit comments

Comments
 (0)