Skip to content

Commit 794f1e5

Browse files
Added HorizontalLine component
1 parent eea645f commit 794f1e5

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

src/border/HorizontalLine.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Widgets } from "@farjs/blessed";
2+
3+
type BlessedStyle = Widgets.Types.TStyle;
4+
5+
export interface HorizontalLineProps {
6+
readonly left: number;
7+
readonly top: number;
8+
readonly length: number;
9+
readonly lineCh: string;
10+
readonly style: BlessedStyle;
11+
readonly startCh?: string;
12+
readonly endCh?: string;
13+
}

src/border/HorizontalLine.mjs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @typedef {import("./HorizontalLine").HorizontalLineProps} HorizontalLineProps
3+
*/
4+
import React from "react";
5+
6+
const h = React.createElement;
7+
8+
/**
9+
* @param {HorizontalLineProps} props
10+
*/
11+
const HorizontalLine = (props) => {
12+
const startCh = props.startCh ?? "";
13+
const endCh = props.endCh ?? "";
14+
const line = props.lineCh.repeat(
15+
props.length - startCh.length - endCh.length
16+
);
17+
const content = `${startCh}${line}${endCh}`;
18+
19+
return h("text", {
20+
width: props.length,
21+
height: 1,
22+
left: props.left,
23+
top: props.top,
24+
style: props.style,
25+
content,
26+
});
27+
};
28+
29+
HorizontalLine.displayName = "HorizontalLine";
30+
31+
export default HorizontalLine;

test/all.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ await import("./ButtonsPanel.test.mjs");
33
await import("./TextLine.test.mjs");
44
await import("./UI.test.mjs");
55

6+
await import("./border/HorizontalLine.test.mjs");
7+
68
await import("./popup/Popup.test.mjs");
79
await import("./popup/PopupOverlay.test.mjs");
810

test/border/HorizontalLine.test.mjs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* @typedef {import('../../src/border/HorizontalLine').HorizontalLineProps} HorizontalLineProps
3+
*/
4+
import React from "react";
5+
import TestRenderer from "react-test-renderer";
6+
import assert from "node:assert/strict";
7+
import { assertComponents } from "react-assert";
8+
import HorizontalLine from "../../src/border/HorizontalLine.mjs";
9+
10+
const h = React.createElement;
11+
12+
const { describe, it } = await (async () => {
13+
// @ts-ignore
14+
return process.isBun // @ts-ignore
15+
? Promise.resolve({ describe: (_, fn) => fn(), it: test })
16+
: import("node:test");
17+
})();
18+
19+
describe("HorizontalLine.test.mjs", () => {
20+
it("should render line without start and end chars", () => {
21+
//given
22+
const props = {
23+
...getHorizontalLineProps(),
24+
startCh: undefined,
25+
endCh: undefined,
26+
};
27+
28+
//when
29+
const result = TestRenderer.create(h(HorizontalLine, props)).root;
30+
31+
//then
32+
assertHorizontalLine(result, props, "*****");
33+
});
34+
35+
it("should render line with start char", () => {
36+
//given
37+
const props = {
38+
...getHorizontalLineProps(),
39+
startCh: "+",
40+
endCh: undefined,
41+
};
42+
43+
//when
44+
const result = TestRenderer.create(h(HorizontalLine, props)).root;
45+
46+
//then
47+
assertHorizontalLine(result, props, "+****");
48+
});
49+
50+
it("should render line with end char", () => {
51+
//given
52+
const props = {
53+
...getHorizontalLineProps(),
54+
startCh: undefined,
55+
endCh: "-",
56+
};
57+
58+
//when
59+
const result = TestRenderer.create(h(HorizontalLine, props)).root;
60+
61+
//then
62+
assertHorizontalLine(result, props, "****-");
63+
});
64+
65+
it("should render line with start and end chars", () => {
66+
//given
67+
const props = {
68+
...getHorizontalLineProps(),
69+
startCh: "+",
70+
endCh: "-",
71+
};
72+
73+
//when
74+
const result = TestRenderer.create(h(HorizontalLine, props)).root;
75+
76+
//then
77+
assertHorizontalLine(result, props, "+***-");
78+
});
79+
});
80+
81+
/**
82+
* @returns {HorizontalLineProps}
83+
*/
84+
function getHorizontalLineProps() {
85+
return {
86+
left: 1,
87+
top: 2,
88+
length: 5,
89+
lineCh: "*",
90+
style: {
91+
fg: "white",
92+
bg: "blue",
93+
},
94+
};
95+
}
96+
97+
/**
98+
* @param {TestRenderer.ReactTestInstance} result
99+
* @param {HorizontalLineProps} props
100+
* @param {string} content
101+
*/
102+
function assertHorizontalLine(result, props, content) {
103+
assert.deepEqual(HorizontalLine.displayName, "HorizontalLine");
104+
105+
assertComponents(
106+
result.children,
107+
h("text", {
108+
width: props.length,
109+
height: 1,
110+
left: props.left,
111+
top: props.top,
112+
style: props.style,
113+
content,
114+
})
115+
);
116+
}

0 commit comments

Comments
 (0)