-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
81 lines (69 loc) · 2.33 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// Helper functions for styling
const colorText = (text, colorCode) => `\x1b[${colorCode}m${text}\x1b[0m`;
const bold = (text) => `\x1b[1m${text}\x1b[0m`;
function createMenu(options) {
let selectedIndex = 0;
const { title = 'Menu', width = 60, borderColor = 90, highlightColor = 34, textColor = 37 } = options;
const renderMenu = () => {
console.clear();
const border = colorText('─'.repeat(width), borderColor);
const highlight = (text) => colorText(text, highlightColor);
const text = (content) => colorText(content, textColor);
console.log(border);
console.log(text(title.padStart(Math.floor(width / 2) + title.length / 2)));
console.log(border);
console.log();
options.items.forEach((item, index) => {
const prefix = index === selectedIndex ? `${highlight('> ')}` : ' ';
console.log(`${prefix}${index === selectedIndex ? bold(text(item.label)) : text(item.label)}`);
});
console.log();
console.log(border);
};
const handleKeypress = (chunk, key) => {
if (key.name === 'up') {
selectedIndex = (selectedIndex - 1 + options.items.length) % options.items.length;
renderMenu();
} else if (key.name === 'down') {
selectedIndex = (selectedIndex + 1) % options.items.length;
renderMenu();
} else if (key.name === 'return') {
console.clear();
options.items[selectedIndex].action();
rl.close();
process.stdin.setRawMode(false);
process.stdin.pause();
} else if (key.ctrl && key.name === 'c') {
// Graceful exit on Ctrl+C
rl.close();
process.stdin.setRawMode(false);
process.stdin.pause();
console.clear();
console.log('Exited menu.');
}
};
const enableRawMode = () => {
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', (chunk) => {
const key = {
name: chunk === '\r' ? 'return' : chunk === '\x1b[A' ? 'up' : chunk === '\x1b[B' ? 'down' : null,
ctrl: chunk === '\x03'
};
if (key.name) handleKeypress(chunk, key);
});
};
return {
render: () => {
renderMenu();
enableRawMode();
}
};
}
module.exports = { createMenu };