Skip to content

Commit

Permalink
Customize border color of each side (#569)
Browse files Browse the repository at this point in the history
  • Loading branch information
vadimdemedes committed Mar 26, 2023
1 parent 714c4a1 commit 015202c
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 9 deletions.
67 changes: 66 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ See example in [examples/borders](examples/borders/borders.tsx).
Type: `string`

Change border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
Shorthand for setting `borderTopColor`, `borderRightColor`, `borderBottomColor` and `borderLeftColor`.

```jsx
<Box borderStyle="round" borderColor="green">
Expand All @@ -990,6 +990,71 @@ Accepts the same values as [`color`](#color) in `<Text>` component.

<img src="media/box-borderColor.jpg" width="228">

##### borderTopColor

Type: `string`

Change top border color.
Accepts the same values as [`color`](#color) in `<Text>` component.

```jsx
<Box borderStyle="round" borderTopColor="green">
<Text>Hello world</Text>
</Box>
```

##### borderRightColor

Type: `string`

Change right border color.
Accepts the same values as [`color`](#color) in `<Text>` component.

```jsx
<Box borderStyle="round" borderRightColor="green">
<Text>Hello world</Text>
</Box>
```

##### borderRightColor

Type: `string`

Change right border color.
Accepts the same values as [`color`](#color) in `<Text>` component.

```jsx
<Box borderStyle="round" borderRightColor="green">
<Text>Hello world</Text>
</Box>
```

##### borderBottomColor

Type: `string`

Change bottom border color.
Accepts the same values as [`color`](#color) in `<Text>` component.

```jsx
<Box borderStyle="round" borderBottomColor="green">
<Text>Hello world</Text>
</Box>
```

##### borderLeftColor

Type: `string`

Change left border color.
Accepts the same values as [`color`](#color) in `<Text>` component.

```jsx
<Box borderStyle="round" borderLeftColor="green">
<Text>Hello world</Text>
</Box>
```

##### borderTop

Type: `boolean`\
Expand Down
25 changes: 18 additions & 7 deletions src/render-border.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@ const renderBorder = (
if (typeof node.style.borderStyle === 'string') {
const width = node.yogaNode!.getComputedWidth();
const height = node.yogaNode!.getComputedHeight();
const color = node.style.borderColor;
const box = cliBoxes[node.style.borderStyle];

const topBorderColor = node.style.borderTopColor ?? node.style.borderColor;
const bottomBorderColor =
node.style.borderBottomColor ?? node.style.borderColor;
const leftBorderColor =
node.style.borderLeftColor ?? node.style.borderColor;
const rightBorderColor =
node.style.borderRightColor ?? node.style.borderColor;

const showTopBorder = node.style.borderTop !== false;
const showBottomBorder = node.style.borderBottom !== false;
const showLeftBorder = node.style.borderLeft !== false;
Expand All @@ -28,7 +35,7 @@ const renderBorder = (
(showLeftBorder ? box.topLeft : '') +
box.top.repeat(contentWidth) +
(showRightBorder ? box.topRight : ''),
color,
topBorderColor,
'foreground'
)
: undefined;
Expand All @@ -43,16 +50,20 @@ const renderBorder = (
verticalBorderHeight -= 1;
}

const verticalBorder = (
colorize(box.left, color, 'foreground') + '\n'
const leftBorder = (
colorize(box.left, leftBorderColor, 'foreground') + '\n'
).repeat(verticalBorderHeight);

const rightBorder = (
colorize(box.left, rightBorderColor, 'foreground') + '\n'
).repeat(verticalBorderHeight);

const bottomBorder = showBottomBorder
? colorize(
(showLeftBorder ? box.bottomLeft : '') +
box.bottom.repeat(contentWidth) +
(showRightBorder ? box.bottomRight : ''),
color,
bottomBorderColor,
'foreground'
)
: undefined;
Expand All @@ -64,11 +75,11 @@ const renderBorder = (
}

if (showLeftBorder) {
output.write(x, y + offsetY, verticalBorder, {transformers: []});
output.write(x, y + offsetY, leftBorder, {transformers: []});
}

if (showRightBorder) {
output.write(x + width - 1, y + offsetY, verticalBorder, {
output.write(x + width - 1, y + offsetY, rightBorder, {
transformers: []
});
}
Expand Down
26 changes: 25 additions & 1 deletion src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,34 @@ export type Styles = {

/**
* Change border color.
* Accepts the same values as `color` in <Text> component.
* Shorthand for setting `borderTopColor`, `borderRightColor`, `borderBottomColor` and `borderLeftColor`.
*/
readonly borderColor?: LiteralUnion<ForegroundColorName, string>;

/**
* Change top border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderTopColor?: LiteralUnion<ForegroundColorName, string>;

/**
* Change bottom border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderBottomColor?: LiteralUnion<ForegroundColorName, string>;

/**
* Change left border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderLeftColor?: LiteralUnion<ForegroundColorName, string>;

/**
* Change right border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderRightColor?: LiteralUnion<ForegroundColorName, string>;

/**
* Behavior for an element's overflow in both directions.
*
Expand Down
113 changes: 113 additions & 0 deletions test/borders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import indentString from 'indent-string';
import delay from 'delay';
import widestLine from 'widest-line';
import cliBoxes from 'cli-boxes';
import chalk from 'chalk';
import {render, Box, Text} from '../src/index.js';
import {renderToString} from './helpers/render-to-string.js';
import createStdout from './helpers/create-stdout.js';
Expand Down Expand Up @@ -611,3 +612,115 @@ test('hide all borders', t => {

t.is(output, ['Above', 'Content', 'Below'].join('\n'));
});

test('change color of top border', t => {
const output = renderToString(
<Box flexDirection="column" alignItems="flex-start">
<Text>Above</Text>
<Box borderStyle="round" borderTopColor="green">
<Text>Content</Text>
</Box>
<Text>Below</Text>
</Box>
);

t.is(
output,
[
'Above',
chalk.green(
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
cliBoxes.round.topRight
}`
),
`${cliBoxes.round.left}Content${cliBoxes.round.right}`,
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
cliBoxes.round.bottomRight
}`,
'Below'
].join('\n')
);
});

test('change color of bottom border', t => {
const output = renderToString(
<Box flexDirection="column" alignItems="flex-start">
<Text>Above</Text>
<Box borderStyle="round" borderBottomColor="green">
<Text>Content</Text>
</Box>
<Text>Below</Text>
</Box>
);

t.is(
output,
[
'Above',
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
cliBoxes.round.topRight
}`,
`${cliBoxes.round.left}Content${cliBoxes.round.right}`,
chalk.green(
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
cliBoxes.round.bottomRight
}`
),
'Below'
].join('\n')
);
});

test('change color of left border', t => {
const output = renderToString(
<Box flexDirection="column" alignItems="flex-start">
<Text>Above</Text>
<Box borderStyle="round" borderLeftColor="green">
<Text>Content</Text>
</Box>
<Text>Below</Text>
</Box>
);

t.is(
output,
[
'Above',
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
cliBoxes.round.topRight
}`,
`${chalk.green(cliBoxes.round.left)}Content${cliBoxes.round.right}`,
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
cliBoxes.round.bottomRight
}`,
'Below'
].join('\n')
);
});

test('change color of right border', t => {
const output = renderToString(
<Box flexDirection="column" alignItems="flex-start">
<Text>Above</Text>
<Box borderStyle="round" borderRightColor="green">
<Text>Content</Text>
</Box>
<Text>Below</Text>
</Box>
);

t.is(
output,
[
'Above',
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
cliBoxes.round.topRight
}`,
`${cliBoxes.round.left}Content${chalk.green(cliBoxes.round.right)}`,
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
cliBoxes.round.bottomRight
}`,
'Below'
].join('\n')
);
});

0 comments on commit 015202c

Please sign in to comment.