Skip to content

Commit 9889d8b

Browse files
committed
fix: Fixed fullscreen bugs and added additional tests
1 parent 5be9e6f commit 9889d8b

6 files changed

Lines changed: 160 additions & 63 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"scripts": {
3737
"start": "ts-node-esm src/demo/overview.tsx",
3838
"demo:overview": "tsx src/demo/overview.tsx",
39+
"demo:counter": "tsx src/demo/counter.tsx",
3940
"demo:codify": "tsx src/demo/codify.tsx",
4041
"demo:packagejson": "tsx src/demo/packagejson.tsx",
4142
"demo:custommanager": "tsx src/demo/custommanager.tsx",

src/FullScreen.tsx

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
1-
import { Box } from 'ink';
2-
import React from 'react';
1+
import { Box, BoxProps } from 'ink';
2+
import React, { PropsWithChildren, useLayoutEffect } from 'react';
33
import { useEffect, useState } from 'react';
44

5-
export function FullScreen(props) {
6-
const [size, setSize] = useState({
7-
columns: process.stdout.columns,
8-
rows: process.stdout.rows,
9-
});
10-
5+
function useStdoutDimensions(): [number, number] {
6+
const {columns, rows} = process.stdout;
7+
const [size, setSize] = useState({columns, rows});
118
useEffect(() => {
129
function onResize() {
13-
setSize({
14-
columns: process.stdout.columns,
15-
rows: process.stdout.rows,
16-
});
10+
const {columns, rows} = process.stdout;
11+
setSize({columns, rows});
1712
}
18-
1913
process.stdout.on("resize", onResize);
20-
process.stdout.write("\x1b[?1049h");
21-
process.stdout.write("\x1b[?1000h");
2214
return () => {
2315
process.stdout.off("resize", onResize);
24-
process.stdout.write("\x1b[?1049l");
25-
process.stdout.write("\x1b[?1000l");
2616
};
2717
}, []);
18+
return [size.columns, size.rows];
19+
}
2820

29-
return (
30-
<Box width={size.columns} height={size.rows}>
31-
{props.children}
32-
</Box>
33-
);
21+
export const FullScreen: React.FC<PropsWithChildren<BoxProps>> = ({children, ...styles}) => {
22+
const [columns, rows] = useStdoutDimensions();
23+
return <Box width={columns} height={rows} {...styles}>{children}</Box>;
3424
}

src/canSubmit.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { FormStructure } from './types.js';
22

3-
export const canSubmit = (form: FormStructure, value: object) => {
3+
export const canSubmit = (form: FormStructure, values: Array<Record<string, unknown>>) => {
44
return form.sections
55
.map(section => section.fields)
66
.reduce((fields1, fields2) => [...fields1, ...fields2], [])
7-
.map(field => !field.required || (value[field.name] !== undefined && value[field.name] !== ''))
7+
.map(field => !field.required || (values[field.name] !== undefined && values[field.name] !== ''))
88
.reduce((field1, field2) => field1 && field2, true);
9+
10+
return true;
911
};

src/demo/Test.tsx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { Box, Text, useInput, useStdout } from "ink";
2+
import React, { useEffect, useLayoutEffect } from 'react';
3+
import { Form } from '../Form.js';
4+
import { clearInterval } from 'node:timers';
5+
import { FullScreen } from '../FullScreen.js';
6+
7+
let counter = 0;
8+
9+
export function Test() {
10+
const stdout = useStdout();
11+
12+
const [isSubmitted, setIsSubmitted] = React.useState(false);
13+
const [showPrompt, setShowPrompt] = React.useState(false);
14+
15+
useLayoutEffect(() => {
16+
stdout.write('This is ap revious message\n')
17+
18+
setTimeout(() => {
19+
process.stdout.write('\x1b[?1049h');
20+
process.stdout.write('\x1b[?1000h');
21+
setShowPrompt(true)
22+
}, 3000);
23+
24+
}, []);
25+
26+
useEffect(() => {
27+
const id = setInterval(() => {
28+
if (isSubmitted) {
29+
stdout.write('hi\n')
30+
counter++;
31+
}
32+
33+
if (counter >= 1) {
34+
clearInterval(id)
35+
}
36+
}, 1000)
37+
}, [isSubmitted]);
38+
39+
return (<Box flexDirection='column'>
40+
{!isSubmitted && showPrompt && (
41+
<Form
42+
onSubmit={value => {
43+
process.stdout.write('\x1b[?1049l');
44+
process.stdout.write('\x1b[?1000l');
45+
setIsSubmitted(true)
46+
}}
47+
form={{
48+
title: "Form title",
49+
sections: [
50+
{
51+
title: "asdf-global",
52+
fields: [
53+
{ type: 'string', name: 'plugin', label: 'plugin', required: true },
54+
{ type: 'string', name: 'version', label: 'version', required: true },
55+
]
56+
},
57+
{
58+
title: "asdf-install",
59+
fields: [
60+
{ type: 'string', name: 'directory', label: 'directory', required: true },
61+
]
62+
},
63+
{
64+
title: "asdf-local",
65+
fields: [
66+
{ type: 'string', name: 'plugin', label: 'plugin', required: true },
67+
{ type: 'string', name: 'version', label: 'version', required: true },
68+
{ type: 'string', name: 'directory', label: 'directory' },
69+
{ type: 'string', name: 'directories', label: 'directories' },
70+
]
71+
},
72+
{
73+
title: "asdf-plugin",
74+
fields: [
75+
{ type: 'string', name: 'plugin', label: 'plugin', required: true },
76+
{ type: 'string', name: 'versions', label: 'version'},
77+
{ type: 'string', name: 'gitUrl', label: 'plugin' },
78+
]
79+
},
80+
]
81+
}}
82+
/>
83+
)}
84+
{
85+
isSubmitted && (
86+
<Text color={'green'}>Submitted!!</Text>
87+
)
88+
}
89+
</Box>)
90+
91+
}

src/demo/codify.tsx

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { render } from 'ink';
1+
import { Box, Text, render } from 'ink';
22
import { Form } from '../Form.js';
33
import React from 'react';
4+
import { Test } from './Test.js';
45

56
const options = [
67
{label: 'Millenium Falcon', value: 'falcon'},
@@ -9,43 +10,13 @@ const options = [
910
{label: 'Raizorcrest', value: 'mando'},
1011
];
1112

13+
console.log('Test');
14+
console.log('Test 1');
15+
console.log('Test 2');
16+
console.log('Test 3');
17+
1218
render(
13-
<Form
14-
onSubmit={value => console.log(`Submitted: `, value)}
15-
form={{
16-
title: "Form title",
17-
sections: [
18-
{
19-
title: "asdf-global",
20-
fields: [
21-
{ type: 'string', name: 'plugin', label: 'plugin', required: true },
22-
{ type: 'string', name: 'version', label: 'version', required: true },
23-
]
24-
},
25-
{
26-
title: "asdf-install",
27-
fields: [
28-
{ type: 'string', name: 'directory', label: 'directory', required: true },
29-
]
30-
},
31-
{
32-
title: "asdf-local",
33-
fields: [
34-
{ type: 'string', name: 'plugin', label: 'plugin', required: true },
35-
{ type: 'string', name: 'version', label: 'version', required: true },
36-
{ type: 'string', name: 'directory', label: 'directory' },
37-
{ type: 'string', name: 'directories', label: 'directories' },
38-
]
39-
},
40-
{
41-
title: "asdf-plugin",
42-
fields: [
43-
{ type: 'string', name: 'plugin', label: 'plugin', required: true },
44-
{ type: 'string', name: 'versions', label: 'version'},
45-
{ type: 'string', name: 'gitUrl', label: 'plugin' },
46-
]
47-
},
48-
]
49-
}}
50-
/>
19+
<Box>
20+
<Test/>
21+
</Box>
5122
);

src/demo/counter.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Box, Text, render, useApp, useInput } from "ink";
2+
import React, { useState } from 'react';
3+
4+
console.log('Previous message ')
5+
console.log('Should still show up')
6+
7+
const Counter = () => {
8+
const [counter, setCounter] = React.useState(0);
9+
const { exit } = useApp();
10+
const [isExited, setIsExited] = useState(false);
11+
12+
React.useEffect(() => {
13+
const timer = setInterval(() => {
14+
setCounter(prevCounter => prevCounter + 1);
15+
}, 100);
16+
17+
return () => {
18+
clearInterval(timer);
19+
};
20+
});
21+
22+
useInput((input, key) => {
23+
if (input === "q" || key.escape) {
24+
setIsExited(true);
25+
process.stdout.write(leaveAltScreenCommand);
26+
}
27+
});
28+
29+
return !isExited ? <Text color={'green'}>{counter} tests passed</Text> : <Box flexDirection={'column'}>
30+
<Text color={'red'}>Exited</Text>
31+
<Text color={'red'}>The program</Text>
32+
</Box>
33+
};
34+
35+
const enterAltScreenCommand = "\x1b[?1049h";
36+
const leaveAltScreenCommand = "\x1b[?1049l";
37+
process.stdout.write(enterAltScreenCommand);
38+
process.on("exit", () => {
39+
process.stdout.write(leaveAltScreenCommand);
40+
});
41+
42+
render(<Counter />);

0 commit comments

Comments
 (0)