Module: panel - uhop/console-toolkit GitHub Wiki
The panel.js module provides
a Panel
class, which is a 2D array of cells corresponding to characters (one position) on the screen.
Each cell can be empty (null
), or an object with symbol
and state
properties.
See Concepts.
The Panel
class works closely with the Box class and
strings. All three can be easily converted between each other.
panel.js
import Panel from 'console-toolkit/panel.js';
This module defines the Panel
class.
Panel
Class import Panel from 'console-toolkit/panel.js';
import Box from 'console-toolkit/box.js';
import style from 'console-toolkit/style.js';
const panel = new Panel(7, 5),
box = Box.make('one\ntwo\nthree', {align: 'center'}),
errorStyle = style.bold.bright.yellow.bg.red;
panel.put(1, 1, box).fillState({state: errorStyle});
for (const line of panel.toStrings()) console.log(line);
This is the most elaborate text container out of three. It provides the following members:
Name | Return | Description |
---|---|---|
constructor(width, height) |
Panel |
Creates a new Panel object with empty cells. |
width |
number | The width of the panel. |
height |
number | The height of the panel. |
box |
array | The 2D array of cells. |
toStrings({emptySymbol = ' ', emptyState = RESET_STATE}) |
strings | Returns the panel as an array of strings. Empty cells are filled with emptySymbol and emptyState . |
toBox({emptySymbol = ' ', emptyState = RESET_STATE}) |
Box |
Returns the panel as a Box object. Empty cells are filled with emptySymbol and emptyState . |
extract(x, y, width, height) |
Panel |
Extracts a sub-panel from the panel. |
clone() |
Panel |
Returns a copy of the panel. |
toPanel() |
Panel |
An alias for clone() . |
copyFrom(x, y, width, height, panel, x1 = 0, y1 = 0) |
this |
Copies the contents of the panel from the specified rectangle to panel at x1 and y1 . |
put(x, y, box, {emptySymbol = '\x07'} = {}) |
this |
Puts box at x and y treating emptySymbol as an empty cell. |
The methods that work on the cell level:
Name | Return | Description |
---|---|---|
applyFn(x, y, width, height, fn, options) |
this |
Applies fn to every cell in the given rectangle in the panel. |
applyFn(fn) |
this |
Applies fn to every cell in the panel. |
fill(x, y, width, height, symbol, state = {}, options) |
this |
Fills the given rectangle in the panel with symbol and state properties. |
fill(symbol, state = {}) |
this |
Fills the panel with symbol and state properties. |
fillState(x, y, width, height, {emptySymbol = ' ', state = ''}) |
this |
Fills the given rectangle in the panel with the state property using emptySymbol for empty cells. |
fillState({emptySymbol = ' ', state = ''}) |
this |
Fills the panel with the state property using emptySymbol for empty cells. |
fillNonEmptyState(x, y, width, height, {state = ''}) |
this |
Fills the given rectangle of non-empty cells in the panel with the state property. |
fillNonEmptyState({state = ''}) |
this |
Fills the non-empty cells in the panel with the state property. |
combineStateBefore(x, y, width, height, {state = {}, emptySymbol = ' ', emptyState = RESET_STATE}) |
this |
Combines the state of the cells in the given rectangle with the state property. Empty cells are assumed to have emptySymbol and emptyState . |
combineStateBefore({state = {}, emptySymbol = ' ', emptyState = RESET_STATE}) |
this |
Combines the state of the cells in the panel with the state property. Empty cells are assumed to have emptySymbol and emptyState . |
combineStateAfter(x, y, width, height, {state = {}, emptySymbol = ' ', emptyState = RESET_STATE}) |
this |
Combines the state of the cells in the given rectangle with the state property. Empty cells are assumed to have emptySymbol and emptyState . |
combineStateAfter({state = {}, emptySymbol = ' ', emptyState = RESET_STATE}) |
this |
Combines the state of the cells in the panel with the state property. Empty cells are assumed to have emptySymbol and emptyState . |
combineState(...args) |
this |
An alias for combineStateAfter() . |
clear(x, y, width, height, options) |
this |
Clears the given rectangle in the panel making cells empty. |
clear() |
this |
Clears the panel making cells empty. |
The padding methods:
Name | Return | Description |
---|---|---|
padLeft(n) |
this |
Pads the left side of the panel with n empty cells. |
padRight(n) |
this |
Pads the right side of the panel with n empty cells. |
padLeftRight(n, m) |
this |
Pads the left and right side of the panel with n and m empty cells. |
padTop(n) |
this |
Pads the top side of the panel with n empty rows. |
padBottom(n) |
this |
Pads the bottom side of the panel with n empty rows. |
padTopBottom(n, m) |
this |
Pads the top and bottom side of the panel with n and m empty rows. |
pad(t, r, b, l) |
this |
Pads the panel with t , r , b , and l empty rows/cells. |
The removing/inserting and resizing methods:
Name | Return | Description |
---|---|---|
removeColumns(x, n) |
this |
Removes n columns starting at x . |
removeRows(y, n) |
this |
Removes n rows starting at y . |
insertColumns(x, n) |
this |
Inserts n empty columns starting at x . |
insertRows(y, n) |
this |
Inserts n empty rows starting at y . |
resizeH(newWidth, align = 'right') |
this |
Resizes the panel horizontally. |
resizeV(newHeight, align = 'bottom') |
this |
Resizes the panel vertically. |
resize(newWidth, newHeight, horizontal = 'right', vertical = 'bottom') |
this |
Resizes the panel. |
The stacking methods:
Name | Return | Description |
---|---|---|
addBottom(panel, {align = 'left'}) |
this |
Adds panel to the bottom of the panel. |
addRight(panel, {align = 'top'}) |
this |
Adds panel to the right of the panel. |
The geometric transformation methods:
Name | Return | Description |
---|---|---|
transpose() |
Panel |
Transposes the panel. It rotates it around the main axis. |
rotateRight() |
Panel |
Rotates the panel 90 degrees to the right. |
rotateLeft() |
Panel |
Rotates the panel 90 degrees to the left. |
flipH() |
this |
Flips the panel horizontally. |
flipV() |
this |
Flips the panel vertically. |
Notes on APIs and semantics
An empty cell is represented by null
. They are used when a Panel
object is created,
when it is padded, when it is cleared, and when rows or columns are inserted. When a panel
is converted to a Box
or strings, the API takes a symbol and a state, which are used
when rendering empty cells. Usually the symbol is space (
) and the state is RESET_STATE
.
Non-empty cells are represented by {symbol, state}
objects. symbol
should be a string
that renders as a single character on the scree. It cannot include ASCI escape sequences, but
can be an arbitrary Unicode character. state
is an object similar to RESET_STATE
. See
state for a description of the properties.
constructor()
creates a new Panel
object with the given width and height filled with empty cells.
put(x, y, box, emptySymbol = '\x07')
inserts a text box at the given location. Strings can have
SGR sequences, which will be correctly interpreted. emptySymbol
defines a character that will be
interpreted as an empty cell. By default it is BELL
(ASCII 7).
applyFn(x, y, width, height, fn, options)
applies fn
to every cell in the given rectangle in the panel.
It serves as the foundation for all other cell level methods. fn(x, y, cell)
takes the position
of the cell and the cell object. It returns the new cell object or undefined
. The new cell object
will replace the old cell. options
is an object, which is passed to size()
of
strings/split.js used to calculate a width of the returned character. Other
applyFn()
-based methods can take the same options
as an argument. See how the methods are
defined above.
combineStateAfter()
and combineStateBefore()
combine the state of the cells in the given rectangle
with the state
. Empty cells are assumed to have emptySymbol
and emptyState
. The application
of states is not symmetric:
import {Colors, Commands, getColor} from 'console-toolkit/ansi/colors.js';
import {combineStates} from 'console-toolkit/ansi/sgr-state.js';
const state1 = {bold: null, foreground: getColor(Colors.RED)};
const state2 = {bold: Commands.BOLD, background: getColor(Colors.GREEN)};
const before = combineStates(state1, state2);
// {bold: Commands.BOLD, foreground: getColor(Colors.RED), background: getColor(Colors.GREEN)}
const after = combineStates(state2, state1);
// {bold: null, background: getColor(Colors.GREEN), foreground: getColor(Colors.RED)}
So if we want to define some generic properties they should be applied "before". If we want to override the generic properties they should be applied "after".
addRight()
and addBottom()
stack the panel
argument on the current panel. If panels are
of different sizes, the extra space of the smaller panel is padded with empty cells.
transpose()
rotates the panel around the main axis. If the original panel was 3 by 4,
the transposed panel will be 4 by 3:
import Panel from 'console-toolkit/panel.js';
const panel = new Panel(3, 4);
// ...
const transposed = panel.transpose();
panel.width === transposed.height;
panel.height === transposed.width;
t.deepEqual(panel.box[0][0], transposed.box[0][0]);
t.deepEqual(panel.box[3][2], transposed.box[2][3]);
t.deepEqual(panel.box[0][2], transposed.box[2][0]);
t.deepEqual(panel.box[3][0], transposed.box[0][3]);
rotateRight()
and rotateLeft()
rotate the panel 90 degrees to the right and left, respectively.
Just like transpose()
, they produce a new panel of H by W size.
toPanel()
Function The toPanel()
method is an alias for Panel.make()
.
Exports
The Panel
class is exported by name and as the default export. toPanel()
is exported by name.