Skip to content

Commit 015202c

Browse files
authored
Customize border color of each side (#569)
1 parent 714c4a1 commit 015202c

File tree

4 files changed

+222
-9
lines changed

4 files changed

+222
-9
lines changed

Diff for: readme.md

+66-1
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ See example in [examples/borders](examples/borders/borders.tsx).
980980
Type: `string`
981981

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

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

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

993+
##### borderTopColor
994+
995+
Type: `string`
996+
997+
Change top border color.
998+
Accepts the same values as [`color`](#color) in `<Text>` component.
999+
1000+
```jsx
1001+
<Box borderStyle="round" borderTopColor="green">
1002+
<Text>Hello world</Text>
1003+
</Box>
1004+
```
1005+
1006+
##### borderRightColor
1007+
1008+
Type: `string`
1009+
1010+
Change right border color.
1011+
Accepts the same values as [`color`](#color) in `<Text>` component.
1012+
1013+
```jsx
1014+
<Box borderStyle="round" borderRightColor="green">
1015+
<Text>Hello world</Text>
1016+
</Box>
1017+
```
1018+
1019+
##### borderRightColor
1020+
1021+
Type: `string`
1022+
1023+
Change right border color.
1024+
Accepts the same values as [`color`](#color) in `<Text>` component.
1025+
1026+
```jsx
1027+
<Box borderStyle="round" borderRightColor="green">
1028+
<Text>Hello world</Text>
1029+
</Box>
1030+
```
1031+
1032+
##### borderBottomColor
1033+
1034+
Type: `string`
1035+
1036+
Change bottom border color.
1037+
Accepts the same values as [`color`](#color) in `<Text>` component.
1038+
1039+
```jsx
1040+
<Box borderStyle="round" borderBottomColor="green">
1041+
<Text>Hello world</Text>
1042+
</Box>
1043+
```
1044+
1045+
##### borderLeftColor
1046+
1047+
Type: `string`
1048+
1049+
Change left border color.
1050+
Accepts the same values as [`color`](#color) in `<Text>` component.
1051+
1052+
```jsx
1053+
<Box borderStyle="round" borderLeftColor="green">
1054+
<Text>Hello world</Text>
1055+
</Box>
1056+
```
1057+
9931058
##### borderTop
9941059

9951060
Type: `boolean`\

Diff for: src/render-border.ts

+18-7
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,16 @@ const renderBorder = (
1212
if (typeof node.style.borderStyle === 'string') {
1313
const width = node.yogaNode!.getComputedWidth();
1414
const height = node.yogaNode!.getComputedHeight();
15-
const color = node.style.borderColor;
1615
const box = cliBoxes[node.style.borderStyle];
1716

17+
const topBorderColor = node.style.borderTopColor ?? node.style.borderColor;
18+
const bottomBorderColor =
19+
node.style.borderBottomColor ?? node.style.borderColor;
20+
const leftBorderColor =
21+
node.style.borderLeftColor ?? node.style.borderColor;
22+
const rightBorderColor =
23+
node.style.borderRightColor ?? node.style.borderColor;
24+
1825
const showTopBorder = node.style.borderTop !== false;
1926
const showBottomBorder = node.style.borderBottom !== false;
2027
const showLeftBorder = node.style.borderLeft !== false;
@@ -28,7 +35,7 @@ const renderBorder = (
2835
(showLeftBorder ? box.topLeft : '') +
2936
box.top.repeat(contentWidth) +
3037
(showRightBorder ? box.topRight : ''),
31-
color,
38+
topBorderColor,
3239
'foreground'
3340
)
3441
: undefined;
@@ -43,16 +50,20 @@ const renderBorder = (
4350
verticalBorderHeight -= 1;
4451
}
4552

46-
const verticalBorder = (
47-
colorize(box.left, color, 'foreground') + '\n'
53+
const leftBorder = (
54+
colorize(box.left, leftBorderColor, 'foreground') + '\n'
55+
).repeat(verticalBorderHeight);
56+
57+
const rightBorder = (
58+
colorize(box.left, rightBorderColor, 'foreground') + '\n'
4859
).repeat(verticalBorderHeight);
4960

5061
const bottomBorder = showBottomBorder
5162
? colorize(
5263
(showLeftBorder ? box.bottomLeft : '') +
5364
box.bottom.repeat(contentWidth) +
5465
(showRightBorder ? box.bottomRight : ''),
55-
color,
66+
bottomBorderColor,
5667
'foreground'
5768
)
5869
: undefined;
@@ -64,11 +75,11 @@ const renderBorder = (
6475
}
6576

6677
if (showLeftBorder) {
67-
output.write(x, y + offsetY, verticalBorder, {transformers: []});
78+
output.write(x, y + offsetY, leftBorder, {transformers: []});
6879
}
6980

7081
if (showRightBorder) {
71-
output.write(x + width - 1, y + offsetY, verticalBorder, {
82+
output.write(x + width - 1, y + offsetY, rightBorder, {
7283
transformers: []
7384
});
7485
}

Diff for: src/styles.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,34 @@ export type Styles = {
218218

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

225+
/**
226+
* Change top border color.
227+
* Accepts the same values as `color` in `Text` component.
228+
*/
229+
readonly borderTopColor?: LiteralUnion<ForegroundColorName, string>;
230+
231+
/**
232+
* Change bottom border color.
233+
* Accepts the same values as `color` in `Text` component.
234+
*/
235+
readonly borderBottomColor?: LiteralUnion<ForegroundColorName, string>;
236+
237+
/**
238+
* Change left border color.
239+
* Accepts the same values as `color` in `Text` component.
240+
*/
241+
readonly borderLeftColor?: LiteralUnion<ForegroundColorName, string>;
242+
243+
/**
244+
* Change right border color.
245+
* Accepts the same values as `color` in `Text` component.
246+
*/
247+
readonly borderRightColor?: LiteralUnion<ForegroundColorName, string>;
248+
225249
/**
226250
* Behavior for an element's overflow in both directions.
227251
*

Diff for: test/borders.tsx

+113
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import indentString from 'indent-string';
55
import delay from 'delay';
66
import widestLine from 'widest-line';
77
import cliBoxes from 'cli-boxes';
8+
import chalk from 'chalk';
89
import {render, Box, Text} from '../src/index.js';
910
import {renderToString} from './helpers/render-to-string.js';
1011
import createStdout from './helpers/create-stdout.js';
@@ -611,3 +612,115 @@ test('hide all borders', t => {
611612

612613
t.is(output, ['Above', 'Content', 'Below'].join('\n'));
613614
});
615+
616+
test('change color of top border', t => {
617+
const output = renderToString(
618+
<Box flexDirection="column" alignItems="flex-start">
619+
<Text>Above</Text>
620+
<Box borderStyle="round" borderTopColor="green">
621+
<Text>Content</Text>
622+
</Box>
623+
<Text>Below</Text>
624+
</Box>
625+
);
626+
627+
t.is(
628+
output,
629+
[
630+
'Above',
631+
chalk.green(
632+
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
633+
cliBoxes.round.topRight
634+
}`
635+
),
636+
`${cliBoxes.round.left}Content${cliBoxes.round.right}`,
637+
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
638+
cliBoxes.round.bottomRight
639+
}`,
640+
'Below'
641+
].join('\n')
642+
);
643+
});
644+
645+
test('change color of bottom border', t => {
646+
const output = renderToString(
647+
<Box flexDirection="column" alignItems="flex-start">
648+
<Text>Above</Text>
649+
<Box borderStyle="round" borderBottomColor="green">
650+
<Text>Content</Text>
651+
</Box>
652+
<Text>Below</Text>
653+
</Box>
654+
);
655+
656+
t.is(
657+
output,
658+
[
659+
'Above',
660+
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
661+
cliBoxes.round.topRight
662+
}`,
663+
`${cliBoxes.round.left}Content${cliBoxes.round.right}`,
664+
chalk.green(
665+
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
666+
cliBoxes.round.bottomRight
667+
}`
668+
),
669+
'Below'
670+
].join('\n')
671+
);
672+
});
673+
674+
test('change color of left border', t => {
675+
const output = renderToString(
676+
<Box flexDirection="column" alignItems="flex-start">
677+
<Text>Above</Text>
678+
<Box borderStyle="round" borderLeftColor="green">
679+
<Text>Content</Text>
680+
</Box>
681+
<Text>Below</Text>
682+
</Box>
683+
);
684+
685+
t.is(
686+
output,
687+
[
688+
'Above',
689+
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
690+
cliBoxes.round.topRight
691+
}`,
692+
`${chalk.green(cliBoxes.round.left)}Content${cliBoxes.round.right}`,
693+
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
694+
cliBoxes.round.bottomRight
695+
}`,
696+
'Below'
697+
].join('\n')
698+
);
699+
});
700+
701+
test('change color of right border', t => {
702+
const output = renderToString(
703+
<Box flexDirection="column" alignItems="flex-start">
704+
<Text>Above</Text>
705+
<Box borderStyle="round" borderRightColor="green">
706+
<Text>Content</Text>
707+
</Box>
708+
<Text>Below</Text>
709+
</Box>
710+
);
711+
712+
t.is(
713+
output,
714+
[
715+
'Above',
716+
`${cliBoxes.round.topLeft}${cliBoxes.round.top.repeat(7)}${
717+
cliBoxes.round.topRight
718+
}`,
719+
`${cliBoxes.round.left}Content${chalk.green(cliBoxes.round.right)}`,
720+
`${cliBoxes.round.bottomLeft}${cliBoxes.round.bottom.repeat(7)}${
721+
cliBoxes.round.bottomRight
722+
}`,
723+
'Below'
724+
].join('\n')
725+
);
726+
});

0 commit comments

Comments
 (0)