Skip to content

Package: progress bar

Eugene Lazutkin edited this page Sep 26, 2026 · 2 revisions

The progress-bar package draws one-line progress bars in several skins, with separate colors for the done part and the rest, and makes moving bars for work with no known total.

Function drawProgressBar()

drawProgressBar(fraction, width, options) returns a string exactly width cells wide. fraction is the completed part, clamped to the range 0–1; a non-finite value draws an empty bar. A step shows only once it is reached, so the bar is full only at 1. With the default skin, the cell at the boundary uses a 1/8th-step Unicode block, so the bar moves smoothly:

import {drawProgressBar} from 'console-toolkit/progress-bar';

drawProgressBar(0, 10); // '░░░░░░░░░░'
drawProgressBar(0.55, 10); // '█████▌░░░░'
drawProgressBar(1, 10); // '██████████'

options is an object with the following optional properties:

  • skin — the glyphs to draw with. Default: blocks. See Skins.
  • fillStyle — a style for the done part: any object with a text() method, such as a Style from style. Default: no styling.
  • trackStyle — a style for the rest of the bar. If it sets a background color, the background also shows behind the partial cell at the boundary. Default: no styling.

Colors

Give the done part and the rest different colors with fillStyle and trackStyle:

import style from 'console-toolkit/style.js';
import {drawProgressBar} from 'console-toolkit/progress-bar';
import {colorLine} from 'console-toolkit/progress-bar/skins.js';

drawProgressBar(0.42, 30, {fillStyle: style.green, trackStyle: style.white});
drawProgressBar(0.42, 30, {skin: colorLine, fillStyle: style.brightWhite, trackStyle: style.gray});

To show a finished bar differently, pick the style from your own state, for example fillStyle: done ? style.green : style.cyan.

Skins

The console-toolkit/progress-bar/skins.js module exports ready-made skins. The samples show 55% at a width of 10 or 12; · stands for a space.

Skin Sample Notes
blocks █████▌░░░░ The default. 1/8th-cell steps over a light shade.
solid █████▌···· A blank track; give trackStyle a background color.
capped ▕█████▌····▏ Thin end caps.
shades █████▒···· Shade steps (░▒▓) over a blank track.
halves █████▌░░░░ Half-cell steps.
line ━━━━━╸──── A heavy line over a thin one, with half-cell steps.
colorLine ━━━━━╸━━━━ One heavy line; the two parts differ only by fillStyle and trackStyle.
dots ⣿⣿⣿⣿⣿⡇⣀⣀⣀⣀ Braille dots with 1/8th-cell steps.
ascii [====>·····] ASCII with a head.
hash [#####-----] ASCII hashes over dashes.

A skin is a plain object, so you can make your own or change a preset:

import {drawProgressBar} from 'console-toolkit/progress-bar';
import {blocks} from 'console-toolkit/progress-bar/skins.js';

drawProgressBar(0.5, 10, {skin: {...blocks, track: '·'}}); // '█████·····'
drawProgressBar(0.5, 10, {skin: {fill: '*', track: ' ', left: '(', right: ')'}}); // '(****    )'

A skin has the following properties. Every glyph must be one cell wide.

  • fill — the glyph for a filled cell.
  • partials — glyphs for a partly filled cell, from least to most filled. Each one adds a step per cell. Optional.
  • track — the glyph for an unfilled cell.
  • trackStart — the glyph for the first unfilled cell after a whole number of filled cells. Optional.
  • head — the glyph for the last filled cell of an unfinished bar without a partial cell. Optional.
  • left, right — end caps, counted in the width. They are dropped when they don't fit. Optional.

To redraw a bar in place while work progresses, return it from an Updater frame.

Function makeIndeterminateBar()

For work with no known total, makeIndeterminateBar(width, options) makes a spinner definition: a segment of the skin's fill moving across its track, one cell a frame. Pass it to Spinner from spinner, and drive it with spin or an Updater like any other spinner:

import {Spinner} from 'console-toolkit/spinner';
import {makeIndeterminateBar} from 'console-toolkit/progress-bar';

const bar = new Spinner(makeIndeterminateBar(10));
// frames: '██░░░░░░░░', '░██░░░░░░░', '░░██░░░░░░', … and back

The definition also has an empty bar for the not-started state and a full bar for the finished state, so a finished spinner shows a complete bar.

options takes the same skin, fillStyle, and trackStyle as drawProgressBar(), plus:

  • segment — the length of the moving segment in cells. Default: a quarter of the bar, at least 1.
  • motion — 'bounce' moves the segment back and forth; 'loop' slides it through and starts again from the left. Default: 'bounce'. Any other value throws a RangeError.
import {ascii} from 'console-toolkit/progress-bar/skins.js';

makeIndeterminateBar(12, {skin: ascii, segment: 3, motion: 'loop'});
// frames: '[=         ]', '[==        ]', '[===       ]', '[ ===      ]', … '[         =]'

The segment moves by whole cells and uses the skin's fill, track, and end caps; partials, head, and trackStart apply to drawProgressBar() only.

Clone this wiki locally