UNPKG

@roots/bud

Version:

Configurable, extensible build tools for modern single and multi-page web applications

35 lines (34 loc) 2.19 kB
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() }) })] })); };