Skip to content

Commit

Permalink
Customize border style (#570)
Browse files Browse the repository at this point in the history
  • Loading branch information
vadimdemedes committed Mar 26, 2023
1 parent 789e613 commit fb66872
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
21 changes: 20 additions & 1 deletion readme.md
Expand Up @@ -929,7 +929,7 @@ Shortcut for setting `overflowX` and `overflowY` at the same time.
##### borderStyle

Type: `string`\
Allowed values: `single` `double` `round` `bold` `singleDouble` `doubleSingle` `classic`
Allowed values: `single` `double` `round` `bold` `singleDouble` `doubleSingle` `classic` | `BoxStyle`

Add a border with a specified style.
If `borderStyle` is `undefined` (which it is by default), no border will be added.
Expand Down Expand Up @@ -973,6 +973,25 @@ Ink uses border styles from [`cli-boxes`](https://github.com/sindresorhus/cli-bo

<img src="media/box-borderStyle.jpg" width="521">

Alternatively, pass a custom border style like so:

```jsx
<Box
borderStyle={{
topLeft: 'β†˜',
top: '↓',
topRight: '↙',
left: 'β†’',
bottomLeft: 'β†—',
bottom: '↑',
bottomRight: 'β†–',
right: '←'
}}
>
<Text>Custom</Text>
</Box>
```

See example in [examples/borders](examples/borders/borders.tsx).

##### borderColor
Expand Down
7 changes: 5 additions & 2 deletions src/render-border.ts
Expand Up @@ -9,10 +9,13 @@ const renderBorder = (
node: DOMNode,
output: Output
): void => {
if (typeof node.style.borderStyle === 'string') {
if (node.style.borderStyle) {
const width = node.yogaNode!.getComputedWidth();
const height = node.yogaNode!.getComputedHeight();
const box = cliBoxes[node.style.borderStyle];
const box =
typeof node.style.borderStyle === 'string'
? cliBoxes[node.style.borderStyle]
: node.style.borderStyle;

const topBorderColor = node.style.borderTopColor ?? node.style.borderColor;
const bottomBorderColor =
Expand Down
6 changes: 3 additions & 3 deletions src/styles.ts
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
import {type Boxes} from 'cli-boxes';
import {type Boxes, type BoxStyle} from 'cli-boxes';
import {type LiteralUnion} from 'type-fest';
import {type ForegroundColorName} from 'chalk';
// eslint-disable-next-line n/file-extension-in-import
Expand Down Expand Up @@ -186,7 +186,7 @@ export type Styles = {
* Add a border with a specified style.
* If `borderStyle` is `undefined` (which it is by default), no border will be added.
*/
readonly borderStyle?: keyof Boxes;
readonly borderStyle?: keyof Boxes | BoxStyle;

/**
* Determines whether top border is visible.
Expand Down Expand Up @@ -499,7 +499,7 @@ const applyDisplayStyles = (node: YogaNode, style: Styles): void => {

const applyBorderStyles = (node: YogaNode, style: Styles): void => {
if ('borderStyle' in style) {
const borderWidth = typeof style.borderStyle === 'string' ? 1 : 0;
const borderWidth = style.borderStyle ? 1 : 0;

if (style.borderTop !== false) {
node.setBorder(Yoga.EDGE_TOP, borderWidth);
Expand Down
21 changes: 21 additions & 0 deletions test/borders.tsx
Expand Up @@ -724,3 +724,24 @@ test('change color of right border', t => {
].join('\n')
);
});

test('custom border style', t => {
const output = renderToString(
<Box
borderStyle={{
topLeft: 'β†˜',
top: '↓',
topRight: '↙',
left: 'β†’',
bottomLeft: 'β†—',
bottom: '↑',
bottomRight: 'β†–',
right: '←'
}}
>
<Text>Content</Text>
</Box>
);

t.is(output, boxen('Content', {width: 100, borderStyle: 'arrow'}));
});

0 comments on commit fb66872

Please sign in to comment.