cli-table / cli-table3

Pretty unicode tables for the command line
MIT License
534 stars 44 forks source link

[feature] border option between header and body #305

Open drahnieR opened 2 years ago

drahnieR commented 2 years ago

I want to do something like this, but looks like it's not possible. Or am I missing something?

┌──────┬─────────────────────┬─────────────────────────┬─────────────────┐
│ Rel  │ Change              │ By                      │ When            │
├──────┼─────────────────────┼─────────────────────────┼─────────────────┤
│ v0.1 │ Testing something … │ rauchg@gmail.com        │ 7 minutes ago   │
│ v0.1 │ Testing something … │ rauchg@gmail.com        │ 8 minutes ago   │
└──────┴─────────────────────┴─────────────────────────┴─────────────────┘
speedytwenty commented 1 year ago

Somehow, I overlooked this feature request. Reviewing this for the first time now.

What you seem to want IS possible! Albeit, it's slightly "wonky" in that you have to customize the cell border options for each cell in the first row (or second row if you don't specify your headings in the table's head option).

Example code with table.head option:

const table = new Table({
  head: ['H1', 'H2', 'H3'],
  chars: {
    'left-mid': '│',
    'right-mid': '│',
    mid: ' ',
    'mid-mid': '│',
  },
});

// First row chars
const chars = {
  midMid: '┼',
  mid: '─',
  leftMid: '├',
  rightMid: '┤',
};

table.push(
  ['foo', 'bar', 'baz'].map((content) => ({ content, chars })),
  ['frob', 'bar', 'quuz']
);

Outputs:

image

Example code without table.head option:

const table = new Table({
  chars: {
    'left-mid': '│',
    'right-mid': '│',
    mid: ' ',
    'mid-mid': '│',
  },
});

// First row chars
const chars = {
  midMid: '┼',
  mid: '─',
  leftMid: '├',
  rightMid: '┤',
};

table.push(
  ['fam', 'bam', 'sam'],
  ['foo', 'bar', 'baz'].map((content) => ({ content, chars })),
  ['frob', 'bar', 'quuz']
);

console.log(table.toString());

Outputs:

image

speedytwenty commented 1 year ago

I noticed that your example is a little different than what mine produce. Your example excludes the vertical space between rows—which is more appealing and saves the otherwise wasted space.

After a little more fiddling, I was able to add a one-line hack to the cell rendering to produce this:

image

Reopening as a feature request so that this feature can potentially be implemented.

A clean and intuitive method for achieving this isn't jumping out at me, however. I have previously considered methods for defining "table style presets", and this feature could be addressed if/when I get around to that (assuming someone doesn't beat me to it).

speedytwenty commented 1 year ago

I've got a new borders feature in the works. Just need to write a couple more tests and do the documentation.

The new feature offers the ability to more easily toggle borders on and off globally—which can presently be accomplished with table.chars.

The new functionality that the new feature offers is the ability to dynamically toggle borders on and off for each cell/row, which can be used specify borders by a cells x and/or y position.

I suppose the same could have been accomplished by manually customizing the border chars for each cell necessary, but this API is more straightforward and much less tedious.

Here is a teaser:

The second table resembles the borders requested by @drahnieR

image

Here is the code that produces the second table:

This feature does not yet exist as of v0.6.2!

const table = new Table({
  head: ['H1', 'H2', 'H3'],
  // Print top border for table top and top of second row
  borders: { top: (cell) => cell.y <= 1 }
});

table.push(['foo', 'bar', 'baz'], ['frob', 'bar', 'quuz']);

console.log('Table with horizontal border after heading:\n');
console.log(table.toString(), '\n');
speedytwenty commented 1 year ago

After fiddling with the border chars working on the new borders feature, I wanted to show that this is possible with the existing API.

This works out of the box with the current and previous versions:

const table = new Table({
  head: ['Rel', 'Change', 'By', 'When'],
  chars: {
    'left-mid': '',
    'right-mid': '',
    mid: '',
    'mid-mid': '',
  },
});

// First row chars
const chars = {
  midMid: '┼',
  mid: '─',
  leftMid: '├',
  rightMid: '┤',
};

table.push(
  ['v0.1', 'Testing something ...', 'rauch@gmail.com', '7 minutes ago'].map((content) => ({ content, chars })),
  ['v0.1', 'Testing something ...', 'rauch@gmail.com', '8 minutes ago']
);

console.log(table.toString());

Outputs:

image

The trick was setting all "mid" border chars to "".