nathanpeck / clui

Command Line UI toolkit for Node.js
MIT License
1.66k stars 40 forks source link

Right alignment #10

Open wayne-nlt opened 8 years ago

wayne-nlt commented 8 years ago

Being able to align to the right would be really handy, especially for numeric values.

I noticed that Line.column won't accept numbers either, maybe it could look at the type of the data passed in and left align for text, and right align for numbers?

artokun commented 7 years ago

Feel free to make a PR if you have a solution. If not I can look into this later once I finish cleaning up other issues

larvata commented 6 years ago

I wrote a util func to approach this

const COLUMN_TEXT_ALIGN = {
  RIGHT: 'RIGHT',
  LEFT: 'LEFT',
  MIDDLE: 'MIDDLE',
};

Line.prototype.columnEx = function (text = '', width = 1, style, options = {}) {
  const {
    repeat = false,
    position = COLUMN_TEXT_ALIGN.LEFT,
  } = options;

  const params = {
    text,
    width,
    style,
    leftPadding: 0,
    rightPadding: 0,
  };

  if (repeat) {
    params.text = text.repeat(width).substr(0, width);
  }

  if (position === COLUMN_TEXT_ALIGN.LEFT) {
    params.rightPadding = width - params.text.length;
  }
  else if (position === COLUMN_TEXT_ALIGN.RIGHT) {
    params.leftPadding = width - params.text.length;
  }
  else if (position === COLUMN_TEXT_ALIGN.MIDDLE) {
    params.leftPadding = Math.floor(parseInt((width - params.text.length), 10) / 2);
    params.rightPadding = width - params.text.length - params.leftPadding;
  }

  params.leftPadding && this.padding(params.leftPadding);
  this.column(params.text, params.text.length, style);
  params.rightPadding && this.padding(params.rightPadding);

  return this;
};
// draw a right aligned text in a box
new Line()
  .columnEx('┌')
  .columnEx('─', 48, [], { repeat: true })
  .columnEx('┐')
  .fill()
  .output();

new Line()
  .columnEx('│')
  .columnEx('text at right', 47, [clc.yellow], { position: COLUMN_TEXT_ALIGN.RIGHT })
  .padding(1)
  .columnEx('│')
  .fill()
  .output();

new Line()
  .columnEx('└', 1)
  .columnEx('─', 48, [], { repeat: true })
  .columnEx('┘', 1)
  .fill()
  .output();
# output
┌────────────────────────────────────────────────┐                                                                                                                                                   
│                                  text at right │                                                                                                                                                   
└────────────────────────────────────────────────┘