UNPKG

rune

Version:

CLI to upload your games to Rune

71 lines (70 loc) 2.7 kB
import figures from "figures"; import { useInput, Box, Text } from "ink"; import React, { useMemo } from "react"; export function Select({ items, value, onChange, onSubmit, }) { const currentIndex = useMemo(() => items.findIndex((item) => item.value === value), [items, value]); useInput((_, key) => { const firstItem = items.at(0); const lastItem = items.at(-1); const nextItem = items[currentIndex + 1]; const prevItem = items[currentIndex - 1]; if (key.downArrow) { if (nextItem) onChange(nextItem.value); else if (firstItem) onChange(firstItem.value); } else if (key.upArrow) { if (prevItem) onChange(prevItem.value); else if (lastItem) onChange(lastItem.value); } else if (key.return) { if (items.find((item) => item.value === value)?.disabled) return; onSubmit(); } }); const { window, beforeCount, afterCount } = useMemo(() => getWindow(items, currentIndex, 7), [currentIndex, items]); return (React.createElement(Box, { flexDirection: "column" }, beforeCount > 0 && (React.createElement(Text, { dimColor: true, italic: true }, "\u00A0\u00A0... ", beforeCount, " more")), window.map((item, i) => (React.createElement(Text, { key: i, dimColor: value !== item.value, color: item.disabled ? "red" : undefined }, value === item.value ? item.disabled ? figures.cross : figures.pointer : " ", " ", React.createElement(Text, { underline: value === item.value }, item.label)))), afterCount > 0 && (React.createElement(Text, { dimColor: true, italic: true }, "\u00A0\u00A0... ", afterCount, " more")))); } function getWindow(list, index, windowSize) { let windowSizeRemains = windowSize; const window = []; for (let i = 0; i < list.length * 2; i++) { if (windowSizeRemains === 0) break; const item = list[index + Math.floor(i % 2 === 0 ? i / 2 : -i / 2)]; if (item) { if (i % 2 === 0) window.push(item); else window.unshift(item); windowSizeRemains--; } } const windowHead = window.at(0); const windowTail = window.at(-1); return { window, beforeCount: windowHead ? list.indexOf(windowHead) : 0, afterCount: windowTail ? list.length - 1 - list.indexOf(windowTail) : 0, }; }