Skip to content

Commit

Permalink
Fix borderStyle: 'none' (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
roydukkey committed Jul 4, 2023
1 parent b064762 commit ef5c987
Show file tree
Hide file tree
Showing 19 changed files with 131 additions and 23 deletions.
56 changes: 38 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import wrapAnsi from 'wrap-ansi';

const NEWLINE = '\n';
const PAD = ' ';
const BORDERS_WIDTH = 2;
const NONE = 'none';

const terminalColumns = () => {
const {env, stdout, stderr} = process;
Expand Down Expand Up @@ -42,6 +42,8 @@ const getObject = detail => typeof detail === 'number' ? {
...detail,
};

const getBorderWidth = borderStyle => borderStyle === NONE ? 0 : 2;

const getBorderChars = borderStyle => {
const sides = [
'topLeft',
Expand All @@ -57,7 +59,7 @@ const getBorderChars = borderStyle => {
let characters;

// Create empty border style
if (borderStyle === 'none') {
if (borderStyle === NONE) {
borderStyle = {};
for (const side of sides) {
borderStyle[side] = '';
Expand Down Expand Up @@ -95,12 +97,12 @@ const getBorderChars = borderStyle => {
return characters;
};

const makeTitle = (text, horizontal, alignement) => {
const makeTitle = (text, horizontal, alignment) => {
let title = '';

const textWidth = stringWidth(text);

switch (alignement) {
switch (alignment) {
case 'left': {
title = text + horizontal.slice(textWidth);
break;
Expand Down Expand Up @@ -231,21 +233,36 @@ const boxContent = (content, contentWidth, options) => {
let marginLeft = PAD.repeat(options.margin.left);

if (options.float === 'center') {
const marginWidth = Math.max((columns - contentWidth - BORDERS_WIDTH) / 2, 0);
const marginWidth = Math.max((columns - contentWidth - getBorderWidth(options.borderStyle)) / 2, 0);
marginLeft = PAD.repeat(marginWidth);
} else if (options.float === 'right') {
const marginWidth = Math.max(columns - contentWidth - options.margin.right - BORDERS_WIDTH, 0);
const marginWidth = Math.max(columns - contentWidth - options.margin.right - getBorderWidth(options.borderStyle), 0);
marginLeft = PAD.repeat(marginWidth);
}

const top = colorizeBorder(NEWLINE.repeat(options.margin.top) + marginLeft + chars.topLeft + (options.title ? makeTitle(options.title, chars.top.repeat(contentWidth), options.titleAlignment) : chars.top.repeat(contentWidth)) + chars.topRight);
const bottom = colorizeBorder(marginLeft + chars.bottomLeft + chars.bottom.repeat(contentWidth) + chars.bottomRight + NEWLINE.repeat(options.margin.bottom));
let result = '';

if (options.margin.top) {
result += NEWLINE.repeat(options.margin.top);
}

if (options.borderStyle !== NONE || options.title) {
result += colorizeBorder(marginLeft + chars.topLeft + (options.title ? makeTitle(options.title, chars.top.repeat(contentWidth), options.titleAlignment) : chars.top.repeat(contentWidth)) + chars.topRight) + NEWLINE;
}

const lines = content.split(NEWLINE);

const middle = lines.map(line => marginLeft + colorizeBorder(chars.left) + colorizeContent(line) + colorizeBorder(chars.right)).join(NEWLINE);
result += lines.map(line => marginLeft + colorizeBorder(chars.left) + colorizeContent(line) + colorizeBorder(chars.right)).join(NEWLINE);

return top + NEWLINE + middle + NEWLINE + bottom;
if (options.borderStyle !== NONE) {
result += NEWLINE + colorizeBorder(marginLeft + chars.bottomLeft + chars.bottom.repeat(contentWidth) + chars.bottomRight);
}

if (options.margin.bottom) {
result += NEWLINE.repeat(options.margin.bottom);
}

return result;
};

const sanitizeOptions = options => {
Expand All @@ -268,37 +285,40 @@ const sanitizeOptions = options => {

// If width is provided, make sure it's not below 1
if (options.width) {
options.width = Math.max(1, options.width - BORDERS_WIDTH);
options.width = Math.max(1, options.width - getBorderWidth(options.borderStyle));
}

// If height is provided, make sure it's not below 1
if (options.height) {
options.height = Math.max(1, options.height - BORDERS_WIDTH);
options.height = Math.max(1, options.height - getBorderWidth(options.borderStyle));
}

return options;
};

const formatTitle = (title, borderStyle) => borderStyle === NONE ? title : ` ${title} `;

const determineDimensions = (text, options) => {
options = sanitizeOptions(options);
const widthOverride = options.width !== undefined;
const columns = terminalColumns();
const maxWidth = columns - options.margin.left - options.margin.right - BORDERS_WIDTH;
const borderWidth = getBorderWidth(options.borderStyle);
const maxWidth = columns - options.margin.left - options.margin.right - borderWidth;

const widest = widestLine(wrapAnsi(text, columns - BORDERS_WIDTH, {hard: true, trim: false})) + options.padding.left + options.padding.right;
const widest = widestLine(wrapAnsi(text, columns - borderWidth, {hard: true, trim: false})) + options.padding.left + options.padding.right;

// If title and width are provided, title adheres to fixed width
if (options.title && widthOverride) {
options.title = options.title.slice(0, Math.max(0, options.width - 2));
if (options.title) {
options.title = ` ${options.title} `;
options.title = formatTitle(options.title, options.borderStyle);
}
} else if (options.title) {
options.title = options.title.slice(0, Math.max(0, maxWidth - 2));

// Recheck if title isn't empty now
if (options.title) {
options.title = ` ${options.title} `;
options.title = formatTitle(options.title, options.borderStyle);
// If the title is larger than content, box adheres to title width
if (stringWidth(options.title) > widest) {
options.width = stringWidth(options.title);
Expand All @@ -312,7 +332,7 @@ const determineDimensions = (text, options) => {
if (!widthOverride) {
if ((options.margin.left && options.margin.right) && options.width > maxWidth) {
// Let's assume we have margins: left = 3, right = 5, in total = 8
const spaceForMargins = columns - options.width - BORDERS_WIDTH;
const spaceForMargins = columns - options.width - borderWidth;
// Let's assume we have space = 4
const multiplier = spaceForMargins / (options.margin.left + options.margin.right);
// Here: multiplier = 4/8 = 0.5
Expand All @@ -323,7 +343,7 @@ const determineDimensions = (text, options) => {
}

// Re-cap width considering the margins after shrinking
options.width = Math.min(options.width, columns - BORDERS_WIDTH - options.margin.left - options.margin.right);
options.width = Math.min(options.width, columns - borderWidth - options.margin.left - options.margin.right);
}

// Prevent padding overflow
Expand Down
2 changes: 0 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,7 @@ Values:
```
- `'none'`
```
foo
```

Style of the box border.
Expand Down
9 changes: 9 additions & 0 deletions tests/height-option.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,12 @@ test('height option with width + padding + margin', t => {

t.snapshot(box);
});

test('height option with border style (none)', t => {
const box = boxen('foo', {
height: 3,
borderStyle: 'none',
});

t.snapshot(box);
});
14 changes: 14 additions & 0 deletions tests/margin-option.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,17 @@ test('margin proportionally decreases when content <= columns', t => {

t.snapshot(box);
});

test('margin option with border style (none)', t => {
const box = boxen('foo', {
margin: {
top: 1,
bottom: 1,
left: 1,
right: 1,
},
borderStyle: 'none',
});

t.snapshot(box);
});
14 changes: 14 additions & 0 deletions tests/padding-option.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,17 @@ test('padding option advanced', t => {

t.snapshot(box);
});

test('padding option with border style (none)', t => {
const box = boxen('foo', {
padding: {
top: 1,
bottom: 1,
left: 1,
right: 1,
},
borderStyle: 'none',
});

t.snapshot(box);
});
4 changes: 1 addition & 3 deletions tests/snapshots/tests/border-option.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ Generated by [AVA](https://avajs.dev).

> Snapshot 1
`␊
foo␊
`
'foo'

## border style (custom ascii style)

Expand Down
Binary file modified tests/snapshots/tests/border-option.js.snap
Binary file not shown.
8 changes: 8 additions & 0 deletions tests/snapshots/tests/height-option.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,11 @@ Generated by [AVA](https://avajs.dev).
└──────────────────┘␊
`

## height option with border style (none)

> Snapshot 1
`foo␊
`
Binary file modified tests/snapshots/tests/height-option.js.snap
Binary file not shown.
8 changes: 8 additions & 0 deletions tests/snapshots/tests/margin-option.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,11 @@ Generated by [AVA](https://avajs.dev).
└──────────────────────────────────────────────────────────┘␊
`

## margin option with border style (none)

> Snapshot 1
`␊
foo␊
`
Binary file modified tests/snapshots/tests/margin-option.js.snap
Binary file not shown.
8 changes: 8 additions & 0 deletions tests/snapshots/tests/padding-option.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ Generated by [AVA](https://avajs.dev).
│ │␊
│ │␊
└──────────────────┘`

## padding option with border style (none)

> Snapshot 1
` ␊
foo ␊
`
Binary file modified tests/snapshots/tests/padding-option.js.snap
Binary file not shown.
7 changes: 7 additions & 0 deletions tests/snapshots/tests/title-option.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,10 @@ Generated by [AVA](https://avajs.dev).
`┌ very long title ─┐␊
│foo │␊
└──────────────────┘`

## title option with border style (none)

> Snapshot 1
`title␊
foo `
Binary file modified tests/snapshots/tests/title-option.js.snap
Binary file not shown.
6 changes: 6 additions & 0 deletions tests/snapshots/tests/width-option.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ Generated by [AVA](https://avajs.dev).
│ │␊
│ │␊
└────┘`

## width option with border style (none)

> Snapshot 1
'foo'
Binary file modified tests/snapshots/tests/width-option.js.snap
Binary file not shown.
9 changes: 9 additions & 0 deletions tests/title-option.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,12 @@ test('title + width option', t => {
}),
);
});

test('title option with border style (none)', t => {
const box = boxen('foo', {
title: 'title',
borderStyle: 'none',
});

t.snapshot(box);
});
9 changes: 9 additions & 0 deletions tests/width-option.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,12 @@ test('width option with big padding', t => {

t.snapshot(box);
});

test('width option with border style (none)', t => {
const box = boxen('foo', {
width: 3,
borderStyle: 'none',
});

t.snapshot(box);
});

0 comments on commit ef5c987

Please sign in to comment.