@roots/bud
Version:
Configurable, extensible build tools for modern single and multi-page web applications
35 lines (34 loc) • 2.19 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "@roots/bud-support/jsx-runtime";
import { exit } from 'node:process';
import figures from '@roots/bud-support/figures';
import { Box, Text, useEffect, useInput, useState, } from '@roots/bud-support/ink';
export const Menu = ({ cli }) => {
const [selected, setSelected] = useState(0);
const defined = cli.definitions();
const items = defined.filter(cmd => cmd.path !== `bud`);
const description = defined[0].description.trim();
const longestCommandLength = items.reduce((a, b) => {
return a.path.length > b.path.length ? a : b;
}).path.length;
useInput((_, input) => {
input.escape && exit();
input.downArrow && setSelected(selected + 1);
input.upArrow && setSelected(selected - 1);
if (input.return) {
cli.run(items[selected].path.split(` `).slice(1));
}
});
useEffect(() => {
if (selected > items.length - 1)
setSelected(0);
if (selected < 0)
setSelected(items.length - 1);
}, [items, selected]);
return (_jsxs(Box, { flexDirection: "column", gap: 1, marginY: 1, children: [_jsx(Header, {}), _jsx(Text, { italic: true, children: description }), _jsx(Box, { flexDirection: "column", gap: 0, children: items.map(({ description, path }, id) => (_jsx(Item, { description: description, minWidth: longestCommandLength, path: path, selected: selected === id }, id))) })] }));
};
const Header = () => (_jsx(Box, { flexDirection: "row", justifyContent: "space-between", children: _jsx(Box, { flexDirection: "row", gap: 1, children: _jsx(Text, { bold: true, children: "bud.js" }) }) }));
const Item = ({ description, minWidth, path, selected, }) => {
const color = selected ? `blue` : `white`;
const figure = selected ? figures.radioOn : figures.radioOff;
return (_jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsx(Box, { children: _jsx(Text, { color: color, children: figure }) }), _jsx(Box, { width: minWidth, children: _jsx(Text, { color: color, children: path.trim() }) }), _jsx(Box, { children: _jsx(Text, { color: "white", dimColor: true, children: description.trim() }) })] }));
};