UNPKG

@hhoangphuoc/escape-room-cli

Version:

A CLI for playing AI-generated escape room games. Install globally with: npm install -g @hhoangphuoc/escape-room-cli

43 lines (42 loc) 1.96 kB
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'; import { Box, useInput } from 'ink'; const ScrollableBox = React.forwardRef(({ children, height = 20, // Default height }, ref) => { const [scrollPos, setScrollPos] = useState(0); const childrenArray = React.Children.toArray(children); const totalItems = childrenArray.length; const maxScroll = Math.max(0, totalItems - height); // Auto-scroll to bottom on new content const prevChildrenLengthRef = useRef(totalItems); useImperativeHandle(ref, () => ({ scrollToBottom: () => { setScrollPos(maxScroll); } })); useEffect(() => { if (totalItems > prevChildrenLengthRef.current) { setScrollPos(maxScroll); } prevChildrenLengthRef.current = totalItems; }, [totalItems, maxScroll]); // Handle keyboard scrolling useInput((_, key) => { if (key.upArrow) { setScrollPos(Math.max(0, scrollPos - 1)); } else if (key.downArrow) { setScrollPos(Math.min(maxScroll, scrollPos + 1)); } else if (key.pageUp) { setScrollPos(Math.max(0, scrollPos - height)); } else if (key.pageDown) { setScrollPos(Math.min(maxScroll, scrollPos + height)); } }); // Calculate which items to show in view const visibleChildren = childrenArray.slice(scrollPos, scrollPos + height); return (_jsxs(Box, { flexDirection: "column", children: [visibleChildren, totalItems > height && (_jsx(Box, { marginTop: 1, children: _jsx(Box, { marginRight: 1, children: _jsxs(Box, { children: [_jsx(Box, { marginRight: 1, children: _jsxs(Box, { children: ["Scroll: ", scrollPos + 1, "/", totalItems] }) }), scrollPos > 0 ? '↑' : ' ', scrollPos < maxScroll ? '↓' : ' '] }) }) }))] })); }); export default ScrollableBox;