-
-
Notifications
You must be signed in to change notification settings - Fork 622
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
Changes from 11 commits
753ee45
a0f169f
2106c57
5d3e29f
3aaab27
845464b
c954ed4
f93b307
b0fc294
4cfe8aa
c0333a9
16c60ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# ProgressBar | ||
|
||
The ProgressBar component represents progress. See examples/progress.js for an example app. | ||
|
||
## Usage | ||
|
||
```js | ||
const {h, Text, ProgressBar} = require('ink'); | ||
|
||
<ProgressBar | ||
char="x" | ||
progress={0.5} | ||
left={5} | ||
right={0} | ||
green | ||
/> | ||
``` | ||
|
||
## Props | ||
|
||
### char | ||
|
||
The character to use for each item in the ProgressBar. Defaults to █ (block). | ||
|
||
### progress | ||
|
||
The percentage (between 0 and 1) of progress in the ProgressBar. | ||
|
||
### left/right | ||
|
||
The number of characters to subtract from each side of the ProgressBar. 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. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* @jsx h */ | ||
const {h, mount, Component, Text, ProgressBar} = require('../'); | ||
|
||
const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); | ||
|
||
const TASKS = 30; | ||
|
||
class ProgressApp extends Component { | ||
constructor() { | ||
super(); | ||
|
||
this.state = { | ||
done: 0 | ||
}; | ||
} | ||
|
||
render() { | ||
const text = `Running `; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just inline this. Everything else is inline. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used in two places, should I hard code the length? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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> | ||
<ProgressBar | ||
blue | ||
left={text.length} | ||
percent={this.state.done / TASKS} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
componentDidMount() { | ||
const promises = Array.from({length: TASKS}, () => | ||
delay(Math.floor(Math.random() * 1500)) | ||
.then(() => { | ||
this.setState(state => ({done: state.done + 1})); | ||
}) | ||
); | ||
|
||
Promise.all(promises) | ||
.then(() => delay(50)) | ||
// eslint-disable-next-line unicorn/no-process-exit | ||
.then(() => process.exit(0)); | ||
} | ||
} | ||
|
||
mount(<ProgressApp/>, process.stdout); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/bash | ||
|
||
./node_modules/.bin/babel-node examples/$1.js | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
'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; | ||
const max = Math.min(Math.floor(space * percent), space); | ||
return char.repeat(max); | ||
} | ||
|
||
render() { | ||
const props = blacklist(this.props, PROPS); | ||
return h(Text, props, this.getString()); | ||
} | ||
} | ||
|
||
module.exports = Bar; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import test from 'ava'; | ||
|
||
const ProgressBar = require('../lib/components/progress-bar.js'); | ||
|
||
const run = (columns, left, right) => ProgressBar.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); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
char => character
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed