Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

progress bar (WIP) #3

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 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
15 changes: 15 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"presets": ["babel-preset-react"],
"env": {
"development": {
"plugins": [
[
"transform-react-jsx",
{
"pragma": "h"
}
]
]
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the Babel config in package.json

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

40 changes: 40 additions & 0 deletions docs/Bar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
The Bar component represents progress. See examples/progress.js for an example app.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a title: # Bar

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. ProgressBar.


## Usage

```js
const {h, Text, Bar} = require('ink');

<Bar
char="x"
progress={0.5}
left={5}
right={0}
green
/>
```

## Props

### char

The character to use for each item in the Bar. Defaults to █ (block).

### progress

The percentage (between 0 and 1) of progress in the Bar.

### left/right

The number of characters to subtract from each side of the Bar. examples/progress.js demonstrates this. Commonly used if you want text before/after the progress bar on the same line.


### {color}

Pass any chalk colors (e.g. `green`, `bgBlue`), similar to Text.

### ...

Any other props are passed to Text as-is.


49 changes: 49 additions & 0 deletions examples/progress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* @jsx h */
const {h, mount, Component, Text, Bar} = require('../');

const MAX = 20;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Max what? Would be nice if the variable name was more descriptive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried a different example.


class ProgressApp extends Component {
constructor() {
super();

this.state = {
i: 0
};
}

render() {
const text = `Running `;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just inline this. Everything else is inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in two places, should I hard code the length?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, didn't notice that. Would be nice if the bar just calculated the left thing automatically. Feels weird having to manually specify it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd have to know what else is on the line, or take the other content as a prop and render it itself, and it couldn't be custom components, and it might be a with multiple to have different colors.

It could have you either pass leftText (string) or leftSize (number), and if you pass leftText it'd render it. This seems confusing though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Ink should handle that for us. That's the behavior I expected. That would mean Ink would provide us the available screen space instead of us using process.stdout.columns directly. Let's wait and see what @vadimdemedes thinks.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good idea, I'd want that to be implemented natively too. Although I've been thinking and didn't come up with a way to solve this properly. Opened #5 to discuss this.

return (
<div>
<Text green>
{text}
</Text>
<Bar
blue
left={text.length}
percent={this.state.i / MAX}
/>
</div>
);
}

componentDidMount() {
this.timer = setInterval(() => {
const i = this.state.i + 1;
this.setState({i}, () => {
if (i === MAX) {
// eslint-disable-next-line unicorn/no-process-exit
process.exit();
}
});
}, 100);
}

componentWillUnmount() {
clearInterval(this.timer);
}
}

mount(<ProgressApp/>, process.stdout);

4 changes: 4 additions & 0 deletions examples/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

./node_modules/.bin/babel-node examples/$1.js

2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const Newline = require('./lib/components/newline');
const Indent = require('./lib/components/indent');
const Group = require('./lib/components/group');
const Text = require('./lib/components/text');
const Bar = require('./lib/components/bar');

exports.StringComponent = StringComponent;
exports.Component = Component;
Expand All @@ -19,6 +20,7 @@ exports.Newline = Newline;
exports.Indent = Indent;
exports.Group = Group;
exports.Text = Text;
exports.Bar = Bar;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just Bar is too ambiguous. ProgressBar would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


const noop = () => {};

Expand Down
36 changes: 36 additions & 0 deletions lib/components/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

const blacklist = require('blacklist');
const Component = require('../component');
const h = require('../h');
const Text = require('./text');

const PROPS = ['percent', 'left', 'right', 'columns', 'char'];

class Bar extends Component {
getString() {
const {
percent = 1,
left = 0,
right = 0,
char = '█'
} = this.props;
const screen = this.props.columns || process.stdout.columns || 80;
const space = screen - right - left;
let str = '';
const max = Math.min(Math.floor(space * percent), space);
for (let i = 0; i < max; i++) {
str += char;
}
Copy link
Collaborator

@sindresorhus sindresorhus Jul 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

char.repeat(max);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


return str;
}

render() {
const props = blacklist(this.props, PROPS);
return h(Text, props, this.getString());
}
}

module.exports = Bar;

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"node": ">= 4"
},
"scripts": {
"test": "xo && ava"
"test": "xo && ava",
"example:progress": "babel-node examples/progress.js"
},
"files": [
"lib",
Expand All @@ -25,6 +26,7 @@
],
"dependencies": {
"arrify": "^1.0.1",
"blacklist": "^1.1.4",
"chalk": "^2.0.1",
"indent-string": "^3.1.0",
"lodash.flattendeep": "^4.4.0",
Expand All @@ -33,7 +35,10 @@
},
"devDependencies": {
"ava": "^0.19.1",
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-register": "^6.24.1",
"eslint-config-xo-react": "^0.12.0",
"eslint-plugin-react": "^7.1.0",
Expand Down
16 changes: 16 additions & 0 deletions test/progress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import test from 'ava';

const Bar = require('../lib/components/bar.js');

const run = (columns, left, right) => Bar.prototype.getString.call({
props: {columns, left, right, char: 'x'}
});

test(`has correct length`, t => {
const str = run(50, 0, 0);
t.is(str.length, 50);

const str2 = run(60, 10, 9);
t.is(str2.length, 41);
});