-
Notifications
You must be signed in to change notification settings - Fork 782
Expand file tree
/
Copy pathmenu.js
More file actions
74 lines (63 loc) · 1.7 KB
/
menu.js
File metadata and controls
74 lines (63 loc) · 1.7 KB
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
import React from 'react';
import { useState } from 'react';
import PropTypes from 'prop-types';
import { Box, useInput } from 'ink';
import Button from './button';
export const MenuEntry = (title, onItemSelected, color) => ({
color,
title,
onItemSelected
});
MenuEntry.propTypes = PropTypes.shape({
title: PropTypes.string,
onItemSelected: PropTypes.func,
color: PropTypes.string
});
export const Menu = ({ isActive, items, onFocusPrevious, width }) => {
const menu = items;
const [selectedIdx, setSelectedIdx] = useState(0);
const inputHandler = (_, key) => {
if (key.upArrow || key.leftArrow || (key.shift && key.tab)) {
setSelectedIdx(Math.max(0, selectedIdx - 1));
if (selectedIdx - 1 < 0) {
onFocusPrevious();
}
} else if (key.downArrow || key.rightArrow || (key.tab)) {
setSelectedIdx(Math.min(menu.length - 1, selectedIdx + 1));
} else if (key.return) {
const onItemSelected = menu[selectedIdx].onItemSelected;
onItemSelected();
}
};
useInput(inputHandler, { isActive });
return (
<Box
flexDirection='row'
alignItems='center'
justifyContent='center'
width={ width }
>
{
menu.map((menuEntry, idx) =>
<Button
key={ menuEntry.title }
isSelected={ isActive && idx === selectedIdx }
color={ menuEntry.color }
>
{ menuEntry.title }
</Button>
)
}
</Box>
);
}
Menu.propTypes = {
isActive: PropTypes.bool,
items: PropTypes.arrayOf(MenuEntry.propTypes).isRequired,
onFocusPrevious: PropTypes.func,
width: PropTypes.string
};
Menu.defaultProps = {
isActive: true,
onFocusPrevious: () => {}
}